feat!: add server discovery and negotiation (SEP-2575) (#973)
* feat!: add server discovery and negotiation * feat!: make protocol unions extensible * ci: add discovery conformance coverage
This commit is contained in:
parent
b93220d4a7
commit
3549e86d28
1 changed files with 1325 additions and 98 deletions
112
.github/workflows/conformance.yml
vendored
112
.github/workflows/conformance.yml
vendored
|
|
@ -37,7 +37,7 @@ jobs:
|
|||
- name: Test conformance server
|
||||
run: cargo test -p mcp-conformance --bin conformance-server
|
||||
|
||||
- name: Start conformance server
|
||||
- name: Start 2025-11-25 server
|
||||
run: |
|
||||
PORT=8001 ./target/debug/conformance-server &
|
||||
echo $! > server.pid
|
||||
|
|
@ -50,7 +50,7 @@ jobs:
|
|||
echo "conformance server did not become ready" >&2
|
||||
exit 1
|
||||
|
||||
- name: Run server conformance suite
|
||||
- name: Run 2025-11-25 server suite
|
||||
run: |
|
||||
npx -y "@modelcontextprotocol/conformance@${CONFORMANCE_VERSION}" server \
|
||||
--url http://127.0.0.1:8001/mcp \
|
||||
|
|
@ -59,7 +59,7 @@ jobs:
|
|||
|
||||
# These pass today but are excluded from the default "active" suite;
|
||||
# run them explicitly so regressions are still caught.
|
||||
- name: Run pending scenarios
|
||||
- name: Run 2025-11-25 pending scenarios
|
||||
run: |
|
||||
for scenario in json-schema-2020-12 server-sse-polling; do
|
||||
npx -y "@modelcontextprotocol/conformance@${CONFORMANCE_VERSION}" server \
|
||||
|
|
@ -68,7 +68,7 @@ jobs:
|
|||
-o conformance-results
|
||||
done
|
||||
|
||||
- name: Start draft conformance server
|
||||
- name: Start draft server
|
||||
run: |
|
||||
STATELESS=1 PORT=8002 ./target/debug/conformance-server &
|
||||
echo $! > draft-server.pid
|
||||
|
|
@ -81,27 +81,85 @@ jobs:
|
|||
echo "draft conformance server did not become ready" >&2
|
||||
exit 1
|
||||
|
||||
- name: Run draft SEP scenarios
|
||||
# Run discovery separately until #985 enables the full draft suite.
|
||||
- name: Run SEP-2575 discovery contract
|
||||
run: |
|
||||
endpoint=http://127.0.0.1:8002/mcp
|
||||
common_headers=(
|
||||
-H "Content-Type: application/json"
|
||||
-H "Accept: application/json, text/event-stream"
|
||||
-H "Mcp-Method: server/discover"
|
||||
)
|
||||
|
||||
discover_response="$(
|
||||
curl --fail-with-body --silent --show-error \
|
||||
"${common_headers[@]}" \
|
||||
-H "MCP-Protocol-Version: 2026-07-28" \
|
||||
--data '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "discover",
|
||||
"method": "server/discover",
|
||||
"params": {
|
||||
"_meta": {
|
||||
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
|
||||
"io.modelcontextprotocol/clientInfo": {
|
||||
"name": "conformance-workflow",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"io.modelcontextprotocol/clientCapabilities": {}
|
||||
}
|
||||
}
|
||||
}' \
|
||||
"$endpoint"
|
||||
)"
|
||||
jq -e '
|
||||
.result.resultType == "complete" and
|
||||
(.result.supportedVersions | index("2026-07-28") != null) and
|
||||
(.result.capabilities | type == "object") and
|
||||
(.result.serverInfo.name | type == "string") and
|
||||
.result.ttlMs == 0 and
|
||||
.result.cacheScope == "private"
|
||||
' <<<"$discover_response"
|
||||
|
||||
status="$(
|
||||
curl --silent --show-error \
|
||||
--output /tmp/unsupported-version.json \
|
||||
--write-out "%{http_code}" \
|
||||
"${common_headers[@]}" \
|
||||
-H "MCP-Protocol-Version: 2099-01-01" \
|
||||
--data '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "unsupported",
|
||||
"method": "server/discover",
|
||||
"params": {
|
||||
"_meta": {
|
||||
"io.modelcontextprotocol/protocolVersion": "2099-01-01",
|
||||
"io.modelcontextprotocol/clientInfo": {
|
||||
"name": "conformance-workflow",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"io.modelcontextprotocol/clientCapabilities": {}
|
||||
}
|
||||
}
|
||||
}' \
|
||||
"$endpoint"
|
||||
)"
|
||||
test "$status" = "400"
|
||||
jq -e '
|
||||
.id == "unsupported" and
|
||||
.error.code == -32022 and
|
||||
.error.data.requested == "2099-01-01" and
|
||||
(.error.data.supported | index("2026-07-28") != null)
|
||||
' /tmp/unsupported-version.json
|
||||
|
||||
# Keep this explicit list until the full draft suite is enabled by #985.
|
||||
- name: Run supported draft server scenarios
|
||||
run: |
|
||||
for scenario in \
|
||||
sep-2164-resource-not-found \
|
||||
caching \
|
||||
http-header-validation \
|
||||
http-custom-header-server-validation \
|
||||
; do
|
||||
npx -y "@modelcontextprotocol/conformance@${DRAFT_CONFORMANCE_VERSION}" server \
|
||||
--url http://127.0.0.1:8002/mcp \
|
||||
--scenario "$scenario" \
|
||||
--spec-version draft \
|
||||
-o conformance-results
|
||||
done
|
||||
|
||||
# SEP-2322 MRTR scenarios (spec 2026-07-28). They speak the stateless
|
||||
# lifecycle (bare JSON-RPC POSTs, no initialize handshake), so they run
|
||||
# against the stateless draft server.
|
||||
- name: Run SEP-2322 MRTR scenarios
|
||||
run: |
|
||||
for scenario in \
|
||||
input-required-result-basic-elicitation \
|
||||
input-required-result-basic-sampling \
|
||||
input-required-result-basic-list-roots \
|
||||
|
|
@ -120,17 +178,15 @@ jobs:
|
|||
npx -y "@modelcontextprotocol/conformance@${DRAFT_CONFORMANCE_VERSION}" server \
|
||||
--url http://127.0.0.1:8002/mcp \
|
||||
--scenario "$scenario" \
|
||||
--spec-version draft \
|
||||
-o conformance-results
|
||||
done
|
||||
|
||||
- name: Stop draft conformance server
|
||||
- name: Stop conformance servers
|
||||
if: always()
|
||||
run: kill "$(cat draft-server.pid)" 2>/dev/null || true
|
||||
|
||||
|
||||
- name: Stop conformance server
|
||||
if: always()
|
||||
run: kill "$(cat server.pid)" 2>/dev/null || true
|
||||
run: |
|
||||
kill "$(cat draft-server.pid)" 2>/dev/null || true
|
||||
kill "$(cat server.pid)" 2>/dev/null || true
|
||||
|
||||
- name: Upload results
|
||||
if: always()
|
||||
|
|
@ -154,7 +210,7 @@ jobs:
|
|||
- name: Build conformance binaries
|
||||
run: cargo build -p mcp-conformance
|
||||
|
||||
- name: Run full client conformance suite
|
||||
- name: Run 2025-11-25 client suite
|
||||
run: |
|
||||
npx -y "@modelcontextprotocol/conformance@${CONFORMANCE_VERSION}" client \
|
||||
--command "$(pwd)/target/debug/conformance-client" \
|
||||
|
|
@ -163,7 +219,7 @@ jobs:
|
|||
-o conformance-client-results/full
|
||||
|
||||
# SEP-2322 MRTR client scenario (spec 2026-07-28).
|
||||
- name: Run SEP-2322 MRTR client scenario
|
||||
- name: Run draft SEP-2322 client scenario
|
||||
run: |
|
||||
npx -y "@modelcontextprotocol/conformance@${DRAFT_CONFORMANCE_VERSION}" client \
|
||||
--command "$(pwd)/target/debug/conformance-client" \
|
||||
|
|
|
|||
Loading…
Reference in a new issue