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>
This commit is contained in:
Rob Findley 2025-05-28 04:02:00 +00:00 • committed by Gopher Robot
commit e2bbd8002d
2 changed files with 535 additions and 51 deletions

View file

@ -0,0 +1,74 @@
Check behavior of a server with just prompts.
Fixed bugs:
- empty tools lists should not be returned as 'null'
-- prompts --
code_review
-- client --
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "ExampleClient", "version": "1.0.0" }
}
}
{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }
{ "jsonrpc": "2.0", "id": 4, "method": "prompts/list" }
-- server --
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"_meta": {},
"capabilities": {
"completions": {},
"logging": {},
"prompts": {
"listChanged": true
},
"resources": {
"listChanged": true
},
"tools": {
"listChanged": true
}
},
"protocolVersion": "2024-11-05",
"serverInfo": {
"name": "testServer",
"version": "v1.0.0"
}
}
}
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"_meta": {},
"tools": []
}
}
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"_meta": {},
"prompts": [
{
"arguments": [
{
"name": "Code",
"required": true
}
],
"description": "do a code review",
"name": "code_review"
}
]
}
}

View file

@ -0,0 +1,93 @@
Check behavior of a server with just tools.
Fixed bugs:
- "tools/list" can have missing params
- "_meta" should not be nil
- empty resource or prompts should not be returned as 'null'
-- tools --
greet
-- client --
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "ExampleClient", "version": "1.0.0" }
}
}
{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }
{ "jsonrpc": "2.0", "id": 3, "method": "resources/list" }
{ "jsonrpc": "2.0", "id": 4, "method": "prompts/list" }
-- server --
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"_meta": {},
"capabilities": {
"completions": {},
"logging": {},
"prompts": {
"listChanged": true
},
"resources": {
"listChanged": true
},
"tools": {
"listChanged": true
}
},
"protocolVersion": "2024-11-05",
"serverInfo": {
"name": "testServer",
"version": "v1.0.0"
}
}
}
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"_meta": {},
"tools": [
{
"description": "say hi",
"inputSchema": {
"type": "object",
"required": [
"Name"
],
"properties": {
"Name": {
"type": "string"
}
},
"additionalProperties": {
"not": {}
}
},
"name": "greet"
}
]
}
}
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"_meta": {},
"resources": []
}
}
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"_meta": {},
"prompts": []
}
}