Commit Graph

842 Commits

Author SHA1 Message Date
Max Isbey 00a1336ee6 refactor: accept plain set for ResourceSecurity.exempt_params
Changes the type from frozenset[str] to collections.abc.Set[str] so
users can write exempt_params={"range"} instead of
exempt_params=frozenset({"range"}). The default factory stays
frozenset for immutability.
2026-03-26 17:42:18 +00:00
Max Isbey 928698b3eb docs: add migration guide entry for resource template changes
Documents the RFC 6570 support, security hardening defaults, and
opt-out configuration for the resource template rewrite. Grouped with
the existing resource URI section.
2026-03-26 17:42:18 +00:00
Max Isbey 5cbbc70b18 feat: wire ResourceSecurity into MCPServer configuration
Adds `resource_security` to `MCPServer.__init__` and a per-resource
`security` override to the `@resource()` decorator. Templates inherit
the server-wide policy unless overridden.

Exports `ResourceSecurity` and `DEFAULT_RESOURCE_SECURITY` from
`mcp.server.mcpserver` for user configuration.

Usage:

    # Server-wide relaxation
    mcp = MCPServer(resource_security=ResourceSecurity(reject_path_traversal=False))

    # Per-resource exemption for non-path parameters
    @mcp.resource(
        "git://diff/{+range}",
        security=ResourceSecurity(exempt_params=frozenset({"range"})),
    )
    def git_diff(range: str) -> str: ...
2026-03-26 17:42:18 +00:00
Max Isbey 0018eea38f feat: integrate UriTemplate into MCPServer resource templates
Refactors the internal `ResourceTemplate` to use the RFC 6570
`UriTemplate` engine for matching, and adds a configurable
`ResourceSecurity` policy for path-safety checks on extracted
parameters.

`ResourceTemplate.matches()` now:
- Delegates to `UriTemplate.match()` for full RFC 6570 Level 1-3
  support (plus path-style explode). `{+path}` can match
  multi-segment paths.
- Enforces structural integrity: `%2F` smuggled into a simple
  `{var}` is rejected.
- Applies `ResourceSecurity` policy: path traversal (`..` components)
  and absolute paths rejected by default, with per-parameter
  exemption available.

The `@mcp.resource()` decorator now parses the template once at
decoration time via `UriTemplate.parse()`, replacing the regex-based
param extraction that couldn't handle operators like `{+path}`.
Malformed templates surface immediately with a clear
`InvalidUriTemplate` including position info.

Also fixes the pre-existing bug where template literals were not
regex-escaped (a `.` in the template acted as a wildcard).
2026-03-26 17:42:18 +00:00
Max Isbey e5ecf50e64 feat: add filesystem path safety primitives
Adds `mcp.shared.path_security` with three standalone utilities for
defending against path-traversal attacks when URI template parameters
flow into filesystem operations:

- `contains_path_traversal()` — base-free component-level check for
  `..` escapes, handles both `/` and `\` separators
- `is_absolute_path()` — detects POSIX, Windows drive, and UNC
  absolute paths (which silently discard the base in `Path` joins)
- `safe_join()` — resolve-and-verify within a sandbox root; catches
  `..`, absolute injection, and symlink escapes

These are pure functions usable from both MCPServer and lowlevel
server implementations. `PathEscapeError(ValueError)` is raised by
`safe_join` on violation.
2026-03-26 17:42:18 +00:00
Max Isbey 5f5e72b87a feat: add RFC 6570 URI template utility with bidirectional support
Adds `mcp.shared.uri_template.UriTemplate`, a standalone utility for
parsing, expanding, and matching RFC 6570 URI templates. Supports
Levels 1-3 fully plus path-style explode (`{/var*}`, `{.var*}`,
`{;var*}`).

Matching enforces structural integrity: decoded values are validated
against their operator's permitted character set. A simple `{var}`
whose decoded value contains `/` is rejected, preventing `%2F`
smuggling while still allowing `/` in `{+var}` where it is
intentional. This is the operator-aware generalization of the
post-decode check for encoded path separators.

Also fixes the existing regex-escaping gap where template literals
like `.` were treated as regex wildcards.

The utility lives in `shared/` so it is usable from both client code
(expand) and server code (match), including lowlevel server
implementations that do not use MCPServer.
2026-03-26 17:42:18 +00:00
Marcelo Trylesinski 98f8ef295a Restrict httpx version to <1.0.0 (#2345)
Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
2026-03-25 22:29:13 +00:00
Felix Weinberger 7ba4fb881d ci: skip claude.yml when comment is '@claude review' (#2337) 2026-03-24 20:36:36 +00:00
Max Isbey 92c693bb73 fix: cancel in-flight handlers when transport closes in server.run() (#2306) 2026-03-20 13:37:32 +00:00
Max Isbey 883d893097 test: rewrite cli.claude config tests to assert JSON output directly (#2311)
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: Felix Weinberger <felixweinberger@users.noreply.github.com>
2026-03-19 15:16:34 +00:00
Jonathan Hefner 5388bea53a docs: generate hierarchical per-module API reference pages (#2103) 2026-03-18 18:15:17 +00:00
Max Isbey 20dd94632e feat(client): store InitializeResult as initialize_result (#2300) 2026-03-18 17:31:26 +00:00
Max Isbey 67201a9bbd test: fix WS test port race; narrow to single smoke test covering both transport ends (#2267) 2026-03-18 15:48:30 +00:00
Max Isbey 7826ade12b test: convert test_integration.py to in-memory transport (fix flaky) (#2277) 2026-03-18 15:25:11 +00:00
Max Isbey ff50351f9e ci: run strict-no-cover in scripts/test to catch stale pragmas locally (#2305) 2026-03-17 19:53:39 +00:00
Max Isbey 1a2244f402 fix: handle non-UTF-8 bytes in stdio server stdin (#2302) 2026-03-17 18:40:39 +00:00
Max Isbey 75a80b6f07 refactor: connect-first stream lifecycle for sse and streamable_http (#2292)
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
2026-03-16 23:30:20 +00:00
Max Isbey abfb482246 refactor(examples): migrate all HTTP examples to streamable_http_app() (#2291) 2026-03-16 11:37:01 +00:00
Max Isbey e1fd62e0f3 fix: close all memory stream ends in client transport cleanup (#2266) 2026-03-13 14:43:54 +00:00
dependabot[bot] 2c73a2a881 chore(deps): bump black from 25.1.0 to 26.3.1 in the uv group across 1 directory (#2290)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-13 10:39:56 +00:00
Max Isbey dd52713517 Rewrite TestChildProcessCleanup with socket-based deterministic liveness probe (#2265) 2026-03-12 12:52:32 +00:00
Max Isbey 62eb08e5b2 fix: don't send log notification on transport error (#2257) 2026-03-09 17:47:27 +00:00
Max Isbey 31a38b5078 fix: correct Context type parameters across examples and tests (#2256) 2026-03-09 16:52:56 +00:00
Shivam Aggarwal 51c53f2c18 fix: accept wildcard media types in Accept header per RFC 7231 (#2152)
Co-authored-by: Shivam <shivam@Shivams-MacBook-Air-2.local>
2026-03-09 16:30:02 +00:00
Max Isbey 7ba41dcfae fix: make local coverage runs reliable (#2236) 2026-03-06 17:24:18 +00:00
Ramesh Reddy Adutla eaf971cf25 Add warning log when rejecting request with unknown/expired session ID (#2212)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
2026-03-06 16:55:37 +00:00
Max Isbey 92f1b1500d fix: remove MIME type validation from MCPServer Resource (#2235) 2026-03-06 14:50:58 +00:00
Giulio Leone b33c811675 perf: use deque for InMemoryTaskMessageQueue FIFO operations (#2165) 2026-03-05 15:44:33 +00:00
Giulio Leone 7c0224828b fix(oauth): include client_id in token request body for client_secret_post (#2185)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-05 14:57:33 +00:00
Max Isbey 528abfab86 tests: remove lax-no-cover pragmas by moving assertions before cancellation (#2206) 2026-03-04 16:11:34 +00:00
Varun6578 b3149d2f33 fix: clean up SSE session on client disconnect (#2200)
Co-authored-by: Varun Sharma <sharmava@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
2026-03-04 14:45:11 +00:00
Max Isbey cc22bf5464 refactor: remove request_ctx ContextVar, thread Context explicitly (#2203)
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
2026-03-04 13:23:02 +00:00
Max Isbey 62575edabd ci: sign weekly lockfile commits as github-actions[bot] (#2148) 2026-02-26 15:36:46 +00:00
Jonathan Hefner 0fe16dd5fd fix: silence mkdocs social plugin warnings in strict mode (#2109) 2026-02-19 23:12:51 +01:00
Jonathan Hefner cb07adeca3 docs: add code fences to Example: docstring blocks (#2104) 2026-02-19 21:06:11 +01:00
Jonathan Hefner c0328540c9 docs: fix docstrings across public API surface (#2095) 2026-02-19 06:45:59 +01:00
Den Delimarsky 688c6e3ade Update SECURITY.md to use GitHub Security Advisories (#2092) 2026-02-18 21:19:25 -08:00
Max Isbey 43d709c976 ci: pin all GitHub Actions to commit SHAs (#2088) 2026-02-18 19:42:00 +00:00
Max Isbey 0e96aecd1d fix: use exact match for loopback hosts in issuer URL validation (#2089) 2026-02-18 19:40:52 +00:00
Max Isbey b9431d483f fix: prevent command injection in example URL opening (#2082) 2026-02-18 15:16:44 +00:00
Max Isbey e82203bfc4 refactor: remove unused mcp.shared.progress module (#2080) 2026-02-18 13:10:02 +00:00
Akshan Krithick fc57c2c4c5 test: fix progress notification assertions for related_request_id (#2038)
Co-authored-by: Lee Hubbard <hubbard.zlee@unknowncyber.com>
Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
2026-02-18 11:53:03 +00:00
Felix Weinberger 92140e5086 Add idle session timeout to StreamableHTTPSessionManager (#2022) 2026-02-18 10:47:02 +00:00
Felix Weinberger be5bb7c4f2 fix: normalize trailing slashes before length check in check_resource_allowed (#2074) 2026-02-17 14:34:59 +00:00
Max Isbey 705497a593 fix: allow null id in JSONRPCError per JSON-RPC 2.0 spec (#2056) 2026-02-17 10:30:34 +00:00
BabyChrist666 3b53fb9a00 fix: add HTTP readiness check to wait_for_server and remove dead code in SSE tests (#2073) 2026-02-17 08:34:47 +01:00
Marcelo Trylesinski 2fe56e56de fix: handle HTTP error status codes in streamable HTTP client (#2047) 2026-02-14 09:49:42 +01:00
Max Isbey 8f669a77e3 fix: explicitly load required pytest plugins in addopts (#2055) 2026-02-13 18:25:10 +00:00
Marcelo Trylesinski a287a40184 docs: add coverage verification instruction to CLAUDE.md (#2050) 2026-02-13 13:10:00 +00:00
Max Isbey 29a14ab9e5 fix: skip readme-v1-frozen in CI and add diff-based README.md check (#2048) 2026-02-13 10:30:30 +00:00