Commit graph go-sdk/mcp/client.go
Author SHA1 Message Date
Jonathan Amsterdam
02fa1b3ea6 internal/mcp: pointerize all the things
Use pointers for the protocol's struct types, to future-proof against
them getting large.

Change-Id: I55b204080a41c8140539697ba264e502e912e613
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672575
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-05-14 06:22:56 -07:00
Rob Findley
4f6510b9ae internal/mcp: merge the protocol package into mcp
In accordance with the updated design, merge the protocol package into
the mcp package. To do so, rename protocol.Content to WireContent and
protocol.ResourceContents to WireResource.

Also, remove some stray logging in readResource.

Change-Id: I76f61ce8d67dd3ac520ef2e1959ade0a0785a480
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672375
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2025-05-13 14:43:46 -07:00
Jonathan Amsterdam
1ae23e7031 internal/mcp: implement resources
Implementation of resources.

This follows the design sketched in design/design.md, except for
Server.FileResourceHandler, which will be in a forthcoming CL.

As the spec recommends, the server verifies an incoming URI from the
client against its list of resources, to make sure the URI came from one
of them.

Some things that aren't in the design doc:
- I provide an exported function that creates a "resource not found"
  jsonrpc2.WireEror error for server authors to return.
  A wrinkle: the MCP spec defines the error code for
  "resource not found" as -32002 [1]. That code is reserved for use
  by implementations of JSON-RPC, not applications. That matters to us
  because our JSON-RPC implementation already uses that code for the
  "server closing" error. I filed a bug against MCP about it [2] and
  chose a different code for the "resource not found" error.

- As a slight convenience, I fill in some fields in the
  ReadResourceResult if the handler doesn't set them.

[1] https://modelcontextprotocol.io/specification/2025-03-26/server/resources#error-handling
[2] https://github.com/modelcontextprotocol/modelcontextprotocol/issues/509

Change-Id: I06153da982ea00748a3691ded923448a880cea2a
Reviewed-on: https://go-review.googlesource.com/c/tools/+/671363
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
2025-05-13 11:39:49 -07:00
Jonathan Amsterdam
5004d3e1bb internal/mcp: implement roots
Add support for roots.

Change-Id: Ia50abc88f0047238272d698f30ce615b1a8fd486
Reviewed-on: https://go-review.googlesource.com/c/tools/+/671360
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
2025-05-13 07:52:49 -07:00
Rob Findley
347a1a0078 internal/mcp: rename ClientConnection to ServerConnection
It's too confusing that you send server requests through the Client, and
send client requests through the ClientConnection. Rename
ClientConnection to ServerConnection, so that the types on the
server side of the control diagram start with 'Server'.

Change-Id: Idfd27af464a9296a2341cd23b2075cd9d0eb6b45
Reviewed-on: https://go-review.googlesource.com/c/tools/+/670538
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Robert Findley <rfindley@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2025-05-07 10:17:38 -07:00
Jonathan Amsterdam
f8098af1c5 internal/mcp: NewClient takes Transport
Pass the client Transport to NewClient instead of Connect.
Combine the ConnectionOptions with the ClientOptions.

Change-Id: I3acd6cf6d5bf46666742f2a73e2acaef2057ea77
Reviewed-on: https://go-review.googlesource.com/c/tools/+/670215
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
2025-05-06 12:19:25 -07:00
Rob Findley
8efb54691d internal/mcp/protocol: move out of mcp/internal, as it's used in the API
The generated protocol package is part of the SDK API, so it shouldn't
be internal.

Change-Id: I5306af48019b1599707b939b348eb6ae4f766ca9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/670356
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2025-05-06 10:18:38 -07:00
Jonathan Amsterdam
7a76f3502a mcp: remove ServerConnection
Remove ServerConnection.
- It's not in typescript or mcpgo APIs.
- Amortizing a client over multiple servers doesn't have any value.

Change-Id: I725b42569733d6836864d96b16898a10ae91e570
Reviewed-on: https://go-review.googlesource.com/c/tools/+/669575
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
2025-05-02 13:30:38 -07:00
Rob Findley
bf608eeeae internal/mcp: clean up handling of content
Add support for all content types, and formalize the conversion of
content to and from the wire format (as a discriminated union).

Change-Id: I93678ce98c02176a524d2c82425fb1267ad68bf0
Reviewed-on: https://go-review.googlesource.com/c/tools/+/669135
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-01 19:15:30 -07:00
Rob Findley
af4d138732 internal/mcp: support prompts
Add support for 'prompts/list' and 'prompts/get', and registering
prompts on the server using AddPrompts. Add a 'MakePrompt' helper to
construct prompts from a prompt handler using reflection.

Change-Id: I479cb9c9b99313cca99640c1f5ea1939363759e6
Reviewed-on: https://go-review.googlesource.com/c/tools/+/669015
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2025-05-01 18:43:44 -07:00
Rob Findley
fe938f6eb7 internal/mcp: implement ping, and test request interleaving
Also validate that requests observe the lifecycle rules defined in the
spec.

Change-Id: I302282f81e053e76926e0bb295f7dbf8d526f02d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/667575
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Commit-Queue: Robert Findley <rfindley@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
TryBot-Bypass: Robert Findley <rfindley@google.com>
2025-04-23 19:15:29 -07:00
Rob Findley
ef446f82d7 internal/mcp: implement HTTP SSE transport
Add support for SSE transport, as defined by version 2024-11-05 and
2025-03-26 of the MCP spec.

In order to achieve this, the jsonrpc2 stream must be abstracted so that
we can implement it across multiple HTTP requests. This required some
refactoring of the jsonrpc2_v2 package, so that we can avoid the
Dialer/Binder interfaces and construct the Connection directly from its
constituent primitives.

Change-Id: Id627b5b5a474d92f2c613cfad904d14611e7c768
Reviewed-on: https://go-review.googlesource.com/c/tools/+/667475
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2025-04-23 19:15:20 -07:00
Rob Findley
34cc770852 internal/mcp: an MCP SDK prototype
This CL contains an minimal prototype of an MCP SDK, using the
"new" jsonrpc2_v2 package (similar to x/exp/jsonrpc2).

Much is still yet to do, but this initial version addressed the
following aspects:

- Support for newline delimited JSONRPC2 framing, and message logging.
- A generated protocol package, containing type definitions to be used
  in transport.
- A minimal jsonschema package to be used for both reading the MCP spec,
  and for serving Tool input schemas.
- A transport abstraction, and two transport implementations: stdio, and
  local (for testing).
- Client and Server types, to be configured with features and then
  connected using their Connect methods, which return (respectively) a
  ServerConnection and ClientConnection object.
- A minimal binding API for tools.

A catalog of things not yet done is in doc.go, but we should review this
CL eagerly, as it contains the fundamental building blocks of an
eventual SDK.

It is the intention that this package is more-or-less standalone, as it
may eventually be carved out into a separate repository. As such, its
only dependency within x/tools is jsonrpc2_v2, and the only change
required to that package is to expose a callback when the connection is
closed.

Change-Id: Ib66018961014f85a8884d56ab721d5642c98443c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/667036
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-04-22 14:37:47 -07:00