Commit graph conformance/examples
Author SHA1 Message Date
Paul Carleton
f12baed382
feat(sep-2468): cover the remaining untested traceability rows (#304)
Add two client scenarios for the SEP-2468 requirements that had no
conformance coverage:

- auth/metadata-issuer-mismatch: the AS metadata document declares an
  issuer that differs from the issuer identifier used to construct the
  well-known URL; the client must not use the metadata
  (sep-2468-client-validate-metadata-issuer).
- auth/iss-normalized: the authorization redirect carries an iss value
  that only matches the recorded issuer after URL normalization; the
  client must compare with simple string comparison and reject
  (sep-2468-client-no-normalization).

The two authorization-server-side rows (AS SHOULD include iss, AS MUST
advertise authorization_response_iss_parameter_supported) are excluded:
observing iss in an authorization response requires driving an
Authorization Code Grant against the AS under test, which the
authorization-server suite does not implement yet (#208).
2026-05-23 00:04:55 +01:00
Caitie McCaffrey
43fbf60d3d
Conformance Tests for SEP-2322 MRTR (#188) 2026-05-22 22:26:11 +01:00
Caitie McCaffrey
7f1b8712ab
feat: add conformance Tests for SEP-2549: TTL for List Results (#275) 2026-05-22 20:57:49 +01:00
Yuan Teoh
c57795e2a3
chore: additional server conformance tests for SEP-2575 (#297)
* chore: additional server conformance tests for SEP-2575

* fix(sep-2575): use the spec's notifications filter object in subscriptions/listen

The scenario sent params.subscriptions: [{type: 'tools/list-changed'}], a
shape that does not exist in the SEP. SubscriptionsListenRequestParams
requires params.notifications: {toolsListChanged?, promptsListChanged?, ...}
(see schema.ts SubscriptionFilter and the canonical
SubscriptionsListenRequest example). A compliant server would either reject
the old request as invalid params or treat it as subscribing to nothing,
failing the ack/list-changed checks.

Also makes the everything-server's acknowledgment echo the agreed
notifications filter, as the SubscriptionsAcknowledgedNotification schema
requires.

* fix(sep-2575): match the spec's notifications/*/list_changed method names

The list-changed checks and the everything-server used
notifications/tools/list-changed (hyphen); the spec's method is
notifications/tools/list_changed (underscore) per ToolListChangedNotification
/ PromptListChangedNotification in schema.ts. With the hyphen form the
notification-filter check cannot catch a real leak, and the list-changed
checks fail a server that emits the correct name.

Also drops the f.params.toolsListChanged === true fallback match: that field
is the subscriptions/listen request filter, not a notification parameter, so
it never appears on a compliant server's notification.

* fix(sep-2575): keep collected frames when the listen stream read times out

listenToStream aborts the fetch after timeoutMs. If the abort fired while
blocked in reader.read(), the rejection propagated to the outer catch and the
helper returned [] — discarding every frame already received. A compliant
server holds a subscriptions/listen stream open indefinitely, so the timeout
is the *normal* way these reads end; previously every subscription check
would report a false 'no frames received' FAILURE against such a server.
The current everything-server only avoided this by res.end()ing immediately
after the ack.

* fix(sep-2575): open the listen stream before triggering list mutations

The notification-filter and list-changed checks fired the mutation trigger
*before* opening the subscriptions/listen stream. A compliant server only
delivers list-changed notifications to streams that are open at the time of
the change, so the SHOULD checks would fail any server that does not replay
past changes to new subscribers, and the filter check could never observe a
real leak.

listenToStream now takes an onFirstFrame hook; the three trigger-based
checks open the stream, wait for the acknowledgment, then fire the mutation
on a separate connection and keep reading.

The everything-server now keeps subscriptions/listen streams open, registers
them with their filters, and fans the list_changed notification out to open
streams when a trigger tool runs - instead of unconditionally emitting a
list-changed frame on every stream open (which itself violated the
notification-filter requirement in spirit: it announced a change when
nothing had changed).

* fix(sep-2575): check the subscription id on every listen-stream notification

server-tags-subscription-id only inspected the acknowledgment frame, so a
server that tags the ack but omits io.modelcontextprotocol/subscriptionId
from subsequent notifications passed. The check now triggers a tool-list
change once the stream is acknowledged and asserts every notification frame
on the stream carries the id in params._meta.

Also drops the f.body.method / f.params.method fallbacks when resolving a
frame's method - those shapes don't exist in JSON-RPC and only masked
malformed frames.

* fix(sep-2575): report WARNING, not FAILURE, for the SHOULD-level list-changed checks

The spec text behind server-sends-{tools,prompts}-list-changed-on-subscription
is a SHOULD ('servers that declared the listChanged capability SHOULD send a
notification...'). Severity follows the spec keyword: MUST -> FAILURE,
SHOULD -> WARNING. runCheck now accepts a warning flag and the two
list-changed checks use it on their failure paths.

* fix(sep-2575): skip stream checks when the diagnostic tool is not exposed

http-server-no-independent-requests-on-stream and
server-no-log-without-loglevel reported SUCCESS when the server rejected the
tools/call outright (e.g. test_streaming_elicitation / test_logging_tool do
not exist): a single error frame contains no independent request and no log
notification, so the check passed without exercising anything. The sibling
list-changed checks already SKIP when their trigger tool is missing; these
now do the same.

* chore(sep-2575): exclude the four unobservable server requirements from traceability

Marks the section-C rows of #296 as excluded rather than untested:
no-prior-context, no-connection-reuse-required, disconnect-is-cancel and
stops-on-cancel describe internal server state that a black-box harness
cannot observe on the wire. With these excluded and the part-B checks landed,
every testable server-side SEP-2575 requirement is covered; the remaining
untested rows are all client-side and blocked on a SEP-2575-aware reference
client.

---------

Co-authored-by: Paul Carleton <paulc@anthropic.com>
2026-05-21 19:17:31 +01:00
Den Delimarsky
8c828a7fab
SEP-2350: scope-accumulation check in auth/scope-step-up (#282)
* Add SEP-2350 scope-accumulation check to auth/scope-step-up

SEP-2350 clarifies that on step-up re-authorization, clients SHOULD
compute the union of previously-granted and newly-challenged scopes so
they don't lose permissions for other operations.

- Traceability yaml: 1 client check (two spec sentences merged), 1 server
  check tracked for a future server-side scenario, 1 excluded reword
- ScopeStepUpAuthScenario now challenges with only the missing scope so
  union accumulation is observable on the second authorization request
- New check sep-2350-scope-union-on-reauth (WARNING when the previously
  granted scope is dropped)
- everything-client withOAuthRetry now accumulates prior token scope into
  the re-auth scope (passing example)
- New auth-test-echo-scope negative client + vitest case

* feat: add client conformance tests for SEP-2575 (#270)

* feat: merge latest request-metadata scenario stacked branch

* test: implement optional capability conditional checks and simulated negotiation retry

* fix(sep-2243): collapse check IDs to one-per-requirement (#287)

The sep-2243 scenario check IDs drifted from the requirement-traceability
yaml in #259 — the code emitted one ID per test case while the yaml
declares one per normative requirement, so the IDs no longer matched.

Rename the emitted IDs so a check ID maps to a single MUST/SHOULD and is
emitted once per case (the per-case detail moves to name/description),
matching the repo's existing 'same id, vary status/message' convention:

- mcp-method-header-* / mcp-name-header-*  -> client-includes-standard-headers
- reject-invalid-tool-* / keep-valid-tool  -> client-reject-invalid-tool
- server-accepts-{lower,upper}case-name    -> header-name-case-insensitive
- server reject status checks (mismatch/missing/case x method/name)
                                            -> server-reject-invalid-headers
- their error-code variants                 -> server-reject-error-code

Merge the yaml's server-reject-mismatch + server-reject-status into one
server-reject-invalid-headers MUST (HTTP 400 on a header-validation
failure); keep server-reject-error-code as the SHOULD. Base64/custom-header
rejection checks keep their own param-validation IDs (out of scope here).

Gates and the whitespace-acceptance check keep their scenario-matching
names. No behavior change — only check IDs, descriptions, and the yaml.

* feat: `sdk` subcommand to run local conformance against any SDK ref (#277)

* feat: add sdk subcommand to run conformance against any SDK ref (#250)

* Revise sdk runner: explicit --mode, KNOWN_SDKS-only config, v1/v2 entries

Addresses review feedback on the sdk subcommand:

- Require --mode (client|server) and remove "both". Each invocation now
  tests exactly one side with its own exit code; the old default ran
  client then server but combined exit codes with ||=, which skipped the
  server side entirely whenever the client run failed.
- Resolve build/run config from KNOWN_SDKS + CLI flags only; drop the
  conformance.config.yaml loader (no SDK ships one yet). The Zod schema
  stays as the type for the built-in entries.
- Split the typescript entry by major version: typescript-sdk (v2/main,
  pnpm install + build:all, expected-failures.yaml) and typescript-sdk-v1
  (v1.x, npm ci + build, conformance-baseline.yml). An entry may set
  `repo` (real clone target for an alias) and `defaultRef` (branch used
  when no @ref is given). parseSdkSpec now leaves ref undefined when
  omitted so defaultRef can apply; a trailing @ is treated as no ref.
- Key the clone cache by ref (<repo>/<ref>) so different refs of the same
  repo no longer share one checkout.
- Bound the server readiness probe with a per-request AbortSignal timeout
  so a server that accepts the socket but never responds can't hang past
  the overall deadline.

* fix(sdk-runner): resolve -o to absolute path; add --expected-failures override; replaceAll for safeName

* feat: add SEP conformance traceability manifest (#288)

squashed; see PR #288 body

* feat: add server conformance tests for SEP-2575 (#271)

* feat: add server conformance tests for SEP-2575

* refactor and add new checks

* Fix stateless scenario source field and report SKIPPED for inapplicable capability checks

- Add the required `source` field (DRAFT) so the scenario typechecks and is
  selectable via --spec-version. Without it the class did not satisfy the
  ClientScenario interface and s.source was dereferenced by the spec-version
  filter at list time.
- Teach runCheck about a SKIPPED status and use it for the two client-capability
  checks when the server does not return -32003, instead of reporting a green
  PASS for a requirement that was never exercised.

* Remove unimplemented placeholder checks from stateless server scenario

The subscriptions/listen, statelessness-invariant, list-changed and
disconnect-is-cancel checks emitted SUCCESS without probing the server,
which inflated coverage in the traceability report. Drop them until they
have real assertions; the corresponding rows remain declared in
src/seps/sep-2575.yaml so traceability shows them as not-yet-covered.

Also fix the checkErrorId helper to push under the
sep-2575-http-server-error-jsonrpc-id slug so its failure path actually
short-circuits the aggregate SUCCESS check at the end of the scenario.

---------

Co-authored-by: Paul Carleton <paulc@anthropic.com>

* SEP-2352: authorization-server migration scenario (#286)

* Add SEP-2352 authorization-server migration scenario

SEP-2352 requires that client credentials are bound to the issuing
authorization server: when PRM authorization_servers changes to a new
issuer, clients MUST re-register and MUST NOT reuse the previous AS's
client credentials.

- Traceability yaml: 3 checks, 3 excluded (internal state / UI)
- New auth/authorization-server-migration scenario (draft suite): two
  auth servers; PRM flips from AS1 to AS2 after the first authenticated
  request; AS2 asserts it received a fresh /register and never saw AS1's
  client_id at /authorize or /token
- ConformanceOAuthProvider gains invalidateCredentials and bindIssuer so
  the everything-client can key credentials by issuer (passing example)
- everything-client adds an issuer-aware handler for this scenario that
  re-reads PRM on each 401 and rebinds before re-authorizing
- auth-test-reuse-credentials negative client + vitest case

* Drop application_type from DCR metadata (not in SDK OAuthClientMetadata type)

---------

Co-authored-by: Paul Carleton <paulc@anthropic.com>

* ci(traceability): enable corepack so the SDK build can use pnpm (#289)

The refresh run failed with 'pnpm: not found' — the reference SDK's
build command (typescript-sdk: pnpm install && pnpm run build:all) needs
pnpm on PATH. Add 'corepack enable' to the run job.

* ci(traceability): tolerate SDK conformance failures in the run step (#290)

The `sdk` command exits non-zero when the SDK has conformance failures
not in its baseline. The traceability manifest only needs the emitted
check IDs (written regardless of pass/fail), so a failing SDK must not
fail the refresh. Add `|| true`; the existing 'no results produced'
guard catches a genuinely broken run.

* chore: refresh SEP traceability manifest (typescript-sdk@main) (#291)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Make scopesSupported disjoint from challenge scopes so the SEP-2350 union check can't be satisfied by scopes_supported ∪ challenge

A client that unions scopes_supported with the challenge — instead of its
prior grant with the challenge — would have requested mcp:basic mcp:write
and falsely passed sep-2350-scope-union-on-reauth, since scopesSupported
happened to coincide with the previously-granted scope. Setting it to a
disjoint value makes the check actually require the prior token's scope.

Spec backing: clients MUST NOT assume any set relationship between the
challenged scope set and scopes_supported, so a disjoint advertisement is
realistic.

* SEP-837: application_type check in DCR registration (#284)

* Add SEP-837 application_type check to DCR registration

SEP-837 requires MCP clients to specify an appropriate application_type
during Dynamic Client Registration so OIDC authorization servers can
apply the correct redirect-URI constraints.

- Traceability yaml: 1 check (presence + valid value), 4 excluded
  (class-specific SHOULDs unobservable; UI/robustness)
- Check added in the shared createAuthServer DCR handler so it fires in
  every auth scenario that performs DCR (no new scenario)
- withOAuthRetry now sets application_type: native (passing example;
  the conformance example clients are CLI tools)
- New auth-test-no-application-type negative client + vitest case

* Widen ConformanceOAuthProvider metadata type for application_type

Fixes CI typecheck (TS2353 at withOAuthRetry.ts:76): the SDK's
OAuthClientMetadataSchema doesn't include application_type yet.
registerClient() spreads clientMetadata verbatim into the /register
POST body, so a local type intersection is sufficient to get the
field on the wire without an SDK release.

* Set application_type in runAuthMigrationClient

The SEP-2352 authorization-server-migration handler constructs its own
ConformanceOAuthProvider (not via withOAuthRetry), so it was missing
application_type after rebasing onto main. The scenario does DCR twice
(old AS, new AS) and the SEP-837 check fires on each.

---------

Co-authored-by: Paul Carleton <paulc@anthropic.com>

* feat: add conformance tests for iss parameter (SEP-2468) (#220)

* feat: add conformance tests for iss parameter (SEP-2468)

Adds 5 draft conformance scenarios testing RFC 9207 issuer parameter
validation in OAuth authorization responses:

- auth/iss-supported: server advertises support and sends correct iss
- auth/iss-not-advertised: server omits iss parameter entirely
- auth/iss-supported-missing: client must reject missing iss when required
- auth/iss-wrong-issuer: client must reject mismatched iss value
- auth/iss-unexpected: client must reject iss when not advertised

Also adds auth-test-iss-validation.ts, a reference client that correctly
validates iss per RFC 9207, and negative tests confirming the standard
client fails all three rejection scenarios.

TODO: Update RFC_9207_ISS_PARAMETER spec reference once SEP-2468
(modelcontextprotocol/modelcontextprotocol#2468) is merged.

* update scenarios

* fix: createAuthServer iss option type/guard and NotAdvertised scenario duplication

The doc comments said 'Default: not included' but the destructure defaulted
to true/'correct', and the `!== undefined` guard at L155 was unreachable —
so there was no way to omit the metadata field, and IssParameterNotAdvertised
silently advertised support (a duplicate of IssParameterSupported).

Kept the on-by-default behavior (mock AS models a well-behaved server) but
made issParameterSupported `boolean | null` so callers pass null to omit,
matching the codeChallengeMethodsSupported pattern. Doc comments now match.
Scenarios that need omission pass null/'omit' explicitly.

* fix: rejection scenarios silently pass when client never reaches auth endpoint

correctlyRejected = !tokenRequestMade reports SUCCESS if the client errors
out before hitting /authorize. Gate on authReached so a setup failure shows
as FAILURE with authReached:false in details.

* fix: iss-unexpected scenario contradicts SEP-2468 spec table row 3

The spec table says: supported=false/absent + iss present -> *Compare* to
the recorded issuer (not reject). The scenario sent a *correct* iss and
FAILed compliant clients for proceeding after a successful comparison.

Now sends a mismatched iss so the comparison fails and rejection is the
spec-required outcome. Reference client updated to compare-when-present
instead of throw-on-presence.

* refactor: replace harness-config checks with client-proceeded checks

iss-advertised-in-metadata / iss-sent-in-redirect (and the not-* variants)
fired in onAuthorizationRequest before the redirect happened, asserting only
that the harness was configured correctly — a client that ignores iss passes
identically. Replaced with one check per scenario keyed on tokenRequestMade,
which observes that the client actually proceeded through the iss path.

* refactor: rename check IDs to sep-2468-* and align with spec table rows

One ID per spec table row; auth/iss-supported and auth/iss-wrong-issuer
both emit sep-2468-client-compare-iss-supported (same comparison, opposite
input) per the same-slug-for-SUCCESS-and-FAIL convention.

* feat: add sep-2468.yaml requirement traceability

8 check rows (4 client table-row checks, 1 metadata-issuer, 2 AS-side,
1 no-normalization), 1 excluded (error-display is UI-facing). The
record-issuer MUST is merged into the compare-iss-supported row text
since it has no independent wire observation.

* fix: migrate iss scenarios specVersions->source (post-#265)

Replaces `specVersions: ['draft']` with `source: { introducedIn: DRAFT_PROTOCOL_VERSION }`
in the 5 iss-parameter scenarios.

This commit typechecks once the stack is rebased onto main >= #265 (the
ScenarioSource migration). Adding it now so the rebase is mechanical.

* fix: include application_type in iss-validation example DCR (post-#284)

The SEP-837 application_type check now runs in every auth scenario; the
hand-rolled DCR in auth-test-iss-validation.ts was omitting the field.

---------

Co-authored-by: Paul Carleton <paulc@anthropic.com>

---------

Co-authored-by: Anubhav Dhawan <anubhavdhawan@google.com>
Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com>
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
Co-authored-by: Paul Carleton <paulc@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Max Gerber <89937743+max-stytch@users.noreply.github.com>
2026-05-20 00:02:03 +01:00
Max Gerber
78d7219198
feat: add conformance tests for iss parameter (SEP-2468) (#220)
* feat: add conformance tests for iss parameter (SEP-2468)

Adds 5 draft conformance scenarios testing RFC 9207 issuer parameter
validation in OAuth authorization responses:

- auth/iss-supported: server advertises support and sends correct iss
- auth/iss-not-advertised: server omits iss parameter entirely
- auth/iss-supported-missing: client must reject missing iss when required
- auth/iss-wrong-issuer: client must reject mismatched iss value
- auth/iss-unexpected: client must reject iss when not advertised

Also adds auth-test-iss-validation.ts, a reference client that correctly
validates iss per RFC 9207, and negative tests confirming the standard
client fails all three rejection scenarios.

TODO: Update RFC_9207_ISS_PARAMETER spec reference once SEP-2468
(modelcontextprotocol/modelcontextprotocol#2468) is merged.

* update scenarios

* fix: createAuthServer iss option type/guard and NotAdvertised scenario duplication

The doc comments said 'Default: not included' but the destructure defaulted
to true/'correct', and the `!== undefined` guard at L155 was unreachable —
so there was no way to omit the metadata field, and IssParameterNotAdvertised
silently advertised support (a duplicate of IssParameterSupported).

Kept the on-by-default behavior (mock AS models a well-behaved server) but
made issParameterSupported `boolean | null` so callers pass null to omit,
matching the codeChallengeMethodsSupported pattern. Doc comments now match.
Scenarios that need omission pass null/'omit' explicitly.

* fix: rejection scenarios silently pass when client never reaches auth endpoint

correctlyRejected = !tokenRequestMade reports SUCCESS if the client errors
out before hitting /authorize. Gate on authReached so a setup failure shows
as FAILURE with authReached:false in details.

* fix: iss-unexpected scenario contradicts SEP-2468 spec table row 3

The spec table says: supported=false/absent + iss present -> *Compare* to
the recorded issuer (not reject). The scenario sent a *correct* iss and
FAILed compliant clients for proceeding after a successful comparison.

Now sends a mismatched iss so the comparison fails and rejection is the
spec-required outcome. Reference client updated to compare-when-present
instead of throw-on-presence.

* refactor: replace harness-config checks with client-proceeded checks

iss-advertised-in-metadata / iss-sent-in-redirect (and the not-* variants)
fired in onAuthorizationRequest before the redirect happened, asserting only
that the harness was configured correctly — a client that ignores iss passes
identically. Replaced with one check per scenario keyed on tokenRequestMade,
which observes that the client actually proceeded through the iss path.

* refactor: rename check IDs to sep-2468-* and align with spec table rows

One ID per spec table row; auth/iss-supported and auth/iss-wrong-issuer
both emit sep-2468-client-compare-iss-supported (same comparison, opposite
input) per the same-slug-for-SUCCESS-and-FAIL convention.

* feat: add sep-2468.yaml requirement traceability

8 check rows (4 client table-row checks, 1 metadata-issuer, 2 AS-side,
1 no-normalization), 1 excluded (error-display is UI-facing). The
record-issuer MUST is merged into the compare-iss-supported row text
since it has no independent wire observation.

* fix: migrate iss scenarios specVersions->source (post-#265)

Replaces `specVersions: ['draft']` with `source: { introducedIn: DRAFT_PROTOCOL_VERSION }`
in the 5 iss-parameter scenarios.

This commit typechecks once the stack is rebased onto main >= #265 (the
ScenarioSource migration). Adding it now so the rebase is mechanical.

* fix: include application_type in iss-validation example DCR (post-#284)

The SEP-837 application_type check now runs in every auth scenario; the
hand-rolled DCR in auth-test-iss-validation.ts was omitting the field.

---------

Co-authored-by: Paul Carleton <paulc@anthropic.com>
2026-05-19 23:42:35 +01:00
Den Delimarsky
12252466e6
SEP-837: application_type check in DCR registration (#284)
* Add SEP-837 application_type check to DCR registration

SEP-837 requires MCP clients to specify an appropriate application_type
during Dynamic Client Registration so OIDC authorization servers can
apply the correct redirect-URI constraints.

- Traceability yaml: 1 check (presence + valid value), 4 excluded
  (class-specific SHOULDs unobservable; UI/robustness)
- Check added in the shared createAuthServer DCR handler so it fires in
  every auth scenario that performs DCR (no new scenario)
- withOAuthRetry now sets application_type: native (passing example;
  the conformance example clients are CLI tools)
- New auth-test-no-application-type negative client + vitest case

* Widen ConformanceOAuthProvider metadata type for application_type

Fixes CI typecheck (TS2353 at withOAuthRetry.ts:76): the SDK's
OAuthClientMetadataSchema doesn't include application_type yet.
registerClient() spreads clientMetadata verbatim into the /register
POST body, so a local type intersection is sufficient to get the
field on the wire without an SDK release.

* Set application_type in runAuthMigrationClient

The SEP-2352 authorization-server-migration handler constructs its own
ConformanceOAuthProvider (not via withOAuthRetry), so it was missing
application_type after rebasing onto main. The scenario does DCR twice
(old AS, new AS) and the SEP-837 check fires on each.

---------

Co-authored-by: Paul Carleton <paulc@anthropic.com>
2026-05-19 23:28:50 +01:00
Den Delimarsky
1ef3cd34bd
SEP-2352: authorization-server migration scenario (#286)
* Add SEP-2352 authorization-server migration scenario

SEP-2352 requires that client credentials are bound to the issuing
authorization server: when PRM authorization_servers changes to a new
issuer, clients MUST re-register and MUST NOT reuse the previous AS's
client credentials.

- Traceability yaml: 3 checks, 3 excluded (internal state / UI)
- New auth/authorization-server-migration scenario (draft suite): two
  auth servers; PRM flips from AS1 to AS2 after the first authenticated
  request; AS2 asserts it received a fresh /register and never saw AS1's
  client_id at /authorize or /token
- ConformanceOAuthProvider gains invalidateCredentials and bindIssuer so
  the everything-client can key credentials by issuer (passing example)
- everything-client adds an issuer-aware handler for this scenario that
  re-reads PRM on each 401 and rebinds before re-authorizing
- auth-test-reuse-credentials negative client + vitest case

* Drop application_type from DCR metadata (not in SDK OAuthClientMetadata type)

---------

Co-authored-by: Paul Carleton <paulc@anthropic.com>
2026-05-19 22:59:31 +01:00
Yuan Teoh
91755d652c
feat: add server conformance tests for SEP-2575 (#271)
* feat: add server conformance tests for SEP-2575

* refactor and add new checks

* Fix stateless scenario source field and report SKIPPED for inapplicable capability checks

- Add the required `source` field (DRAFT) so the scenario typechecks and is
  selectable via --spec-version. Without it the class did not satisfy the
  ClientScenario interface and s.source was dereferenced by the spec-version
  filter at list time.
- Teach runCheck about a SKIPPED status and use it for the two client-capability
  checks when the server does not return -32003, instead of reporting a green
  PASS for a requirement that was never exercised.

* Remove unimplemented placeholder checks from stateless server scenario

The subscriptions/listen, statelessness-invariant, list-changed and
disconnect-is-cancel checks emitted SUCCESS without probing the server,
which inflated coverage in the traceability report. Drop them until they
have real assertions; the corresponding rows remain declared in
src/seps/sep-2575.yaml so traceability shows them as not-yet-covered.

Also fix the checkErrorId helper to push under the
sep-2575-http-server-error-jsonrpc-id slug so its failure path actually
short-circuits the aggregate SUCCESS check at the end of the scenario.

---------

Co-authored-by: Paul Carleton <paulc@anthropic.com>
2026-05-19 22:40:35 +01:00
Anubhav Dhawan
5c1b815cd1
feat: add client conformance tests for SEP-2575 (#270)
* feat: merge latest request-metadata scenario stacked branch

* test: implement optional capability conditional checks and simulated negotiation retry
2026-05-19 21:10:52 +01:00
Paul Carleton
acc70de0f6
refactor: range-based spec version tagging (introducedIn/removedIn) (#265)
* refactor: replace specVersions list with introducedIn/removedIn range tagging

Replaces per-scenario `specVersions: SpecVersion[]` arrays with `introducedIn`
and optional `removedIn` range fields on all three scenario interfaces. Extension
scenarios get an orthogonal `extension?: boolean` flag instead of the former
`'extension'` tag in the versions list.

matchesSpecVersion() is rewritten as a range comparison
(introducedIn <= target && (!removedIn || target < removedIn)), with draft
sorting after all dated versions. getScenarioSpecVersions() reconstructs the
effective version list from the range for backward-compat with tier-check.
Closes #256.

* refactor: nest spec-version range under `source: ScenarioSource` union

The flat `introducedIn`/`removedIn`/`extension?` shape forced extension
scenarios to set a placeholder `introducedIn` that was never read. Nesting
the version-range fields inside a `source` property typed as a union lets
the compiler enforce introducedIn XOR extensionId — no runtime invariant
test needed.

  type ScenarioSource =
    | { introducedIn: SpecVersion; removedIn?: SpecVersion }
    | { extensionId: ExtensionId };

A class can't `implements` a union type directly, so the union lives inside
a property and `Scenario` stays a plain interface — `class implements
Scenario` keeps working everywhere. `EXTENSION_IDS` is a const array
mirroring the `DATED_SPEC_VERSIONS` pattern.

Also renames the cross-app-access scenario to enterprise-managed-auth to
match the extension's canonical name: file, class, slug, context schema
literal, and the everything-client runner.

* refactor: use canonical SEP-2133 extension identifiers

EXTENSION_IDS now holds the wire identifiers from the spec's extension docs
(client-matrix.mdx, docs/extensions/auth/*.mdx) so extensionId values can be
cross-referenced against capabilities.extensions keys directly:

  io.modelcontextprotocol/oauth-client-credentials
  io.modelcontextprotocol/enterprise-managed-authorization

The previous commit used a shortened 'enterprise-managed-auth' which doesn't
match the canonical '-authorization'. Re-renames the scenario file/class/slug
and downstream references to align.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-14 16:12:32 +01:00
Paul Carleton
825f2031c8
chore(deps): security rollup — path-to-regexp, defu, vite, hono, @hono/node-server (#251)
Supersedes #204, #209, #210, #218, #229, #230, #231, #232, #233.
Excludes #205 (failing CI; triaged separately).
2026-04-24 12:22:07 +01:00
Paul Carleton
5d8595b663
test: add server-side negative test harness (#249)
Adds src/scenarios/server/negative.test.ts with spawn helpers. Wires
two cases: the previously-orphaned no-dns-rebinding-protection.ts and
a new sep-2164-empty-contents.ts. Strengthens the AGENTS.md guidance
to point at the harness.
2026-04-24 12:09:12 +01:00
Paul Carleton
8f3994c75f
chore(deps): consolidate dependabot updates (#192)
* chore(deps): consolidate dependabot updates

Bumps all pending dependency updates into one commit:

Root package:
- zod 3.25.76 → 4.3.6 (major)
- @types/node 22 → 25 (major)
- @modelcontextprotocol/sdk 1.26.0 → 1.27.1
- tsdown 0.15.12 → 0.21.4
- prettier 3.6.2 → 3.8.1
- typescript-eslint 8.48.0 → 8.57.1
- lefthook 2.0.2 → 2.1.4
- eslint/@eslint/js → 9.39.4 (kept at v9, typescript-eslint lacks v10 support)
- Regenerated lockfile to pick up transitive security fixes
  (hono, @hono/node-server, express-rate-limit, flatted, rollup,
  minimatch, ajv, qs, undici)

examples/servers/typescript:
- @modelcontextprotocol/sdk → 1.27.1
- Removed zod-to-json-schema (broken with zod v4)
- Added zod ^4 as direct dep
- Regenerated lockfile

GitHub Actions:
- actions/setup-node v4 → v6 in action.yml

Code changes for zod v4:
- ZodError.errors → ZodError.issues (src/index.ts)
- .refine() callback signature updated (src/schemas.ts)
- everything-server: replaced zodToJsonSchema with SDK's
  toJsonSchemaCompat helper (handles zod v3/v4/v4-mini)

Build fix for tsdown 0.21:
- Added --no-fixed-extension to preserve dist/index.js output
  (tsdown 0.21 defaults to .mjs for type:module packages)

* fix: include all platform binaries in lockfile

The lockfile was generated on macOS which caused npm to only resolve
darwin-arm64 entries for platform-specific optional dependencies
(esbuild, rolldown bindings). This broke npm ci on Linux CI runners.

Regenerated from a clean state to include all 26 esbuild platforms
and all 15 rolldown platform bindings.
2026-03-24 16:18:54 +00:00
Wils Dawson
02a5f1c41d
feat (auth): add sep-2207 client checks (#166)
* feat: add sep-2207 client checks

* Update description for the offline access test

Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com>

---------

Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com>
2026-03-18 08:34:17 +00:00
sagar-okta
83c446ddf5
feat: add conformance tests for SEP-990 (#110)
* feat: add conformance tests for SEP-990

* Resolving review changes: Removed redundant tests, updated audience params

* fix: unused serverUrl parameter in runCrossAppAccessTokenExchange

* chore: apply prettier formatting

* fix: address PR review comments for SEP-990 conformance tests

- Delete unused separate token-exchange and jwt-bearer scenarios,
  keeping only the complete e2e flow (review comment)
- Add missing required token exchange params per SEP-990 spec:
  requested_token_type, audience, resource (review comment)
- Use ctx.idp_client_id for token exchange client_id instead of
  AS client_id (review comment)
- Client discovers resource and auth server via PRM metadata
  instead of receiving auth_server_url via context (review comment)
- Server IdP handler verifies all required token exchange params
  with detailed error messages (review comment)
- Add resource, client_id, jti claims to ID-JAG per SEP-990 spec
- Verify ID-JAG typ header (oauth-id-jag+jwt) in JWT bearer handler
- Remove auth_server_url from context schema

* feat: add client auth and ID-JAG validation to XAA conformance test

Server-side (AS) now verifies:
- client_secret_basic authentication on JWT bearer grant
- ID-JAG typ header is oauth-id-jag+jwt
- ID-JAG client_id claim matches the authenticating client (Section 5.1)
- ID-JAG resource claim matches the MCP server resource identifier
- Client credentials provided via context (client_secret)

Server-side (IdP) now:
- Sets ID-JAG client_id to the MCP Client's AS client_id (not the
  IdP client_id), per Section 6.1

Example client now:
- Authenticates to AS via client_secret_basic (Authorization: Basic)
  instead of sending client_id in body
- Checks AS metadata grant_types_supported includes jwt-bearer
  before attempting the flow

* fix: share MockTokenVerifier and remove unadvertised auth method

- Add shared MockTokenVerifier between AS and MCP server so the MCP
  server only accepts tokens actually issued by the auth server,
  matching the pattern used by all other auth scenarios
- Remove private_key_jwt from tokenEndpointAuthMethodsSupported since
  the handler only implements client_secret_basic

---------

Co-authored-by: Paul Carleton <paulc@anthropic.com>
2026-02-13 17:47:54 +00:00
Felix Weinberger
37225cef7d
fix: create fresh Server per request in auth test helpers (#141)
The auth test server helper and no-dns-rebinding-protection example
reused a single Server instance across requests, calling connect()
on each new transport. SDK v1.26.0's security fix (GHSA-345p-7cg4-v4c7)
now throws "Already connected to a transport" in this case.

Fix by wrapping Server creation in a factory function called per
request, matching the pattern already used by tools_call.ts and
everything-server.ts.

Also updates no-dns-rebinding-protection.ts to use registerTool()
instead of the deprecated tool() API.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 19:22:16 +00:00
Paul Carleton
67ad358019
feat: add resource parameter validation tests (RFC 8707) (#118)
* feat: add resource parameter validation tests (RFC 8707)

Adds conformance tests for OAuth Resource Indicators (RFC 8707) implementation:

1. Resource parameter checks added to token-endpoint-auth-basic scenario:
   - resource-parameter-in-authorization: Verify resource in auth request
   - resource-parameter-in-token: Verify resource in token request
   - resource-parameter-valid-uri: Verify valid canonical URI
   - resource-parameter-consistency: Verify consistency between requests

2. New auth/resource-mismatch scenario:
   - Tests that client rejects when PRM resource doesn't match server URL
   - Server returns mismatched resource in PRM
   - Test passes if client does NOT proceed with authorization

Also adds spec references for RFC 8707 and MCP resource parameter spec.

Closes #33

* fix: make resource consistency check a FAILURE and remove dead code

- Change resource parameter consistency from WARNING to FAILURE
- Remove unreachable protocol check in validateCanonicalUri
  (URL constructor already validates scheme presence)
2026-01-23 18:21:46 +00:00
Paul Carleton
4a2ba8ae7b
feat: add PKCE conformance tests (#119)
* feat: add PKCE conformance tests

Adds conformance checks for PKCE requirements from the MCP auth spec:

- pkce-code-challenge-sent: Verifies client sends code_challenge in auth request
- pkce-s256-method-used: Verifies client uses S256 code challenge method
- pkce-code-verifier-sent: Verifies client sends code_verifier in token request
- pkce-verifier-matches-challenge: Validates BASE64URL(SHA256(verifier)) = challenge

Also adds auth/pkce-no-s256-support scenario that tests clients correctly
refuse when S256 is not in code_challenge_methods_supported.

All PKCE checks are added to the createAuthServer helper, so they automatically
apply to all existing auth scenarios.

Fixes #77

* feat: add bad client example that skips PKCE

Adds auth-test-no-pkce.ts which implements a custom OAuth flow that
deliberately skips PKCE (no code_challenge in auth request, no
code_verifier in token request).

Also adds negative test to verify the conformance suite correctly
detects this non-compliant behavior.

* chore: skip pkce-no-s256-support scenario for now

* chore: fix formatting

* refactor: remove pkce-no-s256-support scenario and always validate PKCE

- Remove pkce-no-s256-support scenario (was skipped anyway)
- Make pkce-verifier-matches-challenge fail if either code_challenge
  or code_verifier is missing, rather than only running when both present
- Update negative test to expect the new failure
2026-01-23 18:12:44 +00:00
Paul Carleton
245e44e882
feat: add pre-registration conformance test (#120)
* feat: add pre-registration conformance test

Add conformance test for OAuth pre-registration flow where the server
does NOT support Dynamic Client Registration (DCR) and clients must
use pre-configured static credentials.

This addresses issue #34 (Client Registration Methods) - specifically
the pre-registration section that was previously not covered.

Changes:
- Add disableDynamicRegistration option to createAuthServer helper
- Add auth/pre-registration scenario with pre-registered client creds
- Add MCP_PREREGISTRATION spec reference
- Add context schema for pre-registration credentials
- Add withOAuthRetryWithProvider helper for pre-configured providers
- Add negative test client (auth-test-attempts-dcr.ts) that ignores
  pre-registered credentials and fails

The scenario verifies that when a server does not advertise
registration_endpoint in its OAuth metadata, compliant clients
use pre-registered credentials passed via context instead of
attempting DCR.

Closes #34

* fix: add redirect_uris to saveClientInformation call

* chore: remove unused WithOAuthRetryOptions interface
2026-01-23 11:43:56 +00:00
Paul Carleton
d0b2b4914d
feat: add DNS rebinding protection conformance tests (#115)
* feat: add DNS rebinding protection conformance tests

Add a new server conformance scenario to verify that localhost MCP servers
properly validate Host headers to prevent DNS rebinding attacks.

Checks:
- localhost-host-rebinding-rejected: Verifies server returns 403 for
  non-localhost Host headers (e.g., evil.example.com)
- localhost-host-valid-accepted: Verifies server accepts requests with
  valid localhost Host headers

Also updates the everything-server example to use createMcpExpressApp()
which includes DNS rebinding protection by default.

Closes #103

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add negative test case for DNS rebinding protection

Add a minimal MCP server that intentionally omits DNS rebinding protection
to serve as a negative test case. This server is expected to FAIL the
dns-rebinding-protection scenario.

Also update README to document the negative test case.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: accept any 4xx status code for DNS rebinding rejection

Update the DNS rebinding protection test to accept any 4xx status code
as a valid rejection response, not just 403. This accommodates different
HTTP semantics:
- 403 Forbidden: Per MCP spec
- 421 Misdirected Request: RFC 7540 (semantically correct for DNS rebinding)
- Other 4xx: Implementation-specific error codes

* refactor: address PR review comments

- Simplify negative test server (remove event store, sessions)
- Update spec reference URL to security_best_practices
- Clarify scope: localhost servers without HTTPS/auth
- DRY up checks.push using spread operator
- Fix valid host check to require 2xx response

* fix: include error details in catch block

* refactor: simplify negative test server to stateless

* refactor: check both Host and Origin headers for DNS rebinding protection

- Send both Host and Origin headers in test requests so servers checking
  either header will pass the conformance test
- Add second spec reference for Origin check (transports#security-warning)
- Update descriptions to mention both Host and Origin headers
- Fix protocol version to 2025-11-25
- Remove unnecessary 'as const' type assertions

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-22 18:37:48 +00:00
Konstantin Konstantinov
0675e9b382
update npm audit (#108) 2026-01-19 16:46:09 +00:00
Paul Carleton
753f1240d1
Add client credentials support to everything-client (#89)
* Add client credentials support to everything-client

- Add ConformanceContextSchema with discriminated union for auth contexts
- Add runClientCredentialsJwt and runClientCredentialsBasic handlers
- Update runner to include scenario name in context for discriminated union parsing
- Update test helpers to set env vars for inline client runners
- Fix JWT audience validation to match SDK behavior (no trailing slash)
- Remove client credentials scenarios from skip list

* Accept both trailing slash forms for JWT audience per RFC 3986

Per RFC 3986, URLs with and without trailing slash are equivalent.
The MCP spec recommends (SHOULD) the form without trailing slash, but
since it's not a MUST, the conformance test should accept both forms
for interoperability with clients like Pydantic that normalize URLs.

* Remove .vscode from tracking and add to gitignore

* Address review feedback

- Remove unused issuerUrl variable and comment
- Simplify audience array to exactly 2 values with clearer naming
- Add comment explaining strip-then-add-back logic
- Rename ConformanceContextSchema to ClientConformanceContextSchema

* Remove dist from tracking and add to gitignore

* Fix .gitignore formatting

* Add getHandler to everything-client for cleaner test imports

Instead of importing individual handlers, tests can now import getHandler
and look up handlers by scenario name.

* Use getHandler exclusively, remove goodClient import

- Add CIMD support to runAuthClient in everything-client
- Add auth fallback to getHandler for unregistered auth/* scenarios
- Remove goodClient import from test file

* Remove runAuthClient fallback, register all auth scenarios explicitly
2026-01-05 17:48:53 +00:00
dependabot[bot]
e4cb55ead6
Bump the npm_and_yarn group across 1 directory with 2 updates (#83)
Bumps the npm_and_yarn group with 2 updates in the /examples/servers/typescript directory: [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) and [qs](https://github.com/ljharb/qs).


Updates `@modelcontextprotocol/sdk` from 1.22.0 to 1.24.0
- [Release notes](https://github.com/modelcontextprotocol/typescript-sdk/releases)
- [Commits](https://github.com/modelcontextprotocol/typescript-sdk/compare/1.22.0...1.24.0)

Updates `qs` from 6.14.0 to 6.14.1
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.14.0...v6.14.1)

---
updated-dependencies:
- dependency-name: "@modelcontextprotocol/sdk"
  dependency-version: 1.24.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: qs
  dependency-version: 6.14.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-05 14:20:40 +00:00
Paul Carleton
be51f872e1
Refactor client testing to use 'everything' client with scenario routing (#54)
* Refactor client testing to pass scenario name and server URL

The CLI now passes both scenario name and server URL as arguments to the
client command (instead of just the server URL). This enables a single
"everything" client that can handle all scenarios based on the scenario
name it receives.

Changes:
- Update executeClient() to pass scenarioName as first argument to client
- Add everything-client.ts that routes to appropriate behavior based on
  scenario name
- Update README with new usage examples and documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Use env var for scenario name instead of positional arg

Pass scenario name via MCP_CONFORMANCE_SCENARIO env var instead of as a
positional argument. This is non-breaking for existing clients that just
accept <server-url>.

The env var approach is consistent with how context (including private
keys for JWT auth) is already passed via MCP_CONFORMANCE_CONTEXT.

* Add comment explaining env var design decision

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Olivier Chafik <ochafik@anthropic.com>
2026-01-05 14:16:21 +00:00
dependabot[bot]
13f7950da5
Bump the npm_and_yarn group across 1 directory with 2 updates (#72)
Bumps the npm_and_yarn group with 1 update in the /examples/servers/typescript directory: [express](https://github.com/expressjs/express).


Updates `express` from 5.1.0 to 5.2.1
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/v5.1.0...v5.2.1)

Updates `body-parser` from 2.2.0 to 2.2.1
- [Release notes](https://github.com/expressjs/body-parser/releases)
- [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/body-parser/compare/v2.2.0...v2.2.1)

---
updated-dependencies:
- dependency-name: express
  dependency-version: 5.2.1
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: body-parser
  dependency-version: 2.2.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-05 14:00:56 +00:00
Felix Weinberger
f0e948187d
feat: add conformance tests for SEP-1699 SSE polling (#47) 2025-11-24 18:34:28 +00:00
Paul Carleton
b64e054918
Add sep-835 limit retry scenario, add suite options to server command and update pending scenarios (#49)
* lefthook: move deps installs to optional local change

* add test scenario for infinite retry
and negative test

* Add broken client for retry limit negative test and fix lefthook formatting

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix www-authenticate in scope scenario

* add suites and shift pending to reflect current pending

* lint

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-21 16:49:38 +00:00
Paul Carleton
d303013e5d
[auth] Implement CIMD conformance test (#37)
* add cimd test and negative test

* Improve auth-test-no-cimd.ts documentation for clarity

Address review feedback: expanded comments to better explain what CIMD is,
why this client is non-compliant, and what behavior it's testing.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Remove .js extensions from relative imports

tsx doesn't require .js extensions for TypeScript imports.
Keeps .js for @modelcontextprotocol/sdk imports as those are external packages.

Also improves auth-test-no-cimd.ts documentation for clarity.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Skip auth/basic-cimd test until SDK support lands

Waiting on typescript-sdk PR #1127 for CIMD support.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix trailing whitespace in auth-test-no-cimd.ts

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-20 21:00:13 +00:00
Felix Weinberger
f087e44bdb
Add JSON Schema 2020-12 conformance test (SEP-1613) (#45)
Add conformance test to validate that MCP servers correctly preserve
JSON Schema 2020-12 keywords ($schema, $defs, additionalProperties)
in tool definitions.

Changes:
- Add JsonSchema2020_12Scenario in src/scenarios/server/json-schema-2020-12.ts
- Add json_schema_2020_12_tool to everything-server with tools/list override
  to return raw JSON Schema instead of Zod-converted schema
- Register scenario in pendingClientScenariosList (requires SDK PR #1135)

The test is added to pending because the client SDK currently strips
the JSON Schema 2020-12 keywords. Once PR #1135 is merged into the SDK,
this scenario can be moved to the active list.
2025-11-20 18:20:06 +00:00
Pavel Bezglasny
7f0755627f
Fix example server elicitation conf (#29)
* fix server elicitation conf

* Remove empty elicitation object from server config

* Use ElicitResultSchema instead of z.any() for proper validation

The elicitation/create response should be validated against ElicitResultSchema
which ensures the response has the correct structure (action, content fields)
rather than accepting any response.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Paul Carleton <paulc@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com>
2025-11-20 14:33:37 +00:00
Paul Carleton
5c151133bb
[auth] Scenarios for scope selection (#36)
* wip scope change

* rm useless bool

* fix-me: package changes for linking

* negative test

* negative test for multiple scopes

* fix displays of warnings

* wip step-up

* negative test for step up auth

* move warning into main request flow

* clean up more checks

* cleanup step-up scenario

* cleanup and simplify

* cleanup middleware

* inline negative tests

* inline the other test

* refactor logging and inlining for standalone execution too

* skip pending tests
2025-11-18 17:16:23 +00:00
Paul Carleton
f7c8c4460f
[scenario] authz metadata discovery tests: compatibility with 2025-03-26 spec, prm root, and www-authenticate (#28)
* clean up constructor calls for server lifecycle

* add back compat test

* fix dup logging, rm prm

* avoid fallbacks

* better error from example client

* add final endpoint method

* add test for OASM priority order

* s/prepack/prepare/ for npx

* try switching to .js

* make tsdown version happy default

* fix lock

* fix prmPath issue

* back to main package-lock

* fix bin path

* Add comprehensive auth scenario test suite

- Add index.test.ts to test all auth scenarios with auth-test.ts client
- Upgrade @modelcontextprotocol/sdk from 1.20.1 to 1.22.0
- All 5 auth scenarios now pass including auth/basic-metadata-var2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* consolidate tests into index.test.ts

* rename metadata

* fix comments

* rework auth scenario listing

* add 3rd variation of metadata

* fix some type issues introduced by version bump

* add reusable spec references

* more refs

* fix up spec references

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-14 18:36:07 +00:00
Paul Carleton
eed3b222a1
Typecheck and lint example client
Don't do server yet, since it has its own package.json which breaks
checking imports.
2025-11-12 14:38:07 +00:00
Felix Weinberger
e19918d968
Add conformance tests for SEP-1330 elicitation enums (#22)
* Add SEP-1330 conformance test for elicitation enum schemas

Adds server-side conformance test that validates servers properly request
elicitation with SEP-1330 enum schema improvements:
- Untitled single-select enum (type: string, enum: [...])
- Titled single-select enum (oneOf with const/title)
- Legacy titled enum (enumNames for backward compatibility)
- Untitled multi-select enum (type: array, items.enum)
- Titled multi-select enum (items.anyOf with const/title)

Test expects server to implement `test_elicitation_sep1330_enums` tool.

* Add reference server implementation for SEP-1330 conformance test

Adds test_elicitation_sep1330_enums tool to everything-server that
requests elicitation with all 5 enum schema variants. Also updates
SERVER_REQUIREMENTS.md with full specification.

* Fix prettier formatting

* only test active tests (#24)

* refactor maps to pull names from the test

* bring names back

* separate active from pending

* only test active

---------

Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com>
2025-11-11 19:34:47 +00:00
Paul Carleton
f95f487ae8
[scenario] Add test for broken oauth client (#12)
* starting on broken auth client

* switch to middleware approach

* add broken example

* fix failure testing

* subset matching
2025-11-11 14:17:49 +00:00
Felix Weinberger
f7bc687819
Add client-side SEP-1034 elicitation defaults conformance test (#19)
* feat: add client-side SEP-1034 conformance test for elicitation defaults

Adds a conformance test that validates client SDKs properly apply
default values for omitted fields in elicitation responses per SEP-1034.

The test spins up a server that sends elicitation requests with defaults,
and validates that the client returns content with those defaults applied.

* feat: use elicitInput() for SEP-1034 default validation

Updates client-side test to validate server-side default application
using elicitInput() helper, which applies defaults via validation layer.
This aligns with the TypeScript SDK's SEP-1034 implementation approach.

The test now validates:
- Server uses elicitInput() with schemas containing defaults
- Client returns empty/partial content
- Server automatically applies defaults during validation
- Defaults are correctly merged for all primitive types

* refactor: use server.request() instead of elicitInput() for client-side defaults test

Ensures conformance test validates true client-side default application
rather than server-side validation behavior.

* feat: add applyDefaults capability flag for opt-in default application

Enables conformance test to opt into client-side elicitation defaults
by setting the applyDefaults capability flag.
2025-11-11 14:05:11 +00:00
Matt
7f1515c475
tsdown + cli with commander (#17)
* feat: tsdown

* fix: formatting

* automate version updates in cli

* fix: docs

* scenarios

* fix: commander deps
2025-11-11 11:51:55 +00:00
Felix Weinberger
0e8f13ba1e
feat: add SEP-1034 conformance test for elicitation defaults (#14)
Add comprehensive conformance test for SEP-1034 which extends MCP
elicitation to support default values across all primitive types.

Changes:
- Add test_elicitation_sep1034_defaults tool to reference server
- Create ElicitationDefaultsScenario with 5 granular checks:
  * String schema default value
  * Integer schema default value
  * Number schema default value
  * Enum schema default value (validates it's a valid enum member)
  * Boolean schema default value (regression test)
- Register scenario in index.ts

The test validates that servers properly include default values in
elicitation requestedSchema per SEP-1034 specification.

Test results: All 5 checks pass against TypeScript reference server
2025-11-10 16:04:09 +00:00
Paul Carleton
69f02a4557
[scenario] OAuth basic & PRM variation (#11)
* readme for auth tests

* wip prm test

* add example helper for local oauth w/o browser

* working through dangling timeout issue

* add better test function

* pretty printing

* add mcp method

* some more logging tweaks

* refactor logger into 1 class

* use common request logger

* fix base scenario

* some renaming

* refactor into helpers

* refactor to support second test

* rm readme

* add comment about www-authenticate
2025-11-10 11:51:30 +00:00
Paul Carleton
b377251b15
adjust prettier to use more defaults (#8)
* simplify prettier to use more defaults

* apply new prettier
2025-11-04 15:34:27 +00:00
Inna Harper
a692dd7bba
[compliance tests] initial server scenarios (#4)
* spec for servers

* initial version of everything server and tests - tets are very simple

* some clean up

* lint etc.

* fix package lock agian

---------

Co-authored-by: Paul Carleton <paulc@anthropic.com>
2025-11-04 15:08:20 +00:00
Paul Carleton
cff9669f8a
Add tools_call scenario and test 2025-10-30 13:26:33 +00:00
Paul Carleton
f32b01c57d
apply linting 2025-10-30 13:09:16 +00:00
Paul Carleton
2c1cea291f
readme 2025-10-29 14:56:27 +00:00
Paul Carleton
fb3482530d
add very simple test client 2025-10-29 14:03:36 +00:00