MCP SDK Tier Audit: modelcontextprotocol/ruby-sdk
SDK: modelcontextprotocol/ruby-sdk
Date: 2026-08-15
Branch: main (commit ad73154, v1.2.0 released 2026-08-15)
Requested tier: Tier 1
Requirements revisions scored: 2025-11-25 and 2026-07-28 (frozen requirement sets, each run at that revision's own wire version, per @modelcontextprotocol/conformance 0.2.0-alpha.11)
Auditor: mcp-sdk-tier-audit skill (tier-check CLI + subagent evaluation)
Previous assessments: Tier 2 (#3127, 2026-07-25); Tier 3 (#2340, 2026-03-03)
Tier Assessment
The Ruby SDK meets every Tier 1 requirement that the deterministic scorecard can measure. Server conformance is 100% (67/67) and client conformance is 100% (50/50) across both frozen requirement sets (2025-11-25 and 2026-07-28), each run at that revision's own wire version. Issue triage compliance is 100% with all 12 required labels present, no P0 has ever been filed, the stable release line is at v1.2.0, the 2026-07-28 spec revision was picked up 4 days after its release (and completed in v1.2.0, 18 days after the spec), and all three required policies (dependency updates, roadmap, versioning) are published and pass. The one item that requires working-group interpretation rather than measurement is the documentation requirement's treatment of the legacy SSE transport (features #39/#40), which the SDK intentionally does not implement: every implemented feature (46/46) is documented with examples. This application requests Tier 1 and poses that question explicitly in Question for the Working Group.
Requirements Summary
| # |
Requirement |
Tier 1 Standard |
Tier 2 Standard |
Current Value |
T1? |
T2? |
Gap |
| 1a |
Server Conformance |
100% pass rate |
>= 80% pass rate |
100% (67/67) |
PASS |
PASS |
None (16 not-scored runs detailed below) |
| 1b |
Client Conformance |
100% pass rate |
>= 80% pass rate |
100% (50/50) |
PASS |
PASS |
None (14 not-scored runs detailed below) |
| 2 |
Issue Triage |
>= 90% within 2 biz days |
>= 80% within 1 month |
100% (3/3) |
PASS |
PASS |
None |
| 2b |
Labels |
12 required labels |
12 required labels |
12/12 |
PASS |
PASS |
None |
| 3 |
Critical Bug Resolution |
All P0s within 7 days |
All P0s within 2 weeks |
0 open (0 ever filed) |
PASS |
PASS |
None |
| 4 |
Stable Release |
Required + clear versioning |
At least one stable release |
v1.2.0 (stable) |
PASS |
PASS |
None |
| 4b |
Spec Tracking |
Timeline agreed per release |
Within 6 months |
4-day gap |
PASS |
PASS |
None (v1.2.0 completed the revision 18 days after the spec) |
| 5 |
Documentation |
Comprehensive w/ examples |
Basic docs for core features |
46/48 features |
FAIL |
PASS |
#39/#40 legacy SSE transport, intentionally not implemented; see Question for the Working Group |
| 6 |
Dependency Policy |
Published update policy |
Published update policy |
Found |
PASS |
PASS |
None (bundler ecosystem not enrolled in Dependabot; see below) |
| 7 |
Roadmap |
Published roadmap |
Plan toward Tier 1 |
Found (ROADMAP.md) |
PASS |
PASS |
None (refreshed by ruby-sdk#519; all freshness flags resolved) |
| 8 |
Versioning Policy |
Documented breaking change policy |
N/A |
Found (VERSIONING.md) |
PASS |
N/A |
None |
Tier Determination
- On the strict count, the determination is Tier 2: 10/11 requirement rows meet the Tier 1 standard, and the only misses are the two legacy-SSE rows (Fix doc example of embedding resources #39/roots/list should not be marked as a client request #40) of the documentation table.
- Every other requirement passes Tier 1 outright: both conformance suites at 100% across both frozen requirement sets, 100% triage with all labels, zero P0s ever filed, a stable v1.2.0 release under a documented versioning policy, a 4-day spec-tracking gap, and all three policies published.
- We request a working-group determination on the documentation scoping question below. If the Tier 1 documentation requirement scopes to implemented features or exempts the superseded transport, the SDK meets Tier 1 in full.
- Tier 1 requirement 4b calls for an implementation timeline agreed per spec release. We propose agreeing that timeline with the spec maintainers as part of this application. The SDK's record on spec tracking: the 2025-11-25 revision was implemented 46 days after the spec release; work on the 2026-07-28 revision started at a 4-day gap and was completed in v1.2.0, 18 days after the spec.
Question for the Working Group
The legacy SSE transport (the 2024-11-05 HTTP+SSE transport) is intentionally not implemented in the Ruby SDK. It was replaced by Streamable HTTP in spec revision 2025-03-26, and the SDK's stable line (v1.0.0, released 2026-07-24) postdates that replacement, so there is no migration constituency to serve. The omission is declared out of scope in ROADMAP.md. TypeScript SDK v2 points the same direction: the SSE server transport was removed from its supported packages and survives only in the frozen, deprecated @modelcontextprotocol/server-legacy migration package (planned for removal in v3), and its client transport is deprecated.
Does the Tier 1 documentation requirement ("comprehensive with examples for all features") scope to implemented features, or otherwise exempt the superseded transport? If yes, the SDK meets Tier 1 in full: the two legacy-SSE rows are the only strict-count misses anywhere in this application, and every implemented feature (46/46) is documented with examples.
Server Conformance Details
Pass rate: 100% (67/67 scored). Revision 2025-11-25: 30/30; revision 2026-07-28: 37/37. The baseline conformance/expected_failures.yml has an empty server list: no known server conformance failures.
Scored - revision 2025-11-25 (30/30)
| Scenario |
Status |
Checks |
| tools-list |
PASS |
3/3 |
| tools-call-with-progress |
PASS |
2/2 |
| tools-call-with-logging |
PASS |
2/2 |
| tools-call-simple-text |
PASS |
2/2 |
| tools-call-sampling |
PASS |
2/2 |
| tools-call-mixed-content |
PASS |
2/2 |
| tools-call-image |
PASS |
2/2 |
| tools-call-error |
PASS |
2/2 |
| tools-call-embedded-resource |
PASS |
2/2 |
| tools-call-elicitation |
PASS |
2/2 |
| tools-call-audio |
PASS |
2/2 |
| server-sse-multiple-streams |
PASS |
2/2 |
| server-initialize |
PASS |
3/3 |
| resources-unsubscribe |
PASS |
2/2 |
| resources-templates-read |
PASS |
2/2 |
| resources-subscribe |
PASS |
2/2 |
| resources-read-text |
PASS |
2/2 |
| resources-read-binary |
PASS |
2/2 |
| resources-list |
PASS |
2/2 |
| prompts-list |
PASS |
2/2 |
| prompts-get-with-image |
PASS |
2/2 |
| prompts-get-with-args |
PASS |
2/2 |
| prompts-get-simple |
PASS |
2/2 |
| prompts-get-embedded-resource |
PASS |
2/2 |
| ping |
PASS |
2/2 |
| logging-set-level |
PASS |
2/2 |
| elicitation-sep1330-enums |
PASS |
6/6 |
| elicitation-sep1034-defaults |
PASS |
6/6 |
| dns-rebinding-protection |
PASS |
2/2 |
| completion-complete |
PASS |
2/2 |
Scored - revision 2026-07-28 (37/37)
| Scenario |
Status |
Checks |
| tools-list |
PASS |
3/3 |
| tools-call-with-progress |
PASS |
2/2 |
| tools-call-simple-text |
PASS |
2/2 |
| tools-call-mixed-content |
PASS |
2/2 |
| tools-call-image |
PASS |
2/2 |
| tools-call-error |
PASS |
2/2 |
| tools-call-embedded-resource |
PASS |
2/2 |
| tools-call-audio |
PASS |
2/2 |
| server-stateless |
PASS |
30/30 |
| server-sse-multiple-streams |
PASS |
1/1 |
| sep-2164-resource-not-found |
PASS |
4/4 |
| resources-templates-read |
PASS |
2/2 |
| resources-read-text |
PASS |
2/2 |
| resources-read-binary |
PASS |
2/2 |
| resources-list |
PASS |
2/2 |
| prompts-list |
PASS |
2/2 |
| prompts-get-with-image |
PASS |
2/2 |
| prompts-get-with-args |
PASS |
2/2 |
| prompts-get-simple |
PASS |
2/2 |
| prompts-get-embedded-resource |
PASS |
2/2 |
| input-required-result-validate-input |
PASS |
3/3 |
| input-required-result-unsupported-methods |
PASS |
2/2 |
| input-required-result-tampered-state |
PASS |
2/2 |
| input-required-result-result-type |
PASS |
2/2 |
| input-required-result-request-state |
PASS |
3/3 |
| input-required-result-non-tool-request |
PASS |
3/3 |
| input-required-result-multiple-input-requests |
PASS |
3/3 |
| input-required-result-multi-round |
PASS |
4/4 |
| input-required-result-missing-input-response |
PASS |
2/2 |
| input-required-result-ignore-extra-params |
PASS |
2/2 |
| input-required-result-capability-check |
PASS |
2/2 |
| input-required-result-basic-sampling |
PASS |
3/3 |
| input-required-result-basic-list-roots |
PASS |
3/3 |
| input-required-result-basic-elicitation |
PASS |
3/3 |
| dns-rebinding-protection |
PASS |
2/2 |
| completion-complete |
PASS |
2/2 |
| caching |
PASS |
8/8 |
Not scored (run for visibility)
16 additional runs are not part of the frozen requirement sets and are not scored: 10 tasks-* scenarios exercise the SEP-2663 tasks extension, which the SDK intentionally does not implement (tracked in ruby-sdk#391); the remainder are pending scenarios (server-sse-polling, json-schema-2020-12 at the 2026-07-28 wire, http-header-validation, http-custom-header-server-validation) or scenarios added after the revision's release (server-session-lifecycle). Of these, server-session-lifecycle (3/3), json-schema-2020-12 at the 2025-11-25 wire (5/5), and http-header-validation (14/14) pass.
Client Conformance Details
Full suite pass rate: 100% (50/50 scored). Revision 2025-11-25: 18/18; revision 2026-07-28: 32/32. Suite breakdown: Core 11/11 (100%), Auth 39/39 (100%). The http-standard-headers scenario passes 9/9 following the conformance-driver fix in ruby-sdk#514, merged before v1.2.0.
Core Scenarios
| Scenario |
Revision |
Status |
Checks |
| tools_call |
2025-11-25 |
PASS |
2/2 |
| sse-retry |
2025-11-25 |
PASS |
3/3 |
| initialize |
2025-11-25 |
PASS |
1/1 |
| elicitation-sep1034-client-defaults |
2025-11-25 |
PASS |
5/5 |
| tools_call |
2026-07-28 |
PASS |
2/2 |
| sep-2322-client-request-state |
2026-07-28 |
PASS |
5/5 |
| request-metadata |
2026-07-28 |
PASS |
5/5 |
| json-schema-ref-no-deref |
2026-07-28 |
PASS |
1/1 |
| http-standard-headers |
2026-07-28 |
PASS |
9/9 |
| http-invalid-tool-headers |
2026-07-28 |
PASS |
11/11 |
| http-custom-headers |
2026-07-28 |
PASS |
18/18 |
Auth Scenarios (scored)
| Scenario |
Revision |
Status |
Checks |
| auth/token-endpoint-auth-post |
2025-11-25 |
PASS |
17/17 |
| auth/token-endpoint-auth-none |
2025-11-25 |
PASS |
17/17 |
| auth/token-endpoint-auth-basic |
2025-11-25 |
PASS |
17/17 |
| auth/scope-step-up |
2025-11-25 |
PASS |
22/22 |
| auth/scope-retry-limit |
2025-11-25 |
PASS |
18/18 |
| auth/scope-omitted-when-undefined |
2025-11-25 |
PASS |
13/13 |
| auth/scope-from-www-authenticate |
2025-11-25 |
PASS |
13/13 |
| auth/scope-from-scopes-supported |
2025-11-25 |
PASS |
13/13 |
| auth/pre-registration |
2025-11-25 |
PASS |
12/12 |
| auth/metadata-var3 |
2025-11-25 |
PASS |
12/12 |
| auth/metadata-var2 |
2025-11-25 |
PASS |
12/12 |
| auth/metadata-var1 |
2025-11-25 |
PASS |
12/12 |
| auth/metadata-default |
2025-11-25 |
PASS |
12/12 |
| auth/basic-cimd |
2025-11-25 |
PASS |
12/12 |
| auth/token-endpoint-auth-post |
2026-07-28 |
PASS |
17/17 |
| auth/token-endpoint-auth-none |
2026-07-28 |
PASS |
17/17 |
| auth/token-endpoint-auth-basic |
2026-07-28 |
PASS |
17/17 |
| auth/scope-step-up |
2026-07-28 |
PASS |
25/25 |
| auth/scope-retry-limit |
2026-07-28 |
PASS |
27/27 |
| auth/scope-omitted-when-undefined |
2026-07-28 |
PASS |
13/13 |
| auth/scope-from-www-authenticate |
2026-07-28 |
PASS |
13/13 |
| auth/scope-from-scopes-supported |
2026-07-28 |
PASS |
13/13 |
| auth/resource-mismatch |
2026-07-28 |
PASS |
2/2 |
| auth/pre-registration |
2026-07-28 |
PASS |
11/11 |
| auth/offline-access-scope |
2026-07-28 |
PASS |
14/14 |
| auth/offline-access-not-supported |
2026-07-28 |
PASS |
13/13 |
| auth/metadata-var3 |
2026-07-28 |
PASS |
12/12 |
| auth/metadata-var2 |
2026-07-28 |
PASS |
12/12 |
| auth/metadata-var1 |
2026-07-28 |
PASS |
12/12 |
| auth/metadata-issuer-mismatch |
2026-07-28 |
PASS |
3/3 |
| auth/metadata-default |
2026-07-28 |
PASS |
12/12 |
| auth/iss-wrong-issuer |
2026-07-28 |
PASS |
8/8 |
| auth/iss-unexpected |
2026-07-28 |
PASS |
8/8 |
| auth/iss-supported-missing |
2026-07-28 |
PASS |
8/8 |
| auth/iss-supported |
2026-07-28 |
PASS |
13/13 |
| auth/iss-not-advertised |
2026-07-28 |
PASS |
13/13 |
| auth/iss-normalized |
2026-07-28 |
PASS |
8/8 |
| auth/basic-cimd |
2026-07-28 |
PASS |
11/11 |
| auth/authorization-server-migration |
2026-07-28 |
PASS |
26/26 |
Not scored (run for visibility)
14 additional runs cover extension and added-after-release scenarios, which are not part of the frozen requirement sets. The only failures are auth/dpop, auth/dpop-nonce, and auth/wif-jwt-bearer (at both revisions), all from unimplemented authorization extensions and all documented as the only entries in the conformance/expected_failures.yml client baseline. Extensions are not required for any tier per SEP-1730. The remaining not-scored runs pass, including json-schema-2020-12-preservation (9/9 at both revisions), auth/enterprise-managed-authorization, and both auth/client-credentials-* scenarios.
How to Reproduce
Both conformance legs run against the published conformance CLI with a plain checkout of
modelcontextprotocol/ruby-sdk at main.
Prerequisites: Node.js (for npx) and Ruby with bundle install completed (the SDK's own
conformance CI job uses Ruby 4.0). The numbers in this application were measured with
@modelcontextprotocol/conformance 0.2.0-alpha.11.
# Terminal 1, in the ruby-sdk checkout: start the conformance fixture server.
# One dual-era server serves every revision from the same /mcp endpoint.
bundle exec rake conformance_server
# Terminal 2: server leg, one run per frozen requirement set
npx @modelcontextprotocol/conformance@alpha server --url http://localhost:9292/mcp --requirements 2025-11-25
npx @modelcontextprotocol/conformance@alpha server --url http://localhost:9292/mcp --requirements 2026-07-28
# Client leg, one run per frozen requirement set (no fixture server needed;
# the CLI starts its own scenario servers). Run from the ruby-sdk checkout.
npx @modelcontextprotocol/conformance@alpha client --command "bundle exec ruby conformance/client.rb" --requirements 2025-11-25
npx @modelcontextprotocol/conformance@alpha client --command "bundle exec ruby conformance/client.rb" --requirements 2026-07-28
Each command exits 0 when every scored scenario of that revision's requirement set passes.
Scenarios the set runs without scoring (extensions, additions after the revision's anchor
release) are reported under a separate "Not scored" heading and never affect the exit code.
Append --expected-failures conformance/expected_failures.yml to also assert the recorded
baseline (its server list is empty; its client list carries only the three unimplemented
authorization extensions listed above).
Issue Triage Details
Analysis period: last 3 issues. Labels: all 12 required labels present (bug, enhancement, question, needs confirmation, needs repro, ready for work, good first issue, help wanted, P0, P1, P2, P3); none missing.
| Metric |
Value |
T1 Req |
T2 Req |
Verdict |
| Compliance rate |
100% (3/3) |
>= 90% |
>= 80% |
PASS |
| Median triage |
0h (p95: 0h) |
-- |
-- |
-- |
| Exceeding SLA |
0 |
-- |
-- |
-- |
| Open P0s |
0 (0 ever) |
0 |
0 |
PASS |
Documentation Coverage
46/48 PASS, 0 PARTIAL, 2 FAIL. Core features: 36/36 (100%). The prompt and resource list-changed notification examples were added by ruby-sdk#515. The only FAILs are #39/#40 legacy SSE transport, which is intentionally not implemented (see Question for the Working Group).
| # |
Feature |
Documented |
Examples |
Where |
Verdict |
| 1 |
Tools - listing |
Yes |
Yes |
README.md:83, 626-704 |
PASS |
| 2 |
Tools - calling |
Yes |
Yes |
README.md:84, 141-146, 2637-2640 |
PASS |
| 3 |
Tools - text results |
Yes |
Yes |
README.md:626-704 |
PASS |
| 4 |
Tools - image results |
Yes |
Yes |
README.md:933-949 |
PASS |
| 5 |
Tools - audio results |
Yes |
Yes |
README.md:933-959 |
PASS |
| 6 |
Tools - embedded resources |
Yes |
Yes |
README.md:962-978 |
PASS |
| 7 |
Tools - error handling |
Yes |
Yes |
README.md:907-931 |
PASS |
| 8 |
Tools - change notifications |
Yes |
Yes |
README.md:1598-1629, 2230-2232 |
PASS |
| 9 |
Resources - listing |
Yes |
Yes |
README.md:87, 1161-1246 |
PASS |
| 10 |
Resources - reading text |
Yes |
Yes |
README.md:1165-1275 |
PASS |
| 11 |
Resources - reading binary |
Yes |
Yes |
README.md:1277-1303 |
PASS |
| 12 |
Resources - templates |
Yes |
Yes |
README.md:1305-1403 |
PASS |
| 13 |
Resources - template reading |
Yes |
Yes |
README.md:1311-1344 |
PASS |
| 14 |
Resources - subscribing |
Yes |
Yes |
README.md:1491-1527 |
PASS |
| 15 |
Resources - unsubscribing |
Yes |
Yes |
README.md:1500-1519 |
PASS |
| 16 |
Resources - change notifications |
Yes |
Yes |
README.md:1598-1629, 2240-2244 (example added by ruby-sdk#515) |
PASS |
| 17 |
Prompts - listing |
Yes |
Yes |
README.md:980-1116 |
PASS |
| 18 |
Prompts - getting simple |
Yes |
Yes |
README.md:986-1116 |
PASS |
| 19 |
Prompts - getting with arguments |
Yes |
Yes |
README.md:993-1055 |
PASS |
| 20 |
Prompts - embedded resources |
Yes |
Yes |
README.md:1118-1159 |
PASS |
| 21 |
Prompts - image content |
Yes |
Yes |
README.md:1118-1159 |
PASS |
| 22 |
Prompts - change notifications |
Yes |
Yes |
README.md:1598-1629, 2234-2238 (example added by ruby-sdk#515) |
PASS |
| 23 |
Sampling |
Yes |
Yes |
README.md:1529-1596, 2734-2770 |
PASS |
| 24 |
Elicitation - form |
Yes |
Yes |
README.md:1982-2016 |
PASS |
| 25 |
Elicitation - URL |
Yes |
Yes |
README.md:2105-2141 |
PASS |
| 26 |
Elicitation - schema validation |
Yes |
Yes |
README.md:2013-2016 |
PASS |
| 27 |
Elicitation - defaults |
Yes |
Yes |
README.md:2018-2045, 2719-2726 |
PASS |
| 28 |
Elicitation - enums |
Yes |
Yes |
README.md:2018-2103 |
PASS |
| 29 |
Elicitation - complete notification |
Yes |
Yes |
README.md:2110-2123, 2273 |
PASS |
| 30 |
Roots - listing |
Yes |
Yes |
README.md:1405-1474 |
PASS |
| 31 |
Roots - change notifications |
Yes |
Yes |
README.md:1414, 1476-1484 |
PASS |
| 32 |
Logging - sending |
Yes |
Yes |
README.md:2143-2215 |
PASS |
| 33 |
Logging - level |
Yes |
Yes |
README.md:2164-2186 |
PASS |
| 34 |
Completions - resource |
Yes |
Yes |
README.md:1903-1947 |
PASS |
| 35 |
Completions - prompt |
Yes |
Yes |
README.md:1903-1947 |
PASS |
| 36 |
Ping |
Yes |
Yes |
README.md:1807-1851 |
PASS |
| 37 |
Streamable HTTP - client |
Yes |
Yes |
README.md:2652-2708 |
PASS |
| 38 |
Streamable HTTP - server |
Yes |
Yes |
README.md:148-241, 2217-2329 |
PASS |
| 39 |
SSE (legacy) - client |
No |
No |
Not implemented (intentional; declared in ROADMAP.md) |
FAIL |
| 40 |
SSE (legacy) - server |
No |
No |
Not implemented (intentional; declared in ROADMAP.md) |
FAIL |
| 41 |
stdio - client |
Yes |
Yes |
README.md:2602-2650 |
PASS |
| 42 |
stdio - server |
Yes |
Yes |
README.md:99-146 |
PASS |
| 43 |
Progress |
Yes |
Yes |
README.md:1853-1901, 2689-2697 |
PASS |
| 44 |
Cancellation |
Yes |
Yes |
README.md:1631-1805 |
PASS |
| 45 |
Pagination |
Yes |
Yes |
README.md:2331-2455 |
PASS |
| 46 |
Capability negotiation |
Yes |
Yes |
README.md:35, 291-314 |
PASS |
| 47 |
Protocol version negotiation |
Yes |
Yes |
README.md:579-603 (incl. the ruby-sdk#516 counter-offer), 2531-2564 |
PASS |
| 48 |
JSON Schema 2020-12 |
Yes |
Yes |
README.md:829-856 |
PASS |
Experimental features (informational, not counted): tasks get/result/cancel/list/status-notifications are not implemented (SEP-2663 extension, tracked in ruby-sdk#391).
Tier 1 (all non-experimental features documented with examples): strict FAIL on the two legacy-SSE rows only (#39/#40, intentionally not implemented). Every implemented feature (46/46) is documented with examples.
Tier 2 (basic docs covering core features): PASS, with core features at 36/36 (100%).
Policy Evaluation
1. Dependency Update Policy: PASS
- .github/dependabot.yml is a valid v2 configuration with a weekly schedule.
- Only the github-actions ecosystem is enrolled; bundler is not. Exposure is small: the gem has a single loosely-pinned runtime dependency, json_schemer >= 2.4.
2. Roadmap: PASS
- ROADMAP.md is substantive and explicitly frames itself as the path to SEP-1730 Tier 1.
- It was refreshed by ruby-sdk#519 (merged as commit ad73154, the audited state) and is consistent with the released SDK: it records the 2025-06-18, 2025-11-25, and 2026-07-28 revisions with all scored conformance scenarios passing, records the SEP-2575 lifecycle as shipped during 1.x (dual-era serving), and describes the shipped SEP-2577 deprecation warnings in the present tense. The content cross-checks against the v1.2.0 CHANGELOG entry.
3. Versioning Policy: PASS
- VERSIONING.md covers the versioning scheme, a breaking-change definition with documented exceptions (MCP spec-conformance fixes and security fixes), and how changes are communicated.
- The policy is actively exercised: the v1.2.0 CHANGELOG cites those documented exceptions.
| Policy Area |
Tier 1 |
Tier 2 |
| Dependency Update Policy |
PASS |
PASS |
| Roadmap |
PASS |
PASS |
| Versioning Policy |
PASS |
N/A |
Changes Since the Tier 2 Assessment (#3127)
| Area |
Tier 2 assessment (2026-07-25) |
This application (2026-08-15) |
| Server conformance |
100% (30/30, 2025-06-18 + 2025-11-25 suite) |
100% (67/67 across the frozen 2025-11-25 and 2026-07-28 requirement sets) |
| Client conformance |
100% (24/24, then-current suite) |
100% (50/50 across both frozen sets) |
| Spec revisions implemented |
2025-06-18, 2025-11-25 |
Plus 2026-07-28 in full: SEP-2575 dual-era lifecycle including server/discover and subscriptions/listen, SEP-2322 MRTR (server, client, and legacy shim), SEP-2549 cache hints, SEP-2243 standard and custom headers (ruby-sdk PRs #475 through #516) |
| Documentation |
34/48 PASS (5 PARTIAL, 9 FAIL) |
46/48 PASS (0 PARTIAL; only the two legacy-SSE rows remain) |
| Stable release |
v1.0.0 (2026-07-24) |
v1.2.0 (2026-08-15) |
| Spec tracking |
46 days (2025-11-25 revision) |
4 days (2026-07-28 revision; completed in 18 days) |
| Deprecations |
-- |
SEP-2577 deprecation warnings shipped (ruby-sdk#406) |
| Security response |
-- |
GHSA-4m5j-jjfc-97gx (medium) published 2026-08-15 with the patch shipped in v1.2.0 the same day; below the SEP-1730 P0 threshold, and demonstrates the security-response process |
| Scoring methodology |
Moving suite (latest scenarios at audit time) |
Frozen per-revision requirement sets, each run at that revision's own wire version (stricter) |
Remaining Items
- The working-group documentation-scoping question above (legacy SSE transport, features Fix doc example of embedding resources #39/roots/list should not be marked as a client request #40).
- Formalizing the per-release implementation timeline agreement (Tier 1 requirement 4b), proposed in the Tier Determination section.
Nothing else is outstanding: both conformance suites pass 100% of scored scenarios with a clean server baseline, no P0 has ever been filed, and all three policies pass at the Tier 1 standard.
cc @felixweinberger @pcarleton
MCP SDK Tier Audit: modelcontextprotocol/ruby-sdk
SDK: modelcontextprotocol/ruby-sdk
Date: 2026-08-15
Branch: main (commit ad73154, v1.2.0 released 2026-08-15)
Requested tier: Tier 1
Requirements revisions scored: 2025-11-25 and 2026-07-28 (frozen requirement sets, each run at that revision's own wire version, per @modelcontextprotocol/conformance 0.2.0-alpha.11)
Auditor: mcp-sdk-tier-audit skill (tier-check CLI + subagent evaluation)
Previous assessments: Tier 2 (#3127, 2026-07-25); Tier 3 (#2340, 2026-03-03)
Tier Assessment
The Ruby SDK meets every Tier 1 requirement that the deterministic scorecard can measure. Server conformance is 100% (67/67) and client conformance is 100% (50/50) across both frozen requirement sets (2025-11-25 and 2026-07-28), each run at that revision's own wire version. Issue triage compliance is 100% with all 12 required labels present, no P0 has ever been filed, the stable release line is at v1.2.0, the 2026-07-28 spec revision was picked up 4 days after its release (and completed in v1.2.0, 18 days after the spec), and all three required policies (dependency updates, roadmap, versioning) are published and pass. The one item that requires working-group interpretation rather than measurement is the documentation requirement's treatment of the legacy SSE transport (features #39/#40), which the SDK intentionally does not implement: every implemented feature (46/46) is documented with examples. This application requests Tier 1 and poses that question explicitly in Question for the Working Group.
Requirements Summary
Tier Determination
Question for the Working Group
The legacy SSE transport (the 2024-11-05 HTTP+SSE transport) is intentionally not implemented in the Ruby SDK. It was replaced by Streamable HTTP in spec revision 2025-03-26, and the SDK's stable line (v1.0.0, released 2026-07-24) postdates that replacement, so there is no migration constituency to serve. The omission is declared out of scope in ROADMAP.md. TypeScript SDK v2 points the same direction: the SSE server transport was removed from its supported packages and survives only in the frozen, deprecated @modelcontextprotocol/server-legacy migration package (planned for removal in v3), and its client transport is deprecated.
Does the Tier 1 documentation requirement ("comprehensive with examples for all features") scope to implemented features, or otherwise exempt the superseded transport? If yes, the SDK meets Tier 1 in full: the two legacy-SSE rows are the only strict-count misses anywhere in this application, and every implemented feature (46/46) is documented with examples.
Server Conformance Details
Pass rate: 100% (67/67 scored). Revision 2025-11-25: 30/30; revision 2026-07-28: 37/37. The baseline conformance/expected_failures.yml has an empty server list: no known server conformance failures.
Scored - revision 2025-11-25 (30/30)
Scored - revision 2026-07-28 (37/37)
Not scored (run for visibility)
16 additional runs are not part of the frozen requirement sets and are not scored: 10 tasks-* scenarios exercise the SEP-2663 tasks extension, which the SDK intentionally does not implement (tracked in ruby-sdk#391); the remainder are pending scenarios (server-sse-polling, json-schema-2020-12 at the 2026-07-28 wire, http-header-validation, http-custom-header-server-validation) or scenarios added after the revision's release (server-session-lifecycle). Of these, server-session-lifecycle (3/3), json-schema-2020-12 at the 2025-11-25 wire (5/5), and http-header-validation (14/14) pass.
Client Conformance Details
Full suite pass rate: 100% (50/50 scored). Revision 2025-11-25: 18/18; revision 2026-07-28: 32/32. Suite breakdown: Core 11/11 (100%), Auth 39/39 (100%). The http-standard-headers scenario passes 9/9 following the conformance-driver fix in ruby-sdk#514, merged before v1.2.0.
Core Scenarios
Auth Scenarios (scored)
Not scored (run for visibility)
14 additional runs cover extension and added-after-release scenarios, which are not part of the frozen requirement sets. The only failures are auth/dpop, auth/dpop-nonce, and auth/wif-jwt-bearer (at both revisions), all from unimplemented authorization extensions and all documented as the only entries in the conformance/expected_failures.yml client baseline. Extensions are not required for any tier per SEP-1730. The remaining not-scored runs pass, including json-schema-2020-12-preservation (9/9 at both revisions), auth/enterprise-managed-authorization, and both auth/client-credentials-* scenarios.
How to Reproduce
Both conformance legs run against the published conformance CLI with a plain checkout of
modelcontextprotocol/ruby-sdk at main.
Prerequisites: Node.js (for npx) and Ruby with bundle install completed (the SDK's own
conformance CI job uses Ruby 4.0). The numbers in this application were measured with
@modelcontextprotocol/conformance 0.2.0-alpha.11.
Each command exits 0 when every scored scenario of that revision's requirement set passes.
Scenarios the set runs without scoring (extensions, additions after the revision's anchor
release) are reported under a separate "Not scored" heading and never affect the exit code.
Append --expected-failures conformance/expected_failures.yml to also assert the recorded
baseline (its server list is empty; its client list carries only the three unimplemented
authorization extensions listed above).
Issue Triage Details
Analysis period: last 3 issues. Labels: all 12 required labels present (bug, enhancement, question, needs confirmation, needs repro, ready for work, good first issue, help wanted, P0, P1, P2, P3); none missing.
Documentation Coverage
46/48 PASS, 0 PARTIAL, 2 FAIL. Core features: 36/36 (100%). The prompt and resource list-changed notification examples were added by ruby-sdk#515. The only FAILs are #39/#40 legacy SSE transport, which is intentionally not implemented (see Question for the Working Group).
Experimental features (informational, not counted): tasks get/result/cancel/list/status-notifications are not implemented (SEP-2663 extension, tracked in ruby-sdk#391).
Tier 1 (all non-experimental features documented with examples): strict FAIL on the two legacy-SSE rows only (#39/#40, intentionally not implemented). Every implemented feature (46/46) is documented with examples.
Tier 2 (basic docs covering core features): PASS, with core features at 36/36 (100%).
Policy Evaluation
1. Dependency Update Policy: PASS
2. Roadmap: PASS
3. Versioning Policy: PASS
Changes Since the Tier 2 Assessment (#3127)
Remaining Items
Nothing else is outstanding: both conformance suites pass 100% of scored scenarios with a clean server baseline, no P0 has ever been filed, and all three policies pass at the Tier 1 standard.
cc @felixweinberger @pcarleton