PyPI / fastmcp / 4.1.2

fastmcp 4.1.2

Source
https://github.com/PrefectHQ/fastmcp
Tag scanned
v4.1.2
Compared with
v4.1.1 (3 signals introduced since)
Files
1019 scanned, 750 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 28 info
Scan time
22.9 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 28 of 28 warn and critical signals; 28 demoted to info.
Disclude version
4.0.0
Scanned (UTC)
2026-10-21 05:26

Signals

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

  1. info warn → info by review encoding-base64 tests/server/auth/test_private_key_jwt_auth.py:144:21 new in this release

    base64-like blob (68 bytes, compression ratio 1.16) (raw pass, confidence 0.60)

            # Non-object headers must fail before reaching JWKS key selection.
            "WyJhbGciXQ.eyJzdWIiOiAiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20vbWV0YWRhdGEuanNvbiJ9.c2ln",
            "ImFsZyI.eyJzdWIiOiAiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20vbWV0YWRhdGEuanNvbiJ9.c2ln",
    likely benign LLM, confidence 0.85 Crafted malformed JWT assertion strings used as negative test cases.
    Reasoning

    Malformed JWT-like strings deliberately constructed as negative test inputs for private_key_jwt assertion parsing; base64-like fragments are expected.

  2. info warn → info by review encoding-base64 tests/server/auth/test_private_key_jwt_auth.py:145:18 new in this release

    base64-like blob (68 bytes, compression ratio 1.16) (raw pass, confidence 0.60)

            "WyJhbGciXQ.eyJzdWIiOiAiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20vbWV0YWRhdGEuanNvbiJ9.c2ln",
            "ImFsZyI.eyJzdWIiOiAiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20vbWV0YWRhdGEuanNvbiJ9.c2ln",
            "WyJhbGciLCAiYjY0Il0.eyJzdWIiOiAiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20vbWV0YWRhdGEuanNvbiJ9.c2ln",
        ],
    likely benign LLM, confidence 0.85 Malformed JWT test fixture string in auth negative test list.
    Reasoning

    Same deliberately malformed JWT test fixture list; no executable or hidden payload.

  3. info warn → info by review encoding-base64 tests/server/auth/test_private_key_jwt_auth.py:146:30 new in this release

    base64-like blob (68 bytes, compression ratio 1.16) (raw pass, confidence 0.60)

            "ImFsZyI.eyJzdWIiOiAiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20vbWV0YWRhdGEuanNvbiJ9.c2ln",
            "WyJhbGciLCAiYjY0Il0.eyJzdWIiOiAiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20vbWV0YWRhdGEuanNvbiJ9.c2ln",
        ],
    )
    likely benign LLM, confidence 0.85 Malformed JWT test fixture string in auth negative test list.
    Reasoning

    Same malformed JWT fixture set used in auth tests; benign test data.

  4. 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 root.
    Reasoning

    sys._getframe(1) is used to walk up the call stack and find the first caller outside the package, which is a common way to attribute a client inference call to its origin. It is introspection, not execution or exfiltration, and the snippet shows nothing hidden.

  5. 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.90 Test-only syntax check that compiles generated CLI source without executing it.
    Reasoning

    compile() on generated source only checks syntax and does not execute it. It sits in a test asserting that generated code is valid, so this is a legitimate test pattern.

  6. 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.90 Test-only compile of generated source to verify it is syntactically valid.
    Reasoning

    compile() on generated source in a test only validates syntax; the code is never run. The surrounding asserts confirm this is a test of code generation output.

  7. 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.90 Test-only compile check on generated source content.
    Reasoning

    compile() is used as a syntax validity check on generated code in a test, with assertions on the generated text. Compile alone does not execute the code.

  8. 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.90 Test-only compile of generated code to check it parses.
    Reasoning

    compile() on generated source in a test to confirm the output parses. No execution occurs, so there is no dynamic-execution risk.

  9. 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.90 Test-only syntax validation of generated source.
    Reasoning

    compile() validates generated source as a syntax check inside a test function. The code is not executed.

  10. 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.90 Test-only compile of generated script to verify validity.
    Reasoning

    compile() of generated script within a test checks that it is valid Python. It is a standard pattern for testing code generators.

  11. 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.90 Test-only compile check on a generated script.
    Reasoning

    compile() on generated script in a test, followed by assertions on its contents. Compilation without execution is benign.

  12. 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.90 Test-only compile verifying escaped-quote generated output parses.
    Reasoning

    compile() validates that generated script with escaped quotes is syntactically correct, and assertions follow. This is a test of escaping behavior.

  13. 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.90 Test-only syntax check on generated script within a parametrized test.
    Reasoning

    compile() on generated script in a parametrized test is a syntax check on code generator output. No execution occurs.

  14. 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.90 Test-only compile of generated script to verify validity.
    Reasoning

    compile() on generated script in a test verifies syntactic validity. Nothing is executed.

  15. 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.90 Test-only compile of a generated output file to check syntax.
    Reasoning

    compile() of a generated output file read from disk in a test, used only as a syntax check. No execution follows.

  16. 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.90 Test-only compile of generated script output, followed by content assertions.
    Reasoning

    compile() on generated script read from a test output file, with unicode content assertions. This is a syntax and content check only.

  17. 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 bytes embedded as a test fixture in a conformance server.
    Reasoning

    The blob decodes to a PNG header (iVBORw0KGgo...), a small test image embedded in a conformance server. Base64 image data in a test fixture is expected and is not an obfuscated payload.

  18. 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.90 Test harness importing modules named in documentation examples to verify they resolve.
    Reasoning

    __import__ on alias.name from parsed documentation code checks that documented imports resolve. The module name comes from the docs under test, and the ImportError handling records failures. This is a test harness pattern.

  19. 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.90 Test harness dynamically importing from-import modules found in doc examples.
    Reasoning

    __import__ with fromlist on node.module from parsed doc examples checks that documented from-imports are valid. It is test-only, and failures are collected rather than hidden.

  20. 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 doc example code extracted from markdown.
    Reasoning

    exec of compiled source extracted from documentation code blocks in a test; the source comes from repo docs, not untrusted input.

  21. 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.80 Test helper executes code examples extracted from upgrade-guide documentation.
    Reasoning

    exec(compile(...)) of extracted doc code blocks in a test harness; source comes from repository docs, not untrusted input. Typical doc-testing pattern.

  22. 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.80 Doc-example test runner execs example code from documentation files.
    Reasoning

    exec of compiled documentation example sources inside a test; the examples are repo-controlled markdown snippets, so dynamic execution is expected for doc verification.

  23. 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.80 compile() of documentation example source inside the doc-test runner.
    Reasoning

    Same compile call paired with the exec above; same benign doc-testing context.

  24. 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.90 Embedded base64-encoded 1x1 PNG image used as test data.
    Reasoning

    Base64 PNG constant of a tiny test image decoded for a downstream test server; a standard embedded image fixture, not a payload.

  25. 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.80 Test executes wrapped generated code to validate code-mode transform.
    Reasoning

    exec of a wrapped test program in a namespace for code-mode sandbox tests; the code under test is generated by the test itself.

  26. 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.80 Test execs wrapped code for code-mode discovery validation.
    Reasoning

    Same exec pattern as the sibling code-mode test; test-local code execution for validating a transform.

  27. 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.85 Inline PNG byte literal used as image test data.
    Reasoning

    A bytes literal encoding a 1x1 PNG for an Image test fixture; binary image data in tests is ordinary and not executed or hidden.

  28. 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.85 Data URI containing a tiny PNG used as icon test input.
    Reasoning

    Base64 PNG data URI used as icon input for an inspect-icons test; 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.2
disclude scan --severity info --diff v4.1.1 .