Commit graph go-sdk/mcp/testdata/conformance/server/tools.txtar
Author SHA1 Message Date
Ravish Gupta
74d2751d88
mcp: return input validation errors as tool results, not JSON-RPC errors (#863)
This implements [SEP-1303](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1303).

Input validation errors (missing required fields, wrong types) during
tool calls
are now returned as `CallToolResult` with `IsError=true` instead of
JSON-RPC
`-32602` errors. This allows LLMs to see the validation error and
self-correct,
  per the MCP spec.
The existing pattern for handler-returned errors (lines 347-350 in
server.go)
already converts regular errors to tool results with `IsError=true`.
This change
applies the same pattern to argument schema validation and unmarshal
errors,
  resolving the `TODO(#450)` in the code.                   

Thanks to @iwyrkore for filing the issue and proposing the approach, and
  @findleyr for the cross-SDK analysis in the discussion.
  Fixes #450

Co-authored-by: Maciej Kisiel <mkisiel@google.com>
2026-03-31 10:14:36 +02:00
Jonathan Amsterdam
9c4d349ec0
go.mod: upgrade to jsonschema v0.4.2 (#732)
Visible changes:

- Inference on structs populates PropertyOrder

- An empty map for Schema.Properties marshals as "{}"
2026-01-04 09:18:01 -05:00
Rob Findley
9f1b8646bd mcp: propertly validate against JSON, independent of Go values
Our validation logic was avoiding double-unmarshalling as much as
possible, by parsing before validation and validating the Go type.

This only works if the Go type has the same structure as its JSON
representation, which may not be the case in the presence of types with
custom MarshalJSON or UnmarshalJSON methods (such as time.Time).

But even if the Go type doesn't use any custom marshalling, validation
is broken, because we can't differentiate zero values from missing
values.

Bite the bullet and use double-unmarshalling for both input and output
schemas. Coincidentally, this fixes three bugs:
- We were accepting case-insensitive JSON keys, since we parsed first,
  even though they should have been rejected. A number of tests were
  wrong.
- Defaults were overriding present-yet-zero values, as noted in an
  incorrect test case.
- When "arguments" was missing, validation wasn't performed, no defaults
  were applied, and unmarshalling failed even if all properties were
  optional.

First unmarshalling to map[string]any allows us to fix all these bugs.
Unfortunately, it means a 3x increase in the number of reflection
operations (we need to unmarshal, apply defaults and validate,
re-marshal with the defaults, and then unmarshal into the Go type).
However, this is not likely to be a significant overhead, and we can
always optimize in the future.

Update github.com/google/jsonschema-go to pick up necessary improvements
supporting this change.

Additionally, fix the error codes for invalid tool parameters, to be
consistent with other SDKs (Invalid Params: -32602).

Fixes #447
Fixes #449
Updates #450
2025-09-12 10:50:19 -04:00
Rob Findley
9d34aff732 mcp: avoid "null" in structuredContent
Avoid a typed nil in structuredContent (yet another typed nil), leading
to "null" on the wire.

Fixes #417
2025-09-04 19:48:51 -04:00
Robert Findley
d8e18b34cf
mcp: fix bugs handling pointer types (#344)
Some bad merging in #338 led to a bad bug in the handling of structured
output for pointer output types. Add a conformance test and fix the bug.
2025-08-21 14:43:22 -04:00
Rob Findley
5ab63feefa mcp: don't mark the server sesion as initialized prematurely
Update ServerSession so that the session is not marked as initialized
until 'notifications/initialized' is actually received from the client.

Include a new test of this lifecycle strictness.

Fixes #225
2025-08-07 14:59:36 -04:00
Jonathan Amsterdam
c132621eb0
jsonschema: marshal to bools (#247)
Marshal the empty schema to true, and its negation to false.

This is technically a breaking behavior change, but a properly written
consumer of JSON Schema will not notice.

For #244.

Fixes #230.
2025-08-06 11:41:02 -04:00
Sam Thanawalla
faaf77dc05
mcp/server: advertise completions only if installed (#213)
Previously, completions would always be advertised as a capability even
if the CompletionHandler was not installed by the server. This CL fixes
that.
2025-08-04 10:12:01 -04:00
Robert Findley
b34ba2149d
mcp: handle bad or missing params (#210)
Audit all cases where params must not be null, and enforce this using
methodInfo via a new methodFlags bitfield that parameterizes method
requirements. Write extensive conformance tests catching all the
(server-side) crashes that were possible.

We should go further and validate schema against the spec, but that is
more indirect, more complicated, and potentially slower. For now we
adopt this more explicit approach.

Still TODO in a subsequent CL: verify the client side of this with
client conformance tests.

Additionally, improve some error messages that were redundant or leaked
internal implementation details.

Fixes #195
2025-07-31 10:57:59 -04:00
Jonathan Amsterdam
de4b788e59
mcp: fix conformance tests (#132)
- Use new AddXXX API.

- Update goldens to reflect new capability logic.

Fixes #131.
2025-07-14 12:47:58 -04:00
Robert Findley
204b59483b
mcp,design: revert 'content' back to an interface type (#29)
After some experience with the flattened version of Content, we see that
it can easily lead to incorrect usage and is a harder API to read.
Therefore, this CL changes back to a design similar to what we had prior
to https://go.dev/cl/672415, though opting to promote content
unmarshalling to the protocol types that use it, which leads to an
overall simpler api.
2025-06-25 13:09:05 -04:00
Rob Findley
e2bbd8002d internal/mcp: add JSON conformance tests, and fix some bugs
Add the beginnings of some testdata-driven conformance tests that check
JSON-level compatibility of SDK messages, and fix some bugs in our JSON
message handling:

- "params" can be missing
- "_meta" should not be null
- lists of tools/prompts/resources should not be null

In order to implement this, we need to be able to know when the server
is done processing messages. In general, this is a hard problem; for
gopls we do this with a complicated system of progress reporting and
accounting. However, the new synctest package makes this trivial, as we
can call synctest.Wait to detect when the server is idle. Therefore,
this test requires 1.25 (it uses synctest.Test, added in 1.25, and so
can't run at 1.24 with GOEXPERIMENT=synctest).

Change-Id: I97fa28b56868340ece266a58e1eb3c3bf8cfe0e9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676538
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
2025-05-28 10:00:05 -07:00