go-sdk/internal/docs/rough_edges.src.md
Robert Findley 3cf9f9908d
mcp: implement sampling with tools (#699)
Summary

Add support for tool use within sampling requests, as described in the
MCP 2025-11-25 spec's sampling.tools capability.
  New types

  Content types:
- ToolUseContent — represents a tool invocation request from the
assistant
- ToolResultContent — represents the result of a tool invocation, with
nested []Content for the result blocks

  Capability types:
  - SamplingCapabilities gains Tools and Context sub-fields
  - SamplingToolsCapabilities, SamplingContextCapabilities

  Tool-enabled sampling (parallel tool calls):
- CreateMessageWithToolsParams with SamplingMessageV2 (supports array
content)
  - CreateMessageWithToolsResult (supports array content)
  - ToolChoice — controls tool invocation mode (auto, required, none)
  - ServerSession.CreateMessageWithTools
  - ClientOptions.CreateMessageWithToolsHandler

  Design

Following the TypeScript SDK's pattern, tool-enabled sampling uses
separate types from basic sampling to avoid breaking the existing API.
The basic CreateMessage/CreateMessageResult path
   is unchanged.

Both paths share the same wire method (sampling/createMessage) and go
through the method info table. The table uses the broader
CreateMessageWithToolsResult type internally;
CreateMessage downconverts (erroring if multiple content blocks are
returned). This is documented as a rough edge to unify in v2.

Setting CreateMessageWithToolsHandler automatically infers the
sampling.tools capability. It is a panic to set both
CreateMessageHandler and CreateMessageWithToolsHandler.

  References

-
https://modelcontextprotocol.io/specification/2025-11-25/client/sampling
- TypeScript SDK: CreateMessageResultWithToolsSchema /
CreateMessageRequestParamsWithTools

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 12:07:08 +01:00

60 lines
2.8 KiB
Markdown

# Rough edges: API decisions to reconsider for v2
This file collects a list of API oversights or rough edges that we've uncovered
post v1.0.0, along with their current workarounds. These issues can't be
addressed without breaking backward compatibility, but we'll revisit them for
v2.
- `EventStore.Open` is unnecessary. This was an artifact of an earlier version
of the SDK where event persistence and delivery were combined.
**Workaround**: `Open` may be implemented as a no-op.
- `Event` need not have been exported: it's an implementation detail of the SSE
and streamable transports. Also the 'Name' field is a misnomer: it should be
'event'.
- Enforcing valid tool names: with
[SEP-986](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/986)
landing after the SDK was at v1, we missed an opportunity to panic on invalid
tool names. Instead, we have to simply produce an error log. In v2, we should
panic.
- Inconsistent naming.
- `ResourceUpdatedNotificationsParams` should probably have just been
`ResourceUpdatedParams`, as we don't include the word 'notification' in
other notification param types.
- Similarly, `ProgressNotificationParams` should probably have been
`ProgressParams`.
- `AudioContent.MarshalJSON` should have had a pointer receiver, to be
consistent with other content types.
- `ClientCapabilities.Roots` should have been a distinguished struct pointer
([see #607](https://github.com/modelcontextprotocol/go-sdk/issues/607)).
**Workaround**: use `ClientCapabilities.RootsV2`, which aligns with the
semantics of other capability fields.
- Default capabilities should have been empty. Instead, servers default to
advertising `logging`, and clients default to advertising `roots` with
`listChanged: true`. This is confusing because a nil `Capabilities` field
does not mean "no capabilities".
**Workaround**: to advertise no capabilities, set
`ServerOptions.Capabilities` or `ClientOptions.Capabilities` to an empty
`&ServerCapabilities{}` or `&ClientCapabilities{}` respectively.
- `CreateMessageResult.Content` is singular `Content`, but the 2025-11-25 spec
allows `content` to be a single block or an array (for parallel tool calls).
We added `CreateMessageResultWithTools` (with `Content []Content`) as a
workaround, matching the TypeScript SDK's approach. In v2,
`CreateMessageResult` should use `[]Content` directly. Similarly,
`SamplingMessage.Content` should become `[]Content` to support sending
multiple tool_result blocks in a single user message.
- We didn't actually need CallToolParams and CallToolParamsRaw, since even when
we're unmarshalling into a custom Go type (for the mcp.AddTool convenience
wrapper) we need to first unmarshal into a `map[string]any` in order to do
server-side validation of required fields. CallToolParams could have just had
a map[string]any.