Commit graph

543 commits

Author SHA1 Message Date
Alex Hancock
9299fd3792
fix: do not attempt triage workflow without an API key (#712) 2026-03-02 10:36:42 -05:00
Kristof Mattei
876da50271
fix: downgrade logging of message to TRACE to avoid spamming logs (#699) 2026-02-27 18:11:22 -05:00
github-actions[bot]
955186502d
chore: release (#697)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-27 15:32:46 -05:00
Dale Seo
634852aaa0
fix: prevent mcp-conformance from being published to crates.io (#701) 2026-02-27 15:29:29 -05:00
Dale Seo
e68b15e600
docs: add prose documentation for core features to meet conformance (#702)
* docs: add prose documentation for core features to meet conformance

* docs: remove static coverage badge and svg

* docs: rewrite Chinese README to match current English README
2026-02-27 13:33:53 -05:00
Alex Hancock
98653855ef
feat: issue triage tooling (#698)
* feat: issue triage tooling

* fix: update triage-new-issues script

Co-authored-by: Dale Seo <5466341+DaleSeo@users.noreply.github.com>

---------

Co-authored-by: Dale Seo <5466341+DaleSeo@users.noreply.github.com>
2026-02-27 11:35:18 -05:00
Thiago Mendes
d6703dad75
feat(streamable-http): add json_response option for stateless server mode (#683)
* feat(streamable-http): add json_response option for stateless server mode

Adds `json_response: bool` field to `StreamableHttpServerConfig`.
When true and `stateful_mode` is false, the server returns
`Content-Type: application/json` directly instead of `text/event-stream`,
eliminating SSE framing overhead for simple request-response patterns.

This completes server-side JSON response support (client-side was added
in #540) and contributes to the stateless server goals of SEP-1442 (#526).

Backwards-compatible: `json_response: false` (default) preserves all
existing SSE behaviour unchanged, and `stateful_mode: true` is unaffected.

Benchmark evidence (50 VUs, 5min, 2 CPUs):
- RPS: 770 → 1139 (+48%)
- get_user_cart latency: 41ms → 0.76ms (-98%)
- checkout latency: 41ms → 0.55ms (-99%)
- Zero regressions, zero errors

* fix(tower): add cancellation awareness and logging to JSON response path

* fix(test): add missing Default to StreamableHttpServerConfig in concurrent streams test

Made-with: Cursor
2026-02-26 22:23:05 -05:00
dependabot[bot]
4677a65291
chore(deps): bump github/codeql-action from 3 to 4 (#695)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-26 13:44:24 -05:00
dependabot[bot]
e83665f583
chore(deps): bump actions/checkout from 4 to 6 (#696)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-26 13:44:00 -05:00
Alex Hancock
a7e4ae3203
feat: mcp sdk conformance (#687)
* adds conformance server and client
* adds results from initial run of https://github.com/modelcontextprotocol/conformance/tree/main/.claude/skills/mcp-sdk-tier-audit skill
* various small changes applied during the testing loop

Co-authored-by: Dale Seo <5466341+DaleSeo@users.noreply.github.com>
2026-02-26 13:33:18 -05:00
Dale Seo
b967c132ae
fix: improve error logging and remove token secret from logs (#685) 2026-02-26 10:05:43 -05:00
Dale Seo
93bfb4ac6b
feat: add default value support to string, number, and integer schemas (#686) 2026-02-26 10:02:11 -05:00
EvianZhang
6c336a90c1
feat: add trait-based tool declaration (#677)
* feat: add trait-based tool declaration

* fix: typo

* fix: add docs, make more idomatic patterns, allow for empty parameters and return types

* fix: format code

* fix: add default trait

* fix: docs typo
2026-02-25 12:23:37 -05:00
Alex Hancock
332fcbfb91
Fix/sse channel replacement conflict (#682)
* fix(streamable-http): return 409 Conflict when standalone SSE stream already active

LocalSessionWorker::resume() unconditionally replaced self.common.tx on
every GET request, orphaning the receiver the first SSE stream was
reading from. All subsequent server-to-client notifications were sent to
the new sender while the original client was still listening on the old,
now-dead receiver. notify_tool_list_changed().await returned Ok(())
silently.

This is triggered by VS Code's MCP extension which reconnects SSE every
~5 minutes with the same session ID.

Fix: Check tx.is_closed() before replacing the common channel sender.
If an active stream exists, return SessionError::Conflict which is
propagated as HTTP 409 Conflict. This matches the TypeScript SDK
behavior (streamableHttp.ts:423).

Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>

* fix(streamable-http): handle resume with completed request-wise channel

When a client sends GET with Last-Event-ID from a completed POST SSE
response, the request-wise channel no longer exists in tx_router.
Previously this returned ChannelClosed -> 500, causing clients like
Cursor to enter an infinite re-initialization loop.

Now falls back to the common channel when the request-wise channel is
completed, per MCP spec: "Resumption applies regardless of how the
original stream was initiated (POST or GET)."

* fix: allow SSE channel replacement instead of 409 Conflict

Per MCP spec §Streamable HTTP, "The client MAY remain connected to
multiple SSE streams simultaneously." Returning 409 Conflict when a
second GET arrives causes Cursor to enter an infinite re-initialization
loop (~3s cycle).

Instead of rejecting, replace the old common channel sender. Dropping
the old sender closes the old receiver, cleanly terminating the
previous SSE stream so the client can reconnect on the new stream.

This fixes both code paths:
- GET with Last-Event-ID from a completed POST SSE response
- GET without Last-Event-ID (standalone stream reconnection)

* fix: skip cache replay when replacing active SSE stream

When a client opens a new GET SSE stream while a previous one is
still active, the old sender is dropped (terminating the old stream)
and a new channel is created.  Previously, sync() replayed all cached
events to the new stream, but the client already received those events
on the old stream.  This caused an infinite notification loop:

1. Client receives notifications (e.g. ResourceListChanged)
2. Old SSE stream dies (sender replaced)
3. Client reconnects after sse_retry (3s)
4. sync() replays cached notifications the client already handled
5. Client processes them again → goto 2

Fix: check tx.is_closed() BEFORE replacing the sender.  If the old
stream was still alive, skip replay entirely — the client already has
those events.  Only replay when the old stream was genuinely dead
(network failure, timeout) so the client catches up on missed events.

* fix: use shadow channels to prevent SSE reconnect loops

When POST SSE responses include a `retry` field, the browser's
EventSource automatically reconnects via GET after the stream ends.
This creates multiple competing EventSource connections that each
replace the common channel sender, killing the other stream's receiver.
Both reconnect every sse_retry seconds, creating an infinite loop.

Instead of always replacing the common channel, check if the primary
is still active. If so, create a "shadow" stream — an idle SSE
connection kept alive by keep-alive pings that doesn't receive
notifications or interfere with the primary channel.

Also removes cache replay (sync) on common channel resume, as
replaying server-initiated list_changed notifications causes clients
to re-process old signals.

Signed-off-by: Myko Ash <myko@mcpmux.com>
Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>

* test: comprehensive shadow channel tests (15 cases)

Rewrite test suite for SSE channel replacement fix:
- Shadow creation: standalone GET returns 200, multiple GETs coexist
- Dead primary: replacement, notification delivery, repeated cycles
- Notification routing: primary receives, shadow does not
- Resume paths: completed request-wise, common alive/dead
- Real scenarios: Cursor leapfrog, VS Code reconnect
- Edge cases: invalid session, missing header, shadow cleanup

Fix Accept header bug (was missing text/event-stream for
notifications/initialized POST, causing 406 rejection).

* fix: use correct HTTP status codes for session errors per MCP spec

MCP spec (2025-11-25) section "Session Management" requires:
- Missing session ID header → 400 Bad Request (not 401)
- Unknown/terminated session → 404 Not Found (not 401)

Using 401 Unauthorized caused MCP clients (e.g. VS Code) to
trigger full OAuth re-authentication on server restart, instead
of simply re-initializing the session.

Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>

* fix: address review feedback — remove dead Conflict variant, restore sync on resume, rename test

- Remove unused SessionError::Conflict and dead string-matching in tower.rs
  (leftover from abandoned 409 approach)
- Restore sync() replay when replacing a dead primary common channel so
  server-initiated requests and cached notifications are not lost on reconnect
- Rename test from test_sse_channel_replacement_bug to test_sse_concurrent_streams
  per reviewer suggestion (describe what tests verify, not what triggered them)
- Add test for cache replay on dead primary replacement
- Use generic "MCP clients" in comments instead of specific client names

Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>

* fix: use minimal buffer for shadow streams and cap at 32

- Shadow streams only receive SSE keep-alive pings, so use capacity 1
  instead of full channel_capacity
- Cap shadow_txs at 32 to prevent unbounded growth from misbehaving
  clients, dropping the oldest shadow when the limit is reached
- Add test verifying primary works after exceeding shadow limit

Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>

* fix: remove redundant single-component `use reqwest` import

Fixes clippy::single_component_path_imports lint error in
test_sse_concurrent_streams.rs.

---------

Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>
Signed-off-by: Myko Ash <myko@mcpmux.com>
Co-authored-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>
2026-02-24 17:16:42 -05:00
Guy Lichtman
3cb855bcf8
fix(auth): current_scopes read to async (#678) 2026-02-24 12:04:10 -05:00
dependabot[bot]
fd6460bdc5
chore(deps): update rig-core requirement from 0.29.0 to 0.31.0 (#679)
* chore(deps): update rig-core requirement from 0.29.0 to 0.31.0

Updates the requirements on [rig-core](https://github.com/0xPlaygrounds/rig) to permit the latest version.
- [Release notes](https://github.com/0xPlaygrounds/rig/releases)
- [Commits](https://github.com/0xPlaygrounds/rig/compare/rig-core-v0.29.0...rig-core-v0.31.0)

---
updated-dependencies:
- dependency-name: rig-core
  dependency-version: 0.31.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix: address breaking changes

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Dale Seo <5466341+DaleSeo@users.noreply.github.com>
2026-02-24 12:03:18 -05:00
Wils Dawson
83808d3114
fix: refresh token expiry (#680) 2026-02-24 12:02:50 -05:00
Dale Seo
66c7000626
docs: document session management for streamable HTTP transport (#674) 2026-02-24 11:58:55 -05:00
Dale Seo
5fa012d163
feat: send and validate MCP-Protocol-Version header (#675) 2026-02-24 11:08:49 -05:00
Dale Seo
91e208efb7
fix: gate optional dependencies behind feature flags (#672) 2026-02-24 11:02:28 -05:00
Anish Athalye
98eef440c6
fix: allow empty content in CallToolResult (#681)
Per the MCP spec [1] and the TypeScript schema [2],
`CallToolResult.content` is typed as `ContentBlock[]`, so it is a
required array with no minimum length constraint.

MCP server libraries use such a representation in practice: for example,
FastMCP returns responses with no `structuredContent` and an empty
`content` array when tools return `None`.

[1]: https://modelcontextprotocol.io/specification/2025-11-25/server/tools
[2]: https://github.com/modelcontextprotocol/specification/blob/main/schema/2025-11-25/schema.ts
2026-02-24 11:09:57 +08:00
Den Delimarsky
085470025f
feat: add SECURITY.md with GitHub Security Advisories guidance (#670) 2026-02-20 12:13:46 -05:00
Dale Seo
0967d714d2
chore: add CODEOWNERS (#673) 2026-02-20 12:03:38 -05:00
Mark Wotton
92b1459647
fix(schema): remove AddNullable from draft2020_12 settings (#664)
* fix(schema): remove AddNullable from draft2020_12 settings

The `nullable` keyword is an OpenAPI 3.0 extension, not part of
JSON Schema 2020-12. Using AddNullable with draft2020_12 settings
causes validation failures with strict JSON Schema validators.

JSON Schema 2020-12 represents nullable types using:
- {"type": ["string", "null"]} (type array with null)
- {"anyOf": [{"type": "string"}, {"type": "null"}]}

Fixes #663

* test(schema): update complex schema nullable expectation

* test(schema): align macro optional-field expectations with draft2020
2026-02-19 11:19:45 -05:00
github-actions[bot]
3df4c5bf5f
chore: release v0.16.0 (#652)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-17 13:51:44 -05:00
Dale Seo
021a431bef
chore: upgrade reqwest to 0.13.2 (#669) 2026-02-17 13:41:12 -05:00
EvianZhang
0b53bfd7b9
fix: remove unnecessary doc-cfg (#661) 2026-02-17 10:07:40 -05:00
Dale Seo
5a6ff1f74c
fix: duplicate meta serialization (#662) 2026-02-17 10:03:01 -05:00
Peter
61ffba84b5
fix: sort list_all() output in ToolRouter and PromptRouter for deterministic ordering (#665)
ToolRouter::list_all() and PromptRouter::list_all() iterate over a
HashMap, which returns items in non-deterministic order. Since list_all()
backs the tools/list and prompts/list MCP protocol responses, this causes
MCP clients to receive differently-ordered results across calls and
process restarts, leading to intermittent tool discovery failures.

Sort the output alphabetically by name to guarantee stable ordering.
2026-02-17 09:37:17 -05:00
dependabot[bot]
53cd5ed84a
chore(deps): update toml requirement from 0.9 to 1.0 (#668)
Updates the requirements on [toml](https://github.com/toml-rs/toml) to permit the latest version.
- [Commits](https://github.com/toml-rs/toml/compare/toml-v0.9.0...toml-v1.0.2)

---
updated-dependencies:
- dependency-name: toml
  dependency-version: 1.0.2+spec-1.1.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-17 09:34:32 -05:00
Dale Seo
08a5b0551b
fix: align task response types with MCP spec (#658) 2026-02-13 17:56:44 -05:00
Rodolfo Olivieri
453032faed
chore: include LICENSE in final crate tarball (#657)
Required for packaging in distributions such as Fedora and others.

Verified with:
$ cargo package --list | grep LICENSE
2026-02-13 16:13:45 -05:00
Arc
016b7d3bfa
feat: add support for custom HTTP headers in StreamableHttpClient (#655)
* feat: add support for custom HTTP headers in StreamableHttpClient

* feat: implement reserved header checks for custom HTTP headers in StreamableHttpClient
2026-02-13 12:28:55 -05:00
dependabot[bot]
70f6380b48
chore(deps): update rand requirement from 0.9 to 0.10 (#650)
* chore(deps): update rand requirement from 0.9 to 0.10

Updates the requirements on [rand](https://github.com/rust-random/rand) to permit the latest version.
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/rand_core-0.9.1...0.10.0)

---
updated-dependencies:
- dependency-name: rand
  dependency-version: 0.10.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix: update rand import from Rng to RngExt for rand 0.10 compatibility

In rand 0.10, the Rng trait was renamed to RngExt. This updates the
imports in the example servers to use the new trait name.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alex Hancock <alexhancock@block.xyz>
2026-02-13 10:24:17 -05:00
Anar Azadaliyev
d9a5560953
feat(auth): add token_endpoint_auth_method to OAuthClientConfig (#648)
* feat(auth): add token_endpoint_auth_method to OAuthClientConfig

Some OAuth providers (e.g. HubSpot) require client credentials to be
sent as POST body parameters (client_secret_post) instead of via HTTP
Basic Auth header. The oauth2 crate defaults to BasicAuth, and rmcp
had no way to override this, causing TokenExchangeFailed errors.

Add an optional `token_endpoint_auth_method` field to OAuthClientConfig
that accepts "client_secret_post" (RequestBody) and "client_secret_basic"
(BasicAuth). Unknown values are silently ignored, preserving the default.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(auth): derive token_endpoint_auth_method from server metadata

Move auth method selection from per-client config to server's
AuthorizationMetadata, which is the correct OAuth 2.0 approach.
Servers like HubSpot advertise token_endpoint_auth_methods_supported
in their metadata; reading it from there avoids manual configuration
and prevents TokenExchangeFailed errors with non-BasicAuth providers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(auth): read token_endpoint_auth_methods_supported from additional_fields

Move token_endpoint_auth_methods_supported out of AuthorizationMetadata
as an explicit field and read it from the serde(flatten) additional_fields
HashMap instead. This avoids serializing `null` when the field is absent,
which broke Zod validation in downstream consumers like MCP Inspector.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(auth): prefer basic auth when both methods supported and improve test assertions

When token_endpoint_auth_methods_supported contains both client_secret_post
and client_secret_basic, default to basic auth per RFC 6749 §2.3.1.
Update configure_client tests to assert actual AuthType instead of is_some().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style(auth): apply cargo fmt formatting

* style(auth): apply nightly cargo fmt import grouping

* revert: undo .gitignore change

---------

Co-authored-by: Anar Azadaliyev <anar.azadaliye@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 09:56:07 -05:00
Andrew Gazelka
bb534a7a68
refactor: remove unused axum dependency from server-side-http feature (#642)
* refactor: remove unused axum dependency from server-side-http feature

The `server-side-http` feature included `dep:axum` but axum was never
actually used in the rmcp library source code (0 references found).

The `StreamableHttpService` is a tower service that works with any
HTTP server framework. Users can choose to use:
- axum (via `Router::nest_service()` or `fallback_service()`)
- hyper directly (via `hyper_util::service::TowerToHyperService`)
- any other tower-compatible HTTP server

This change removes the unnecessary transitive dependency, giving users
more flexibility in their choice of HTTP server framework.

Examples that use axum already have their own explicit axum dependency
in their Cargo.toml, so they continue to work unchanged.

* refactor: move axum to dev-dependencies with minimal features

- Remove axum from library dependencies (not used in library source)
- Add axum to dev-dependencies for tests with minimal features:
  default-features = false, features = ["http1", "tokio"]
- Examples have their own axum dependency and are unaffected

This addresses review feedback from @ofek to use minimal features,
while ensuring axum is only bundled for running rmcp's own tests,
not for downstream users.
2026-02-12 12:00:47 -05:00
Wils Dawson
61845d61c4
11-25-2025 compliant Auth (#651)
* fix: correct discovery for AS metadata

* fix: add commitlint to dev container

* feat: add RFC 8707 support for resource parameter

* feat: pkce method verification

* feat(auth): implement SEP-835 scope handling and 403 upgrade flow

- add WWWAuthenticateParams for parsing scope and resource_metadata from headers
- add ScopeUpgradeConfig and scope tracking in AuthorizationManager
- add InsufficientScopeError and 403 handling in streamable HTTP client
- add scope union computation for progressive authorization
- export new public types: AuthClient, ScopeUpgradeConfig, WWWAuthenticateParams

Co-authored-by: fizy069 <fizy069@users.noreply.github.com>

* fix: reorg auth tests

* feat: add error to www-authenticate header parsing

* feat: consider protected resource metadata in scope selection

* fix: reorganize auth tests

* feat: add examples and docs for updated auth

---------

Co-authored-by: fizy069 <fizy069@users.noreply.github.com>
2026-02-12 11:30:13 -05:00
Alex Hancock
a1c66a8a36
chore: make pre-commit do formatting (#653) 2026-02-12 11:29:19 -05:00
Samuel Bustamante Larriet
3eb4c384d3
docs: add rudof-mcp to MCP servers list (#645) 2026-02-12 09:52:51 -05:00
github-actions[bot]
9cfc905a9e
chore: release v0.15.0 (#636)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-10 09:00:28 -05:00
Dale Seo
07028bc0aa
Add optional description field to Implementation struct (#649)
* feat: add optional description field to Implementation struct

* test: update snapshots
2026-02-10 08:36:47 -05:00
Pavel Bezglasny
187597bf7e
feat(elicitation): add support URL elicitation. SEP-1036 (#605) 2026-02-07 21:39:30 -05:00
Dale Seo
edd5b1d7e9
feat: enforce SEP-1577 MUST requirements for sampling with tools (#646) 2026-02-07 20:57:00 -05:00
Dale Seo
8bd3fcb890
Implement SEP-1577: Sampling With Tools (#628)
* feat: implement SEP-1577 sampling with tools support

* feat: add TryFrom<Content> for backward-compatible migration
2026-02-06 12:51:26 +01:00
Jiho Park
be23334f9d
fix(tasks): avoid dropping completed task results during collection (#639)
* fix(tasks): avoid dropping completed task results during collection

* chore(tasks): make `task_result_receiver` required

* refactor(tasks): make `collect_completed_results` private
2026-02-05 09:00:09 +01:00
Guy Lichtman
f6ebc7af13
fix(auth): oauth metadata discovery (#641)
* fix(auth): oauth metadata discovery

* fix: format auth.rs
2026-02-04 17:57:52 +01:00
Rodolfo Olivieri
bfd9cc08d8
feat: add native-tls as an optional TLS backend (#631)
Add reqwest-native-tls feature flag to allow users to choose between
rustls (default) and native-tls for HTTP transports.

native-tls uses platform-native TLS implementations:
- OpenSSL on Linux
- Secure Transport on macOS
- SChannel on Windows

This is particularly useful for Linux distribution packagers who need
to link against system TLS libraries (e.g., OpenSSL) rather than
bundling a separate TLS implementation. Linking against system libs
ensures security updates are applied system-wide and satisfies
distribution packaging policies.

Updated documentation to explain the available TLS backend options.
2026-02-03 19:27:37 -05:00
Evgenii
53b64a9f87
fix: compilation with --no-default-features (#593) 2026-02-03 19:21:06 -05:00
Luca Chang
df6c3f0665
fix(tasks): expose execution.taskSupport on tools (#635)
* fix(tasks): expose execution.taskSupport on tools

* feat: implement taskSupport validation on server
2026-02-03 19:17:36 -05:00
Andrew Harvard
1794fe1548
feat(capabilities): add extensions field for SEP-1724 (#643)
Add support for MCP extension capabilities in both ClientCapabilities
and ServerCapabilities structs, as specified in SEP-1724.

Changes:
- Add ExtensionCapabilities type alias (BTreeMap<String, JsonObject>)
- Add 'extensions' field to ClientCapabilities struct
- Add 'extensions' field to ServerCapabilities struct
- Update builder macros and impl blocks for both structs
- Add comprehensive tests for extension capabilities
- Update JSON schema test fixtures

This enables clients to advertise extension support during initialize,
such as:

  {
    "capabilities": {
      "extensions": {
        "io.modelcontextprotocol/ui": {
          "mimeTypes": ["text/html;profile=mcp-app"]
        }
      }
    }
  }

Closes #530
2026-02-03 19:14:22 -05:00