A dynamic reference is like a dynamic variable in a programming
language, with two twists:
- There must be a dynamic anchor in lexical scope for the ref to
resolve. (Think of it as declaring the dynamic variable.)
- The ref resolves to the schema highest on the stack, not lowest.
That feels odd, but it turns out to work for the intended purpose,
which is to provide extension points for additional features.
There is some distracting code motion and refactoring in this CL:
resolveRefs was moved down in the file, and resolution of a single
ref was split off.
Change-Id: I17da6052e0782fc540d14b8a41b06a2645923872
Reviewed-on: https://go-review.googlesource.com/c/tools/+/674155
Auto-Submit: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This change is necessary to support pagination which will be implemented
in subsequent CLs.
Change-Id: I8bc616a57463ea569dc7cadf1d4f06c69602ddd5
Reviewed-on: https://go-review.googlesource.com/c/tools/+/674135
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Remove a TODO that was in package doc position.
Change-Id: Ib98dbcd7d733fdf0059bc3ced1fd6a1008b91a26
Reviewed-on: https://go-review.googlesource.com/c/tools/+/674257
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Augment the generator to create constants for all method names.
Change-Id: I858e516b1afec0aa3cf3b9852cbdfc16aec4c553
Reviewed-on: https://go-review.googlesource.com/c/tools/+/673177
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Implement middleware for clients.
Make the middleware types generic so we can factor out code
from both peers.
I was able to make the request handler generic, with one weird trick
(see handleRequest).
The first three declarations of shared.go, and a few others as well,
are copied unchanged from middleware.go.
Change-Id: Ib3239d8fcfda022ddb5b554c38cff4cdbc3704c1
Reviewed-on: https://go-review.googlesource.com/c/tools/+/673635
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Provide secure reading of files on the local filesystem.
There are subtleties in path manipulation on Windows that I don't fully
understand, so I defer that work for now.
Change-Id: Ic11f4617dde4ac0b31ccd5b0a772bb2f56db026f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/673196
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Implement the dispatcher middleware framework, allowing users to
wrap method dispatching with their own code.
The Dispatcher functions have an untyped params arg, but expect its
value to be a typed, unmarshaled XXXParams struct. That required
splitting the elegant dispatch[P, R] function into two parts, one
to do the unmarshaling and one to call the method. The nicest way
I could find to do that was to map from method names to a pair
of functions, one to unmarshal and one to call. We could also write
it as two switches on method name, which would require less machinery
but would duplicate the list of method names, already a tad fragile
because they are literal strings.
I also exported the initialize params and result, so user Dispatchers
could access them. All Params and Result types will have to be exported
for that reason.
Change-Id: Ie2c95cc17b4ef3d3d095dccdadb294e5f1590796
Reviewed-on: https://go-review.googlesource.com/c/tools/+/673515
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Due to the irregularities of github-flavored markdown, I had to join all
paragraphs before posting the public design. Additionally, I made a few
wording tweaks.
If we want to continue editing the design here, we should keep it in
sync with the public design discussion. Therefore, copy back those
changes.
Change-Id: Ie6ab3b3f59b923bb58540e86bbb1451ce0b4815d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/673199
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Do another pass of clean up for the design prior to posting.
Also, add a cached Roots iterator, as discussed.
Change-Id: If8d444b23c7332b89effb2fce8b3be28841f0882
Reviewed-on: https://go-review.googlesource.com/c/tools/+/673195
TryBot-Bypass: Sam Thanawalla <samthanawalla@google.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
TryBot-Bypass: Robert Findley <rfindley@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Update the README to reflect recent API changes. Also, remove some
design discussion in the README, to instead refer to the canonical
design doc.
Change-Id: Id77d34c6364d0a35e33f6952a291b3b659ad732b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672619
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Do a pass through the design doc, adding a bit more clean-up and
commentary.
Additionally, update ServerTool and ServerPrompt to be consistent with
the design.
Change-Id: I1b75c4690d86fe8946d512cb36a1fc2938b3c883
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672576
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Since cancellation is handled transparently, this type need not be
exported.
Change-Id: Id4e195b0c3bd49eca52587032a027ffa449eb9d1
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672796
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Add a logical client session type back to the SDK, to bring it closer to
the design. Also, remove 'ConnectionOptions', which is better
implemented using middleware, and reimplement logging as a
LoggingTransport middleware, which is also added to the design.
Change-Id: I908b4f837d513ffc60ae5b6171a31519cffafebc
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672795
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Various typo and style changes.
Change-Id: Ifd4322dcf0bf2b2653bb38a023a51056424cca39
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672815
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Commit-Queue: Jonathan Amsterdam <jba@google.com>
TryBot-Bypass: Jonathan Amsterdam <jba@google.com>
Add a link to a recent commit that illustrates a backward-compatible
change.
Change-Id: I5e277f9417cf9bbbc5146512e29a3cb8205a4e14
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672716
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
TryBot-Bypass: Jonathan Amsterdam <jba@google.com>
Commit-Queue: Jonathan Amsterdam <jba@google.com>
Update the design to mention our in-memory transport, since it is
generally useful, and update the implementation to use distinct types
for InMemoryTransport and StdIOTransport (the fact that they are both
implemented as an io.ReadWriteCloser is an implementation detail).
Change-Id: I8228ccf2092a56a730c113c4db105fb492cce112
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672715
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Commit-Queue: Robert Findley <rfindley@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
TryBot-Bypass: Robert Findley <rfindley@google.com>
Bring the Server implementation up to date with the spec by renaming
ServerConnection to ServerSession. Also update variable names, which
were in various states of disarray from the multiple renamings of this
type.
Change-Id: I4aec883db6d0500fb91e6daa51b702614877cf8a
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672655
Auto-Submit: Robert Findley <rfindley@google.com>
TryBot-Bypass: Robert Findley <rfindley@google.com>
Commit-Queue: Robert Findley <rfindley@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Change-Id: I2cb8be82a91dea7755ea5514ee1fbe1e937135c9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672376
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
TryBot-Bypass: Jonathan Amsterdam <jba@google.com>
Commit-Queue: Jonathan Amsterdam <jba@google.com>
Get the name and signature of the handler right.
Change-Id: I743aaaee45cc07a741ab8ad16e90e1b1d5519b64
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672336
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>
Change-Id: I5f7a6bad296d23c1bc075eb767a243c24a42668c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672675
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Sam Thanawalla <samthanawalla@google.com>
TryBot-Bypass: Sam Thanawalla <samthanawalla@google.com>
Commit-Queue: Sam Thanawalla <samthanawalla@google.com>
Change the type of CallToolParams.Arguments to json.RawMessage.
Change-Id: Ief16ef261b9f41566a1a16efc60a9382a8d414eb
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672615
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
CallTool takes a tool name, arguments, and an options struct.
Also, pass the params to ToolHandler.
Update the design doc accordingly.
Change-Id: I21b7995b607bea976ad708ebb6ac0716018f39cb
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672596
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
To ensure backward compatibility, every method in the spec now takes a
*Params struct and returns a *Result struct.
CallTools is an exception: we'll change that in the next CL.
Change-Id: I58835239c67582401b8c9c2d070702d270131c08
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672595
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
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>
Also, make sure that NewBlobResourceContents creates a Blob.
Change-Id: I2f0fe2ac6410d6b155deb2c8643a40bc73e25cd4
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672418
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
To be compatible with Go 1.23, we cannot use the
encoding/json "omitzero" option. Replace with a
custom MarshalJSON method.
Change-Id: Ied615ea04fb20e2459f9ed20ef03c81edbc74961
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672417
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Now that the protocol package is merged into the mcp package, clean up
the higher level 'Content' union types, in favor of types constructors.
Change-Id: I37bedb0ff0a296eef799ba65c37ca7f94ee1dbbe
Reviewed-on: https://go-review.googlesource.com/c/tools/+/672415
Reviewed-by: Jonathan Amsterdam <jba@google.com>
TryBot-Bypass: Jonathan Amsterdam <jba@google.com>
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>
Design for pagination.
Change-Id: I8257a499b1e4691382b5681b84a52030344ab0e3
Reviewed-on: https://go-review.googlesource.com/c/tools/+/671135
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
When we check the root schema during resolution, first make sure
its descendants form a tree.
Change-Id: Icc430e7df463aa84b961c28616be567f98960430
Reviewed-on: https://go-review.googlesource.com/c/tools/+/670776
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Support remote references.
Most of the machinery was in place; we just had to define the
right loader, copy files from the test repo, and download
the meta-schema files from json-schema.org.
Change-Id: Ib588200ef0fa483641b9b53f9904f53b39dc4b82
Reviewed-on: https://go-review.googlesource.com/c/tools/+/670795
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
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>
Mention that all methods from the spec have the same signature,
and then don't repeat those method declarations.
Modify all method calls in the doc to take a Params struct, even if
the current MCP spec says it is empty.
Change `string` to `[]byte` in some of the listed struct fields.
The current code generator incorrectly generates these as strings.
(I have a forthcoming CL to fix that.)
Also, elaborate the logging design.
Change-Id: I5f323d4d98a4b6045d3cdef770d13b4bfdcb1044
Reviewed-on: https://go-review.googlesource.com/c/tools/+/671358
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Bypass: Jonathan Amsterdam <jba@google.com>
Handle resource subscriptions by delegating to the user.
We don't need to use the word "Resource" in the handlers because
the Subscribe and Unsubscribe methods in the spec don't use that
name. If the spec adds another kind of subscription, they will pick
a new name.
The need for two handlers is dictated by backward compatibility.
We must pass the RPC params to the subscription handler, which means
we need different signatures for subscribe and unsubscribe.
Change-Id: I045abaf52dc9c3e96181331728d50cf36cc8ed91
Reviewed-on: https://go-review.googlesource.com/c/tools/+/671895
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Bypass: Jonathan Amsterdam <jba@google.com>
- Change the names of some content-related types to better match
the spec. Most notably, rename Resource to EmbeddedResource,
because the former has a different meaning in the spec.
- Use []byte intead of string where the spec says "base64-encoded data."
- Unexport EmbeddedResource.ToWire.
Change-Id: I9f65efaadadda1b3abc0e58c64a743af1a72852c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/671362
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Bypass: Jonathan Amsterdam <jba@google.com>
Commit-Queue: Jonathan Amsterdam <jba@google.com>
You can now write "*" for a name in a config to use the original
name.
Also, fix a bug in dealing with initialisms.
Change-Id: I4d5d0acb1200fff6500644457ec34c5026d63f9f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/671361
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
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>
What the spec calls "lists" of features (tools, prompts and so on)
are actually sets. Define a common data structure we can use to
implement all of them, and use it for server tools and prompts.
Change-Id: I257d0776b87a746ff23cd49ebcc7b317f4ea65e1
Reviewed-on: https://go-review.googlesource.com/c/tools/+/671359
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Minor changes to the roots part of the design.
Change-Id: I8125aecc5da297594f74d8d7dc5ef3d94dfa8519
Reviewed-on: https://go-review.googlesource.com/c/tools/+/671356
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Bypass: Jonathan Amsterdam <jba@google.com>
Fix typos and formatting, reword slightly.
Also, change names in the middleware section.
Change-Id: Ie86e5f633a07675ab188a8aaf70e51a48b0878bb
Reviewed-on: https://go-review.googlesource.com/c/tools/+/671555
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Bypass: Jonathan Amsterdam <jba@google.com>
Put discussion of mcp-go up front, and address differences in the
individual sections. I think this leads to easier reading for the user
who is concerned about our divergence in design.
Change-Id: Ifd21f6b9eb570ad4a325b8a8800b7868dac12205
Reviewed-on: https://go-review.googlesource.com/c/tools/+/671556
TryBot-Bypass: Robert Findley <rfindley@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Commit-Queue: Robert Findley <rfindley@google.com>
Per discussion, remove the separate protocol package in favor of a
single mcp package. Update the tools section accordingly, and add more
discussion about the decision of the NewTool API.
Change-Id: Ifb259555ca9d493ce63bc4f71e5f2fa295bdf09c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/671496
TryBot-Bypass: Robert Findley <rfindley@google.com>
Commit-Queue: Robert Findley <rfindley@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
After much deliberation, revert back to the symmetrical many-to-one form
of the client APIs. Every time I tried to write the asymmetrical form, I
couldn't justify it. Furthermore, I think the names 'ClientSession' and
'ServerSession' significantly clarify the meaning.
Change-Id: I5c5e1eaf0d5de5ac7c98dab7aad9c0f31c3ff4e1
Reviewed-on: https://go-review.googlesource.com/c/tools/+/671177
Auto-Submit: Robert Findley <rfindley@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>