Skip to content

Commit 8bb14c1

Browse files
committed
merge: resolve conflicts with upstream main
Sync the progress_callback feature branch onto current upstream/main, which had undergone a large refactor since the branch was last updated (dispatcher extraction, ProgressFnT moved from mcp.shared.session to mcp.shared.dispatcher, removal of the experimental tasks modules, and a test reorganization). Conflict resolution: - src/mcp/server/session.py: take upstream's import block (ProgressFnT now comes from mcp.shared.dispatcher). The progress_callback pass-throughs on create_message/elicit/elicit_form/elicit_url auto-merged onto upstream's refactored send_request, which already accepts progress_callback. - src/mcp/server/mcpserver/context.py: keep both upstream's LoggingLevel import and the ProgressFnT import (relocated to mcp.shared.dispatcher). - tests/shared/test_progress_notifications.py: upstream deleted this pre-existing file in its test reorg. Re-add it containing only this PR's two feature tests (create_message and elicit_form progress_callback pass-through), adapted to the new client callback API (mcp.client.ClientRequestContext). Verified locally: ruff format/lint clean, pyright clean, full suite green (2388 passed serially), coverage 100%.
2 parents 9c70654 + 1cec2d6 commit 8bb14c1

315 files changed

Lines changed: 52297 additions & 21375 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
File renamed without changes.

.github/actions/conformance/client.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
Contract:
77
- MCP_CONFORMANCE_SCENARIO env var -> scenario name
88
- MCP_CONFORMANCE_CONTEXT env var -> optional JSON (for client-credentials scenarios)
9+
- MCP_CONFORMANCE_PROTOCOL_VERSION env var -> spec version the harness mock
10+
server is speaking (e.g. "2025-11-25", "2026-07-28"). Always set; defaults
11+
to the harness's LATEST_SPEC_VERSION when --spec-version is omitted.
912
- Server URL as last CLI argument (sys.argv[1])
1013
- Must exit 0 within 30 seconds
1114
@@ -50,6 +53,13 @@
5053
)
5154
logger = logging.getLogger(__name__)
5255

56+
#: Spec version the harness is running this scenario at (e.g. "2025-11-25",
57+
#: "2026-07-28"). The harness always sets this (it falls back to its own
58+
#: LATEST_SPEC_VERSION when --spec-version is omitted), so None means we were
59+
#: invoked outside the harness. Handlers that need to take the stateless 2026
60+
#: path will branch on this once the SDK has one; today it is logged only.
61+
PROTOCOL_VERSION: str | None = os.environ.get("MCP_CONFORMANCE_PROTOCOL_VERSION")
62+
5363
# Type for async scenario handler functions
5464
ScenarioHandler = Callable[[str], Coroutine[Any, None, None]]
5565

@@ -347,6 +357,7 @@ def main() -> None:
347357

348358
server_url = sys.argv[1]
349359
scenario = os.environ.get("MCP_CONFORMANCE_SCENARIO")
360+
logger.debug(f"Conformance protocol version: {PROTOCOL_VERSION!r}")
350361

351362
if scenario:
352363
logger.debug(f"Running explicit scenario '{scenario}' against {server_url}")
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# Expected failures for the carried-forward 2026-07-28 legs
2+
# (`--suite all --spec-version 2026-07-28` for both server and client).
3+
#
4+
# This baseline is separate from expected-failures.yml because entries are
5+
# keyed by scenario name only: a scenario that passes at its default version
6+
# in the 2025 legs but fails when forced to 2026-07-28 (or vice versa) cannot
7+
# be expressed in a shared file (the passing leg would flag the entry as
8+
# stale). Like expected-failures.yml, this single file covers both
9+
# directions: the client 2026 leg reads the `client:` section and the server
10+
# 2026 leg reads the `server:` section. Both burn down independently of the
11+
# 2025 legs.
12+
#
13+
# Baseline established against @modelcontextprotocol/conformance pinned in
14+
# .github/workflows/conformance.yml (CONFORMANCE_VERSION = 0.2.0-alpha.4).
15+
# New conformance releases are adopted by deliberately bumping that pin and
16+
# reconciling both this file and expected-failures.yml in the same change.
17+
#
18+
# Entries are grouped by what unblocks them. As each gap closes the
19+
# corresponding scenarios start passing and MUST be removed from this list
20+
# (the runner fails on stale entries), so the baseline burns down per
21+
# milestone.
22+
23+
client:
24+
# --- No stateless client path on main yet ---
25+
# client.py drives the 2025 stateful lifecycle (initialize handshake +
26+
# session). The 2026-mode mock server is stateless, so the call sequence
27+
# never reaches the assertion. Unblocks when client.py's is_modern_protocol()
28+
# branch takes the per-request _meta path.
29+
- tools_call
30+
31+
# --- SEP-837 (application_type during DCR) ---
32+
# The sep-837-application-type-present check only fires on 2026-version
33+
# runs; the client omits application_type during Dynamic Client
34+
# Registration, so every auth scenario that reaches DCR fails it on this
35+
# leg (the same scenarios pass at their default version in the 2025 legs).
36+
- auth/metadata-default
37+
- auth/metadata-var1
38+
- auth/metadata-var2
39+
- auth/metadata-var3
40+
- auth/scope-from-www-authenticate
41+
- auth/scope-from-scopes-supported
42+
- auth/scope-omitted-when-undefined
43+
- auth/token-endpoint-auth-basic
44+
- auth/token-endpoint-auth-post
45+
- auth/token-endpoint-auth-none
46+
- auth/offline-access-not-supported
47+
48+
# --- Auth scenarios cut short by the 2026 connection lifecycle ---
49+
# The auth fixture flow drives the 2025 stateful lifecycle; the 2026-mode
50+
# mock rejects the MCP POST before the scope-escalation behaviour these
51+
# scenarios measure, so no authorization requests are observed. Unblocks
52+
# when client.py's auth flow speaks the 2026 per-request lifecycle.
53+
- auth/scope-step-up
54+
- auth/scope-retry-limit
55+
56+
# --- Same gaps as the 2025 baseline (fail identically when forced to 2026-07-28) ---
57+
# SEP-2575 (request metadata / _meta envelope): client does not populate the
58+
# _meta envelope or the MCP-Protocol-Version header semantics yet.
59+
- request-metadata
60+
# SEP-2322 (multi-round-trip requests): client does not echo requestState /
61+
# handle IncompleteResult yet.
62+
- sep-2322-client-request-state
63+
# SEP-2243 (HTTP standardization): no fixture handler / client header support yet.
64+
- http-custom-headers
65+
- http-invalid-tool-headers
66+
# SEP-2106 (JSON Schema $ref handling): client still dereferences network $refs.
67+
- json-schema-ref-no-deref
68+
# SEP-2468 (authorization response iss parameter): not implemented in the client.
69+
- auth/iss-supported
70+
- auth/iss-not-advertised
71+
- auth/iss-supported-missing
72+
- auth/iss-wrong-issuer
73+
- auth/iss-unexpected
74+
- auth/iss-normalized
75+
- auth/metadata-issuer-mismatch
76+
# SEP-2352 (authorization server migration): client does not re-register when
77+
# PRM authorization_servers changes.
78+
- auth/authorization-server-migration
79+
# auth/enterprise-managed-authorization (SEP-990) is in the 2025 baseline but
80+
# NOT here: the harness skips it as inapplicable at --spec-version 2026-07-28
81+
# (it is an extension scenario not carried into the 2026 wire), so it is
82+
# neither run nor evaluated on this leg.
83+
84+
server:
85+
# --- No stateless server path on main yet (carried-forward 2025-era scenarios) ---
86+
# mcp-everything-server only runs in 2025 stateful mode. With
87+
# --spec-version 2026-07-28 the harness sends stateless requests
88+
# (MCP-Protocol-Version: 2026-07-28, _meta envelope, no initialize), which
89+
# the server rejects before the handler runs. These scenarios all pass on
90+
# the 2025 legs; they unblock once mcp-everything-server routes 2026
91+
# requests through a stateless path.
92+
- completion-complete
93+
- tools-list
94+
- tools-call-simple-text
95+
- tools-call-image
96+
- tools-call-audio
97+
- tools-call-embedded-resource
98+
- tools-call-mixed-content
99+
- tools-call-error
100+
- tools-call-with-progress
101+
- server-sse-multiple-streams
102+
- resources-list
103+
- resources-read-text
104+
- resources-read-binary
105+
- resources-templates-read
106+
- prompts-list
107+
- prompts-get-simple
108+
- prompts-get-with-args
109+
- prompts-get-embedded-resource
110+
- prompts-get-with-image
111+
- dns-rebinding-protection
112+
# SEP-2106 (JSON Schema 2020-12 in tool inputSchema): the fixture tool's
113+
# schema has none of the 2020-12 keywords the scenario checks. The scenario
114+
# is in `--suite all` but not `--suite active`, so this is the only leg that
115+
# runs it; it fails identically at 2025-11-25 (not a 2026-path regression).
116+
- json-schema-2020-12
117+
118+
# --- Draft scenarios (same failures and reasons as the `--suite draft` leg) ---
119+
# SEP-2575 (stateless HTTP / _meta envelope): server has no stateless mode,
120+
# _meta-derived capabilities, error-code mappings, or server/discover yet.
121+
- server-stateless
122+
# SEP-2322 (multi-round-trip requests / IncompleteResult): not implemented.
123+
- input-required-result-basic-elicitation
124+
- input-required-result-basic-sampling
125+
- input-required-result-basic-list-roots
126+
- input-required-result-request-state
127+
- input-required-result-multiple-input-requests
128+
- input-required-result-multi-round
129+
- input-required-result-non-tool-request
130+
- input-required-result-result-type
131+
- input-required-result-tampered-state
132+
- input-required-result-capability-check
133+
# SEP-2549 (caching): no ttlMs/cacheScope support.
134+
- caching
135+
# SEP-2243 (HTTP header standardization): -32020 HeaderMismatch handling and
136+
# case-insensitive/whitespace-trimmed header validation not implemented.
137+
- http-header-validation
138+
- http-custom-header-server-validation
139+
140+
# --- WARNING-only entries ---
141+
# These scenarios emit no FAILURE checks, only SHOULD-level WARNINGs, but
142+
# the expected-failures evaluator counts WARNINGs as failures. Same entries
143+
# as the draft suite in expected-failures.yml.
144+
# SEP-2164: server returns -32600 (not -32602) and omits error.data.uri.
145+
- sep-2164-resource-not-found
146+
# SEP-2322 SHOULD-level behaviours (re-request missing inputResponses,
147+
# ignore unrecognized inputResponses keys).
148+
- input-required-result-missing-input-response
149+
- input-required-result-ignore-extra-params
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Conformance scenarios not yet passing against the Python SDK on main.
2+
# CI exits 0 if only these fail, exits 1 on unexpected failures or stale entries.
3+
#
4+
# Baseline established against @modelcontextprotocol/conformance pinned in
5+
# .github/workflows/conformance.yml (CONFORMANCE_VERSION = 0.2.0-alpha.4).
6+
# New conformance releases are adopted by deliberately bumping that pin and
7+
# reconciling both this file and expected-failures.2026-07-28.yml in the same
8+
# change.
9+
#
10+
# Entries are grouped by SEP. As each SEP lands in the SDK the corresponding
11+
# scenarios start passing and MUST be removed from this list (the runner fails
12+
# on stale entries), so the baseline burns down per milestone.
13+
14+
client:
15+
# --- Draft-spec scenarios (in `--suite draft`, also part of `--suite all`) ---
16+
# SEP-2575 (request metadata / _meta envelope): client does not populate the
17+
# _meta envelope or the MCP-Protocol-Version header semantics yet.
18+
- request-metadata
19+
# SEP-2322 (multi-round-trip requests): client does not echo requestState /
20+
# handle IncompleteResult yet.
21+
- sep-2322-client-request-state
22+
# SEP-2243 (HTTP standardization): no fixture handler / client header support yet.
23+
- http-custom-headers
24+
- http-invalid-tool-headers
25+
# SEP-2106 (JSON Schema $ref handling): client still dereferences network $refs.
26+
- json-schema-ref-no-deref
27+
# SEP-2468 (authorization response iss parameter): not implemented in the client.
28+
- auth/iss-supported
29+
- auth/iss-not-advertised
30+
- auth/iss-supported-missing
31+
- auth/iss-wrong-issuer
32+
- auth/iss-unexpected
33+
- auth/iss-normalized
34+
- auth/metadata-issuer-mismatch
35+
# SEP-2352 (authorization server migration): client does not re-register when
36+
# PRM authorization_servers changes.
37+
- auth/authorization-server-migration
38+
# SEP-837 (application_type during DCR): the check only fires on draft-version
39+
# runs; this draft scenario is the one place the client still hits it.
40+
- auth/offline-access-not-supported
41+
42+
# --- Pre-existing scenarios that fail on checks added after conformance 0.1.15 ---
43+
# SEP-2350 (scope step-up): WARNING-only; the expected-failures evaluator
44+
# counts WARNINGs as failures.
45+
- auth/scope-step-up
46+
# SEP-990 (enterprise-managed authorization extension): no fixture handler /
47+
# client support for the token-exchange + JWT bearer flow.
48+
- auth/enterprise-managed-authorization
49+
50+
server:
51+
# --- Draft-spec scenarios (in `--suite draft`; the `active` suite is green) ---
52+
# SEP-2575 (stateless HTTP / _meta envelope): server has no stateless mode,
53+
# _meta-derived capabilities, error-code mappings, or server/discover yet.
54+
- server-stateless
55+
# SEP-2322 (multi-round-trip requests / IncompleteResult): not implemented;
56+
# most scenarios currently fail early with "Missing session ID" because
57+
# mcp-everything-server only runs in stateful mode.
58+
- input-required-result-basic-elicitation
59+
- input-required-result-basic-sampling
60+
- input-required-result-basic-list-roots
61+
- input-required-result-request-state
62+
- input-required-result-multiple-input-requests
63+
- input-required-result-multi-round
64+
- input-required-result-non-tool-request
65+
- input-required-result-result-type
66+
- input-required-result-tampered-state
67+
- input-required-result-capability-check
68+
# SEP-2549 (caching): no ttlMs/cacheScope support; scenario also hits the
69+
# stateful-mode "Missing session ID" error.
70+
- caching
71+
# SEP-2243 (HTTP header standardization): -32020 HeaderMismatch handling and
72+
# case-insensitive/whitespace-trimmed header validation not implemented.
73+
- http-header-validation
74+
- http-custom-header-server-validation
75+
# WARNING-only entries: these scenarios emit no FAILURE checks, only SHOULD-level
76+
# WARNINGs, but the expected-failures evaluator counts WARNINGs as failures.
77+
# SEP-2164: server returns -32600 (not -32602) and omits error.data.uri.
78+
- sep-2164-resource-not-found
79+
# SEP-2322 SHOULD-level behaviours (re-request missing inputResponses, ignore
80+
# unrecognized inputResponses keys).
81+
- input-required-result-missing-input-response
82+
- input-required-result-ignore-extra-params
83+
# Intentionally NOT baselined (2 of 19 draft scenarios): the SEP-2322
84+
# negative-case scenarios input-required-result-unsupported-methods and
85+
# input-required-result-validate-input pass today only because the stateful
86+
# server's -32600 "Missing session ID" satisfies their assertions. They will
87+
# start failing for real once stateless mode lands; add them then.

.github/actions/conformance/run-server.sh

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,36 @@ SERVER_URL="http://localhost:${PORT}/mcp"
77
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
88
cd "$SCRIPT_DIR/../../.."
99

10-
# Start everything-server
10+
# Refuse to start if something is already listening on the port. The readiness
11+
# check below cannot tell our server apart from a stale one, so a leftover
12+
# listener would mean silently running conformance against old code.
13+
if (: > "/dev/tcp/localhost/${PORT}") 2>/dev/null; then
14+
echo "Error: port ${PORT} is already in use." >&2
15+
echo "Stop the stale process first (lsof -ti:${PORT} -sTCP:LISTEN | xargs kill) or set PORT to a free port." >&2
16+
exit 1
17+
fi
18+
19+
echo "Starting mcp-everything-server on port ${PORT}..."
1120
uv run --frozen mcp-everything-server --port "$PORT" &
1221
SERVER_PID=$!
13-
trap "kill $SERVER_PID 2>/dev/null || true; wait $SERVER_PID 2>/dev/null || true" EXIT
1422

15-
# Wait for server to be ready
23+
cleanup() {
24+
echo "Stopping server (PID: ${SERVER_PID})..."
25+
kill $SERVER_PID 2>/dev/null || true
26+
wait $SERVER_PID 2>/dev/null || true
27+
}
28+
trap cleanup EXIT
29+
30+
# Wait for server to be ready. --max-time keeps a hung listener from wedging
31+
# the loop, and a dead server process fails fast instead of retrying.
32+
echo "Waiting for server to be ready..."
1633
MAX_RETRIES=30
1734
RETRY_COUNT=0
18-
while ! curl -s "$SERVER_URL" > /dev/null 2>&1; do
35+
while ! curl -s --max-time 2 "$SERVER_URL" > /dev/null 2>&1; do
36+
if ! kill -0 $SERVER_PID 2>/dev/null; then
37+
echo "Server process exited unexpectedly" >&2
38+
exit 1
39+
fi
1940
RETRY_COUNT=$((RETRY_COUNT + 1))
2041
if [ $RETRY_COUNT -ge $MAX_RETRIES ]; then
2142
echo "Server failed to start after ${MAX_RETRIES} retries" >&2
@@ -26,5 +47,5 @@ done
2647

2748
echo "Server ready at $SERVER_URL"
2849

29-
# Run conformance tests
30-
npx @modelcontextprotocol/conformance@0.1.10 server --url "$SERVER_URL" "$@"
50+
npx --yes @modelcontextprotocol/conformance@"${CONFORMANCE_VERSION:?set CONFORMANCE_VERSION (pinned in .github/workflows/conformance.yml)}" \
51+
server --url "$SERVER_URL" "$@"

.github/workflows/claude-code-review.yml

Lines changed: 0 additions & 33 deletions
This file was deleted.

.github/workflows/claude.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ on:
1414
jobs:
1515
claude:
1616
if: |
17-
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && !startsWith(github.event.comment.body, '@claude review')) ||
1818
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
1919
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
2020
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
@@ -27,15 +27,16 @@ jobs:
2727
actions: read # Required for Claude to read CI results on PRs
2828
steps:
2929
- name: Checkout repository
30-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
30+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
3131
with:
3232
fetch-depth: 1
33+
persist-credentials: false
3334

3435
- name: Run Claude Code
3536
id: claude
36-
uses: anthropics/claude-code-action@2f8ba26a219c06cfb0f468eef8d97055fa814f97 # v1.0.53
37+
uses: anthropics/claude-code-action@d5726de019ec4498aa667642bc3a80fca83aa102 # v1.0.148
3738
with:
38-
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
39+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} # zizmor: ignore[secrets-outside-env]
3940
use_commit_signing: true
4041
additional_permissions: |
4142
actions: read

0 commit comments

Comments
 (0)