Skip to content

add Result.resultType from protocol 2026-07-28 - #565

Merged
jakemac53 merged 2 commits into
dart-lang:mainfrom
Yusufihsangorgel:issue-162-result-type
Jul 24, 2026
Merged

add Result.resultType from protocol 2026-07-28#565
jakemac53 merged 2 commits into
dart-lang:mainfrom
Yusufihsangorgel:issue-162-result-type

Conversation

@Yusufihsangorgel

Copy link
Copy Markdown
Contributor

First slice of the 2026-07-28 core-protocol support tracked in #162, split out from the HTTP transport work to keep it small and reviewable on its own.

Adds the resultType result field as an additive, non-breaking API:

  • Result.resultType reads the field. A null value means the server did not send it; callers treat null as complete, the backward-compatible convention the 2026-07-28 schema requires for results from servers on earlier protocol versions. See Clarify resultType is required; reframe absent-field handling as backward compat modelcontextprotocol/modelcontextprotocol#2726, which reframes an absent resultType as backward compatibility.
  • The getter is a nullable String, exactly matching CreateMessageResult.stopReason (both String?), the open union this package already has. The schema types resultType as "complete" | "input_required" | string, so a server may send a value this package does not know. A closed enum cannot represent that set; it would have to throw on an unknown value or fold it into a fallback constant, and both lose the string the server actually sent. See fix(SEP-2322): Explicitly support extending ResultType modelcontextprotocol/modelcontextprotocol#2773, the SEP-2322 fix that made ResultType an open union so servers can extend it.
  • No latestSupported bump and no server-side emission; those are later slices. This is the read side, so a client parses resultType from a 2026-07-28 server correctly without waiting for the rest.

Tests

  • resultType is null when the field is absent, and passes both a known value and an unknown string through unchanged.
  • dart test -p chrome,vm -c dart2wasm,dart2js,kernel,exe passes (219 tests in each of the four configurations).
  • dart analyze --fatal-infos is clean here and in mcp_examples resolved against this branch. The diff only adds lines, so existing formatting is untouched.

Part of #162.

Model the resultType result field (schema draft 2026-07-28) as a
non-breaking, additive API: a Result.resultType getter which returns the
raw string, or null when the field is absent. A null value means the
server did not send the field, and the caller treats it as complete, as
the spec requires for results from servers on earlier protocol versions.

The schema types the field as an open union, so the getter returns a
nullable String, matching CreateMessageResult.stopReason.

No protocol version bump and no server emission yet; those land in later
slices. Part of dart-lang#162.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the Result.resultType getter to the Result extension type in pkgs/dart_mcp/lib/src/api/api.dart, modeling the resultType field from the 2026-07-28 draft schema. It also adds the corresponding constant in constants.dart, updates the changelog, and includes unit tests verifying that resultType is null when absent and correctly passes string values through. There are no review comments, and I have no feedback to provide.

Comment thread pkgs/dart_mcp/lib/src/api/api.dart Outdated
@jakemac53
jakemac53 merged commit eb11f59 into dart-lang:main Jul 24, 2026
26 checks passed
jakemac53 pushed a commit that referenced this pull request Jul 27, 2026
Next 2026-07-28 core-protocol slice tracked in #162, following #565 and kept separate from the HTTP transport work.

Adds the `CacheableResult` "mixin" extension type and the `CacheScope` enum, modeling the caching hints from modelcontextprotocol/modelcontextprotocol#2549:

- `CacheableResult.ttlMs` reads the TTL hint as an `int`. The spec requires servers to send `ttlMs >= 0` and tells clients to treat both an absent value and a negative one as `0` (https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/draft/server/utilities/caching.mdx; servers on earlier protocol versions never send the field), so the getter reads `0` for both. Same fold `Result.resultType` does with `complete`.
- `CacheableResult.cacheScope` reads the scope as a nullable `CacheScope`. The schema types the field as a closed `"public" | "private"` union with no absent-value default, so the getter is an enum like the package's other closed unions (`Role`, `LoggingLevel`) but resolves the way `Schema.type` does: an absent or unrecognized value reads as `null` instead of throwing, which keeps results from older servers readable and leaves room for the still-draft schema to grow the union before the RC.
- The type mirrors `PaginatedResult`: no public constructor, "mixed in" by other extension types. The schema attaches it to the four list results, `ReadResourceResult`, and the new `DiscoverResult`; the five that already exist in this package now implement it, so the hints are readable on the results the client API already returns. `DiscoverResult` itself and server-side emission of the hints (factory parameters) are follow-up slices.

## Tests

- `ttlMs` reads `0` on an empty result and for a negative value, `cacheScope` reads `null` when absent, both parse when present, an unrecognized scope string reads as `null`, and a `ListToolsResult` carrying the fields exposes both.
- `dart test -p chrome,vm -c dart2wasm,dart2js,kernel,exe` passes (220 tests in each of the four configurations).
- `dart analyze --fatal-infos` is clean here and in `mcp_examples` resolved against this branch.

Part of #162.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants