PyPI / fastmcp / 4.1.1

fastmcp 4.1.1

Source
https://github.com/PrefectHQ/fastmcp
Tag scanned
v4.1.1
Compared with
v4.1.0 (0 signals introduced since)
Files
992 scanned, 749 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 25 info
Scan time
19.6 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 25 of 25 warn and critical signals; 25 demoted to info.
Disclude version
4.0.0
Scanned (UTC)
2026-10-19 04:11

Signals

Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.

  1. info warn → info by review frame-introspection fastmcp_slim/fastmcp/client/transports/inference.py:41:13

    `sys._getframe` — call-stack frame introspection (ast pass, confidence 0.70)

        level = 1
        frame = sys._getframe(1)
        while frame is not None:
            if not frame.f_code.co_filename.startswith(_PACKAGE_ROOT):
    likely benign LLM, confidence 0.80 Walks the call stack via sys._getframe to locate the first frame outside the package.
    Reasoning

    sys._getframe(1) walks the call stack to find the first caller outside the fastmcp package, which is a common way to attribute inference to the calling user code. The snippet shows no obfuscation, encoding, or network or exec behavior, so it is most likely a legitimate design choice.

  2. info warn → info by review dynamic-execution tests/cli/test_generate_cli.py:266:9

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            # Generated code should compile
            compile(source, "<test>", "exec")
    
        def test_array_of_strings_parameter(self):
    likely benign LLM, confidence 0.95 Test asserts that generated source code compiles.
    Reasoning

    In a test, compile() checks that generated CLI source is syntactically valid. The source is produced by the code under test, not attacker input, and compile() does not execute it.

  3. info warn → info by review dynamic-execution tests/cli/test_generate_cli.py:286:9

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            assert "json.loads" not in source
            compile(source, "<test>", "exec")
    
        def test_complex_object_parameter(self):
    likely benign LLM, confidence 0.95 Test compiles generated source to verify syntax.
    Reasoning

    Same pattern as the other generate-CLI tests: compile() validates generated source in a test. It only compiles and never executes the code.

  4. info warn → info by review dynamic-execution tests/cli/test_generate_cli.py:319:9

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            assert "'metadata': metadata_parsed" in source
            compile(source, "<test>", "exec")
    
        def test_nested_array_parameter(self):
    likely benign LLM, confidence 0.95 Test compiles generated source to check syntax.
    Reasoning

    compile() is used in a test to check that generated code is syntactically valid. The input is generator output and nothing is executed.

  5. info warn → info by review dynamic-execution tests/cli/test_generate_cli.py:346:9

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            )
            compile(source, "<test>", "exec")
    
        def test_complex_type_with_default(self):
    likely benign LLM, confidence 0.95 Test compiles generated source to check syntax.
    Reasoning

    compile() validates generated code inside a unit test. This is a syntax check on output from the code under test.

  6. info warn → info by review dynamic-execution tests/cli/test_generate_cli.py:367:9

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            assert "isinstance(options, str)" in source
            compile(source, "<test>", "exec")
    
        def test_name_collision_detection(self):
    likely benign LLM, confidence 0.95 Test compiles generated source to check syntax.
    Reasoning

    compile() is a syntax-validation step on generated source in a test. No execution occurs.

  7. info warn → info by review dynamic-execution tests/cli/test_generate_cli.py:446:9

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            )
            compile(script, "<generated>", "exec")
    
        def test_contains_tool_functions(self):
    likely benign LLM, confidence 0.95 Test compiles a generated script to verify it is valid.
    Reasoning

    compile() on a generated script string in a test is a syntax check. The script comes from the generator under test.

  8. info warn → info by review dynamic-execution tests/cli/test_generate_cli.py:492:9

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            )
            compile(script, "<generated>", "exec")
            assert "call_tool_app" in script
    likely benign LLM, confidence 0.95 Test compiles a generated script to verify validity.
    Reasoning

    compile() of a generated script in a test is a syntax check on generator output, not dynamic execution of untrusted input.

  9. info warn → info by review dynamic-execution tests/cli/test_generate_cli.py:505:9

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            # Should compile without syntax errors
            compile(script, "<generated>", "exec")
            # App name should have escaped quotes
            assert r'app = cyclopts.App(name="test-\"server\"-name"' in script
    likely benign LLM, confidence 0.95 Test verifies a generated script compiles and has escaped quotes.
    Reasoning

    The comment says the script should compile without syntax errors, which confirms a syntax-validation purpose. The escaped-quote assertion shows the test is checking generator output.

  10. info warn → info by review dynamic-execution tests/cli/test_generate_cli.py:529:9

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            )
            compile(script, "<generated>", "exec")
    
        @pytest.mark.parametrize(
    likely benign LLM, confidence 0.95 Test compiles generated script output for syntax.
    Reasoning

    compile() on generated script text in a test is a syntax check. Nothing is executed.

  11. info warn → info by review dynamic-execution tests/cli/test_generate_cli.py:562:9

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            )
            compile(script, "<generated>", "exec")
    likely benign LLM, confidence 0.95 Test compiles generated script output for syntax.
    Reasoning

    compile() validates generated script output in a test. This is not an execution path for untrusted data.

  12. info warn → info by review dynamic-execution tests/cli/test_generate_cli.py:622:9

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            content = output.read_text(encoding="utf-8")
            compile(content, str(output), "exec")
    
        @pytest.mark.usefixtures("_patch_client")
    likely benign LLM, confidence 0.95 Test compiles a generated output file to check syntax.
    Reasoning

    compile() is applied to a file the test just wrote, to check it is valid Python. It is a syntax check only.

  13. info warn → info by review dynamic-execution tests/cli/test_generate_cli.py:701:9

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            script = output.read_bytes().decode("utf-8")
            compile(script, str(output), "exec")
            assert "temperature in °C → rounded" in script
            skill = (tmp_path / "SKILL.md").read_bytes().decode("utf-8")
    likely benign LLM, confidence 0.95 Test compiles a generated output file and checks its content.
    Reasoning

    compile() on generated output read from a temp file is a syntax check in a test. The non-ASCII assertion shows it is testing generator output content.

  14. info warn → info by review encoding-base64 tests/conformance/server.py:43:6

    base64-like blob (40 bytes, compression ratio 1.27) (raw pass, confidence 0.60)

        "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4"
        "nGP4z8BQDwAEgAF/pooBPQAAAABJRU5ErkJggg=="
    )
    likely benign LLM, confidence 0.90 Base64-encoded PNG image fixture in a conformance test server.
    Reasoning

    The snippet is a base64 string that starts with the PNG signature (iVBORw0KGgo) and matches the test-image pattern in a conformance server. Embedded image fixtures are normal, and the low compression ratio fits compressed PNG data.

  15. info critical → info by review dynamic-import tests/docs/test_doc_examples.py:80:25

    `__import__` called on a non-literal expression (ast pass, confidence 0.70)

                        try:
                            __import__(alias.name)
                        except ImportError:
                            errors.append(
    likely benign LLM, confidence 0.85 Test dynamically imports modules referenced in documentation examples to verify they resolve.
    Reasoning

    In a docs-example test, __import__ checks that modules named in documentation imports can be loaded. The module name comes from parsing doc source, and the result is only used to record ImportError failures. Critical severity reflects the dynamic import pattern, not malicious use here.

  16. info critical → info by review dynamic-import tests/docs/test_doc_examples.py:89:27

    `__import__` called on a non-literal expression (ast pass, confidence 0.70)

                    try:
                        mod = __import__(node.module, fromlist=names)
                    except ImportError:
                        errors.append(
    likely benign LLM, confidence 0.85 Test imports a module from a documentation example with fromlist to check it resolves.
    Reasoning

    This __import__ call with fromlist loads a module named in a doc example so the test can verify the import works. It is a test-harness pattern, and its failures are collected as errors.

  17. info warn → info by review dynamic-execution tests/docs/test_upgrade_guide_equivalence.py:45:5

    `exec` called on a non-literal expression (ast pass, confidence 0.70)

        namespace: dict[str, Any] = {"__name__": "fastmcp_docs_example"}
        exec(compile(matches[0].source, str(path), "exec"), namespace)
        return namespace
    likely benign LLM, confidence 0.90 Test helper executes Python code examples extracted from upgrade guide docs.
    Reasoning

    exec of compiled source extracted from documentation code blocks in a test harness. Source comes from repo docs under test, not untrusted input; standard doc-example testing pattern.

  18. info warn → info by review dynamic-execution tests/docs/test_upgrade_guide_equivalence.py:45:10

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

        namespace: dict[str, Any] = {"__name__": "fastmcp_docs_example"}
        exec(compile(matches[0].source, str(path), "exec"), namespace)
        return namespace
    likely benign LLM, confidence 0.90 compile() of extracted doc example source inside the same test helper.
    Reasoning

    compile() is the companion of the exec above and operates on repo-local doc source; no external input or obfuscation.

  19. info warn → info by review dynamic-execution tests/docs/test_upgrade_guide_examples.py:101:9

    `exec` called on a non-literal expression (ast pass, confidence 0.70)

            warnings.simplefilter("ignore")
            exec(compile(example.source, str(example.path), "exec"), namespace)
    likely benign LLM, confidence 0.88 Executes upgrade guide example code in a test with warnings ignored.
    Reasoning

    Test runs documentation examples from the repository, with warnings suppressed. Consistent with doc-testing; source is local and trusted.

  20. info warn → info by review dynamic-execution tests/docs/test_upgrade_guide_examples.py:101:14

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            warnings.simplefilter("ignore")
            exec(compile(example.source, str(example.path), "exec"), namespace)
    likely benign LLM, confidence 0.88 compile() of documentation example source for test execution.
    Reasoning

    compile() of local documentation example source feeding the exec; no obfuscation evident.

  21. info warn → info by review encoding-base64 tests/downstream/server.py:38:6

    base64-like blob (96 bytes, compression ratio 0.99) (raw pass, confidence 0.60)

    PNG = base64.b64decode(
        "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg=="
    )
    WAV = (
    likely benign LLM, confidence 0.93 Base64-encoded tiny PNG image constant used as test fixture data.
    Reasoning

    A small base64-encoded 1x1 PNG test fixture decoded at module load for a downstream test server. Typical embedded test image, not a dropper.

  22. info warn → info by review dynamic-execution tests/experimental/transforms/test_code_mode.py:93:9

    `exec` called on a non-literal expression (ast pass, confidence 0.70)

    
            exec(wrapped, namespace, namespace)
            return await namespace["__test_main__"]()
    likely benign LLM, confidence 0.93 Test executes wrapped code-mode snippet in an isolated namespace.
    Reasoning

    Test wraps generated code in a namespace and execs it; the code is produced by the code-mode transform under test, not attacker input. Expected for testing a code-execution feature.

  23. info warn → info by review dynamic-execution tests/experimental/transforms/test_code_mode_discovery.py:76:9

    `exec` called on a non-literal expression (ast pass, confidence 0.70)

    
            exec(wrapped, namespace, namespace)
            return await namespace["__test_main__"]()
    likely benign LLM, confidence 0.93 Test execs a wrapped code-mode test program in a namespace.
    Reasoning

    Same pattern as the sibling code_mode test: exec of locally generated wrapped test code within a test function.

  24. info warn → info by review payload-bytes-literal tests/tools/test_tool_future_annotations.py:48:16

    bytes literal contains 41 `\xNN` escapes (85% of content) — binary payload shape (ast pass, confidence 0.85)

        # Create a simple 1x1 white pixel PNG
        png_data = b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde\x00\x00\x00\x0cIDATx\x9cc\xf8\x0f\x00\x00\x01\x01\x00\x05\x18\xd4c\x00\x00\x00\x00IEND\xaeB`\x82"
        return Image(data=png_data, format="png")
    likely benign LLM, confidence 0.93 Inline PNG bytes literal used to build a test Image.
    Reasoning

    A bytes literal containing a 1x1 PNG built in a test to create an Image object. Legitimate fixture data with no execution or exfiltration.

  25. info warn → info by review encoding-base64 tests/utilities/test_inspect_icons.py:244:43

    base64-like blob (96 bytes, compression ratio 1.00) (raw pass, confidence 0.60)

    
            data_uri = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
    
            mcp = FastMCP("DataURIServer")
    likely benign LLM, confidence 0.93 Base64 PNG data URI string used in an icon inspection test.
    Reasoning

    A base64 PNG data URI used as icon test input for a FastMCP server. Standard test fixture.

Reproduce This Scan

Run disclude locally to verify. Add --format sarif for SARIF output. Add --llm (with an API key in the environment) to include the LLM review.

cargo install disclude --version 4.0.0
git clone https://github.com/PrefectHQ/fastmcp fastmcp && cd fastmcp
git checkout v4.1.1
disclude scan --severity info --diff v4.1.0 .