Commit graph rust-sdk/crates/rmcp/tests
Author SHA1 Message Date
Dale Seo
2d90b76501
fix: api ergonomics follow-up (#720)
* fix: builder with_* methods take T instead of Option<T>

* fix: emit conditional builder calls for optional fields in macros

* fix: convert with_task, with_stop_reason, with_logger, with_content to proper builders

* fix: update test callers for new builder signatures

* fix: simplify make_task helper and remove unused import

* fix: update sampling_stdio example for new with_stop_reason signature

* fix: make annotations and execution Option<Expr> consistent with other fields

* fix: remove unused none_expr import
2026-03-03 12:05:32 -05:00
Adam Kowalski
1fe5d1e1cd
fix(streamable-http): map stale session 401 to status-aware error (#709)
* fix(streamable-http): map stale session 401 to status-aware error

* test(streamable-http): expect 404 for stale session
2026-03-03 12:01:14 -05:00
Jack Amadeo
f63718d202
chore: add #[non_exhaustive] and mutation methods to improve compatibility (#715)
* chore: add #[non_exhaustive] to reduce backwards-incompatible changes going forward

* fix: remove ProtocolVersion import

* fix: add a few more with_ mutator methods

---------

Co-authored-by: Alex Hancock <alexhancock@block.xyz>
2026-03-03 10:38:01 -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
Dale Seo
93bfb4ac6b
feat: add default value support to string, number, and integer schemas (#686) 2026-02-26 10:02:11 -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
Dale Seo
5fa012d163
feat: send and validate MCP-Protocol-Version header (#675) 2026-02-24 11:08:49 -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
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
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
Dale Seo
08a5b0551b
fix: align task response types with MCP spec (#658) 2026-02-13 17:56:44 -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
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
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
apexlnc
32a68aa239
fix(tasks): correct enum variant ordering for deserialization (#634)
Move CustomRequest and CustomResult to end of their respective untagged
enums to ensure specific task variants match before catch-all custom types.
Add deny_unknown_fields to GetTaskInfoResult to prevent matching arbitrary
JSON objects.

Fixes issue where tasks/get, tasks/list, tasks/result, and tasks/cancel
incorrectly deserialized as CustomRequest instead of their typed variants.
2026-01-30 09:30:53 +08:00
Alex Hancock
613eafbda8
fix(tasks): #626 model task capabilities correctly (#627) 2026-01-23 13:03:31 -05:00
Dale Seo
9e881a645b
Implement SEP-1319: Decouple Request Payload from RPC Methods (#617)
* feat: implement SEP-1319 Decouple Request Payload from RPC Methods

* test: update tests

* fix: update handler trait methods to use new types

* fix: update examples

* fix: correct deprecation version

* fix: update wrapper macros to use new *Params type names
2026-01-16 12:16:52 -05:00
Xing
95d3e3f940
fix: use the json rpc error from the initialize response and bubble it up to the client (#569) 2026-01-14 11:28:54 -05:00
Taylor Ninesling
81f858836d
feat: provide blanket implementations for ClientHandler and ServerHandler traits (#609)
* feat!: implement ServerHandler for Box<H> and Arc<H> where H is a ServerHandler

* feat!: implement ClientHandler for Box<H> and Arc<H> where H is a ClientHandler

* test: test Box and Arc have blanket implementations for handler traits

* refactor: deduplicate blanket implementations with macros
2026-01-14 10:53:05 -05:00
Jack Amadeo
46e149ee8b
chore: clean up optional dependencies (#546) 2026-01-13 21:29:35 -05:00
Tyler Mailman
cc96f379ba
feat(service): add close() method for graceful connection shutdown (#588)
This PR primarily fixes #572 by enabling graceful shutdown without consuming self. While implementing this, I noticed delete_session() is spawned as a background task, which means close() may return before HTTP session cleanup completes. Since this is part of the same shutdown lifecycle and can cause resource leaks/races, I'm including a small, localized fix to ensure cleanup is completed before close() returns. If maintainers prefer, I can split the cleanup timing change into a follow-up PR.

Changes:
- Add close(&mut self) for graceful shutdown without consuming
- Add close_with_timeout() for bounded shutdown operations
- Add is_closed() to check connection state
- Move HTTP delete_session from background spawn to inline cleanup
- Add 5-second timeout on session cleanup to prevent indefinite hangs
- Add Drop impl with debug log if dropped without explicit close

Fixes #572
2026-01-13 16:25:06 -05:00
Dale Seo
971c64c31f
Implement SEP-1699: Support SSE Polling via Server-Side Disconnect (#604)
* feat: implement SEP-1699 SSE polling via server-side disconnect

* test: add tests for priming behavior on stream start and close
2026-01-09 13:22:57 -05:00
Pavel Bezglasny
e9029ccc99
feat(elicitation): implement SEP-1330 Elicitation Enum Schema Improvements (#539) 2025-12-24 13:54:20 -05:00
jokemanfire
621c9f619e
feat(task): add task support (SEP-1686) (#536)
Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
2025-12-22 09:01:00 -05:00
Dale Seo
eeacd1375f
Add optional icons field to RawResourceTemplate (#589)
* feat: add optional icons field to RawResourceTemplate

* chore: update JSON schema for ResourceTemplate icons
2025-12-18 16:56:55 -05:00
Michael Bolin
e0faf1ed51
feat: add support for custom requests (#590)
#580 and #556 introduced support for custom notifications,
so this PR takes the next logical step and adds support for custom requests:

- Introduces `CustomRequest` and `CustomResult` model types, wires them into the client/server
  request and result unions, and allows `ClientRequest::method()` to return the dynamic method
  name.
- Implements serde and meta handling for `CustomRequest` so `_meta` is carried through
  extensions; adds default `on_custom_request` handlers that return `METHOD_NOT_FOUND` unless
  overridden.
- Updates JSON schema fixtures to include the new request/result shapes and `EmptyObject`
  strictness.
- Adds tests for custom request roundtrips and end-to-end client↔server handling.
- Focused integration test in `crates/rmcp/tests/test_custom_request.rs`.

For additional testing, I used this locally to update Codex to use a custom
request instead of a custom notification so that it gets an "ack" from the MCP
server to ensure it has processed the update before sending more messages:
https://github.com/openai/codex/pull/8142.
2025-12-18 12:41:06 -05:00
Michael Bolin
2e3cc4a973
feat: add support for custom server notifications (#580)
https://github.com/modelcontextprotocol/rust-sdk/pull/556 introduced support for
custom client notifications, so this PR makes the complementary change, adding
support for custom server notifications.

MCP clients, particularly ones that offer "experimental" capabilities,
may wish to handle custom server notifications that are not part of the
standard MCP specification. This change introduces a new
`CustomServerNotification` type that allows a client to process
such custom notifications.

- introduces `CustomServerNotification` to carry arbitrary methods/params while
  still preserving meta/extensions; wires it into the `ServerNotification` union
  and `serde` so `params` can be decoded with `params_as`
- allows client handlers to receive custom notifications via a new
  `on_custom_notification` hook
- adds integration coverage that sends a custom server notification end-to-end
  and asserts the client sees the method and payload

Test:

```shell
cargo test -p rmcp --features client test_custom_server_notification_reaches_client
```
2025-12-16 12:48:03 -05:00
Dale Seo
8d33b155b6
refactor: merge cached_schema_for_type into schema_for_type (#581) 2025-12-09 20:04:52 -05:00
Pavel Bezglasny
81411fc12d
feat(meta): add _meta field to prompts, resources and paginated result (#558) 2025-12-04 09:38:47 +08:00
adam jones
eb5a7f7408
feat!: remove SSE transport support (#562)
SSE transport has been removed from the MCP specification in favor of
streamable HTTP. This removes all SSE-specific transport code:

- Remove `transport-sse-client` and `transport-sse-server` features
- Remove `SseClientTransport` and `SseServer` types
- Remove SSE-specific examples (`counter_sse`, `counter_sse_directly`)
- Migrate auth examples from SSE to streamable HTTP
- Update tests to remove SSE transport usage
- Update documentation

BREAKING CHANGE: The following have been removed:
- `transport-sse-client` feature
- `transport-sse-client-reqwest` feature
- `transport-sse-server` feature
- `SseClientTransport` type
- `SseServer` type
- `sse_client` and `sse_server` modules

Users should migrate to streamable HTTP transport which provides
equivalent functionality. See `StreamableHttpClientTransport` and
`StreamableHttpService` for the replacement APIs.

Ref: https://github.com/modelcontextprotocol/rust-sdk/pull/561#issuecomment-3576551699
2025-12-01 20:40:13 -05:00
Jonson Petard
3dee024325
fix(streamable-http): gracefully shutdown while client connected (#494)
* fix(streamable-http): gracefully shutdown while client connected

* fix: adviced comments

* fix: windows test build
2025-12-02 09:22:52 +08:00
Michael Bolin
4ef1a163f4
feat: add support for custom client notifications (#556)
MCP servers, particularly ones that offer "experimental" capabilities,
may wish to handle custom client notifications that are not part of the
standard MCP specification. This change introduces a new
`CustomClientNotification` type that allows a server to process
such custom notifications.

- introduces `CustomClientNotification` to carry arbitrary methods/params while
  still preserving meta/extensions; wires it into the `ClientNotification` union
  and `serde` so `params` can be decoded with `params_as`
- allows server handlers to receive custom notifications via a new
  `on_custom_notification` hook
- adds integration coverage that sends a custom client notification end-to-end
  and asserts the server sees the method and payload

Test:

```shell
cargo test -p rmcp --features client test_custom_client_notification_reaches_server
```
2025-12-01 15:58:18 -05:00
jokemanfire
76cdf48b68
fix(shemars): use JSON Schema 2020-12 as Default Dialect (#549)
TODO: Not fully compatible with 2020-12 yet.
2025-11-19 09:55:39 +08:00
Dylan Anthony
03040f8b0b
feat(tool): add _meta to tool definitions (#534) 2025-11-11 09:27:52 +08:00
sktrpathi
11093bc830
feat: add type-safe elicitation schema support (#465) (#466)
* feat: add type-safe elicitation schema support (#465)

Implement type-safe schema definitions for MCP elicitation requests,
replacing generic `JsonObject` with strongly-typed primitive schemas
per the [MCP 2025-06-18 specification](https://spec.modelcontextprotocol.io/specification/2025-06-18/server/elicitation/).

Features:
- Type-safe schema hierarchy (`StringSchema`, `NumberSchema`, `IntegerSchema`, `BooleanSchema`)
- Builder pattern with fluent API and 20+ convenience methods
- Build-time validation ensuring required fields exist in properties
- Private fields enforcing invariants through validated constructors
- Comprehensive validation support (range, length, format, enums)
- Typed property methods for cleaner schema construction

Benefits:
- Compile-time type safety prevents invalid schema construction
- 60-70% reduction in boilerplate through convenience methods
- Enforces MCP specification requirement for primitive-only properties
- Better IDE autocomplete and type inference
- Runtime validation catches schema errors early

Breaking changes:
- `CreateElicitationRequestParam.requested_schema` changed from `JsonObject` to `ElicitationSchema`
- `ElicitationSchemaBuilder::build()` now returns `Result` instead of direct value

Fixes #465

* fix: fix RMCP compliance

* feat: add conversion methods to ElicitationSchema

Add from_json_schema() and from_type() methods to ElicitationSchema
for easier type-to-schema conversion. This addresses feedback about
improving ergonomics when working with generated schemas.

Also make all struct fields public for better flexibility.

* chore: change `StringFormat` to enum
2025-10-15 17:55:10 +08:00
Honsun Zhu
b749e3c9b4
feat(SEP-973): following change Icon.sizes from string to string array (#479)
Ref:
https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1531
2025-10-10 19:23:04 +08:00
V
717ec56e23
fix: generate default schema for tools with no params (#446)
* fix: generate default schema for tools with no params
2025-09-26 18:16:08 +08:00
Jack Amadeo
57fc428c57
chore: bump to rust 1.90.0 (#453) 2025-09-24 12:58:54 -04:00
Rob Jellinghaus
ddef4ce529
fix(clippy): add doc comment for generated tool attr fn (#439)
This change makes the `tool` macro's output safe for the `missing_docs` lint, by
emitting a doc comment for the generated `[tool]_tool_attr` function. This doc
comment is emitted regardless of whether the tool function is public, for simplicity.

We are building an MCP server using `rmcp` and discovered that the current crate
was not compatible with the `#![deny(missing_docs)]` lint which we use everywhere.

Tested by modifying the `test_tool_macros.rs` test to use `#![deny(missing_docs)]`
and adding doc comments to all pub fns and structs in that file.

None.

Fixes #438.

Co-authored-by: RobJellinghaus <rjellinghaus@live.com>
2025-09-17 15:02:56 +08:00
Alex Hancock
b57aa47693
feat(SEP-973): add support for icons and websiteUrl across relevant types (#432) 2025-09-11 11:49:03 -04:00
Andrei G
452fe2c50f
feat: implement context-aware completion (MCP 2025-06-18) (#396)
* feat: implement MCP completion specification 2025-06-18

Complete implementation of MCP completion specification with performance optimizations:

Core Features:
- Add CompletionContext for context-aware completion with previously resolved arguments
- Implement CompletionProvider trait with async support and dyn compatibility
- Create DefaultCompletionProvider with optimized fuzzy matching algorithm
- Add comprehensive validation and helper methods to CompletionInfo
- Update ServerHandler to handle completion/complete requests
- Add client convenience methods for prompt and resource completion

Performance Optimizations:
- Zero-allocation fuzzy matching using index-based scoring
- Top-k selection with select_nth_unstable instead of full sorting
- Pre-allocated vectors to avoid reallocations during matching
- Char-based case-insensitive matching to minimize string operations
- 5-8x performance improvement for large candidate sets

API Design:
- Context-aware completion supporting multi-argument scenarios
- Type-safe validation with MAX_VALUES limit (100 per MCP spec)
- Helper methods: with_all_values, with_pagination, validate
- Reference convenience methods: for_prompt, for_resource
- Client methods: complete_prompt_argument, complete_resource_argument

Testing:
- 17 comprehensive tests covering all functionality
- Schema compliance tests for MCP 2025-06-18 specification
- Performance tests with <100ms target for 1000 candidates
- Edge case and validation tests

Schema Updates:
- Add CompletionContext to JSON schema
- Update CompleteRequestParam with optional context field
- Maintain backward compatibility with existing API

* test: add comprehensive fuzzy matching tests for completion

Add three new test cases to enhance coverage of fuzzy matching algorithm:

- test_fuzzy_matching_with_typos_and_missing_chars: Tests subsequence matching
  with real-world scenarios including abbreviated patterns, case-insensitive
  matching, and complex file/package name completion

- test_fuzzy_matching_scoring_priority: Validates scoring system prioritizes
  exact matches > prefix matches > substring matches > subsequence matches

- test_fuzzy_matching_edge_cases: Covers boundary conditions including
  single character queries, oversized queries, and repeated characters

These tests ensure robust fuzzy search functionality for MCP completion
specification implementation with proper handling of user typos and
incomplete input patterns.

* feat: improve completion algorithms, add comprehensive tests and example

- Enhance fuzzy matching algorithm with acronym support for multi-word entries
- Add comprehensive scoring system for better relevance ranking
- Implement multi-level matching: exact, prefix, word prefix, acronym, substring
- Add context-aware completion scoring with proper priority ordering
- Optimize performance through efficient character-by-character matching
- Support case-insensitive acronym matching
- Improve code quality with clippy fixes and async fn syntax
- Add comprehensive test suite covering edge cases and acronym matching
- Create completion example server demonstrating weather-related prompts

* fix(test): typos

* refactor: improve completion API and replace example with SQL query builder

- Remove DefaultCompletionProvider from library core
- Move completion logic to examples following review feedback
- Update CompletionContext.argument_names() to return Iterator for better performance
- Replace tech search example with SQL query builder demonstrating progressive completion
- Add context-aware completion that adapts based on filled arguments
- Use proper Option types for optional SQL fields (columns, where_clause, values)
- Demonstrate real-world value of argument_names() method for dynamic completion flow

The SQL query builder showcases:
• Progressive field availability based on operation type
• Context validation using argument_names()
• Proper Optional field handling
• Smart completion that guides user through multi-step form

* fix: fmt
2025-09-08 14:44:49 +08:00
Dale Seo
b482cfc4bb
fix: generate simple {} schema for tools with no parameters (#425) 2025-09-08 14:40:02 +08:00
4t145
1b70f5b032
feat: add title field for data types (#410)
* feat(model): add title field to various structs

* fix(test): fix test json schema

* fix(model): allow boxed type  in `ts_union` macro
2025-09-08 09:15:22 +08:00
Andrew Harvard
4eb413b6c6
Spec conformance: meta support and spec updates (#415)
* feat: add _meta to content blocks and embedded resources; update schemas

* feat: set default protocol version; add _meta to content blocks/resources; update schemas

* chore: format content.rs via rustfmt

* chore(protocol): keep LATEST at 2025-03-26 per review until full 2025-06-18 compliance

* feat(prompt): add constructors with optional meta for image and resource

- Keep text helper; meta is currently ignored for text until schema supports it.

* refactor(prompt): simplify constructors so meta is optional; remove duplicate non-meta variants

* fix: modify code comment about version

* refactor(prompt): rename meta parameters in new_resource function for clarity
2025-09-04 14:23:36 -04:00
4t145
f381c2b899
fix: remove batched json rpc support (#408)
* fix: remove batched json rpc  support

* fix(test): fix schema
2025-09-03 14:13:55 +08:00