Skip to content

feat(mcp): implement resources/templates/list as static empty catalog#2828

Merged
YellowSnnowmann merged 1 commit into
tinyhumansai:mainfrom
obchain:feat/mcp-resources-templates-list
May 28, 2026
Merged

feat(mcp): implement resources/templates/list as static empty catalog#2828
YellowSnnowmann merged 1 commit into
tinyhumansai:mainfrom
obchain:feat/mcp-resources-templates-list

Conversation

@obchain
Copy link
Copy Markdown
Contributor

@obchain obchain commented May 28, 2026

Summary

  • Adds resources/templates/list handler to the MCP stdio + HTTP server, returning { "resourceTemplates": [] } because the bundled prompt catalog is fully static (every URI is concrete).
  • Tolerates unknown / cursor params on the request - extra fields do not force a -32602 Invalid params.
  • Capability block stays unchanged (resources: { subscribe: false, listChanged: false }); only the handler dispatch surface grows.
  • Adds 3 new tests (1 pure helper, 2 wire-through via handle_json_value) and a new coverage matrix row 11.1.8.
  • Updates gitbooks/developing/mcp-server.md (and the zh-CN mirror) with a Resource Templates note and extends the smoke-test snippet.

Problem

The initialize block already advertises the resources capability (#2745). MCP clients that see that capability are invited by the spec to probe resources/templates/list. Today the server replies:

{ "error": { "code": -32601, "message": "Method not found", "data": "unsupported MCP method `resources/templates/list`" } }

Compliant clients (Claude Desktop, Cursor, Zed) treat the -32601 as a graceful fallback but log it as a spec violation, polluting their debug surfaces and signalling an incomplete server. The catalog has no templated URIs so the correct response is an empty array.

Solution

  • src/openhuman/mcp_server/resources.rs gains pub fn list_resource_templates_result() -> Value returning json!({ "resourceTemplates": [] }). Pure, no I/O.
  • src/openhuman/mcp_server/protocol.rs adds a "resources/templates/list" match arm that calls the new helper and a log::debug! trace mirroring the existing resources handlers.
  • Cursor / extra params are accepted and ignored - the spec allows the field, and the static catalog means pagination is a no-op.

Verified end-to-end against the built openhuman-core binary:

$ printf '%s\n' \
    '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
    '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
    '{"jsonrpc":"2.0","id":2,"method":"resources/templates/list"}' \
    '{"jsonrpc":"2.0","id":3,"method":"resources/templates/list","params":{"cursor":"ignored"}}' \
  | ./target/debug/openhuman-core mcp
{"id":1,...}
{"id":2,"jsonrpc":"2.0","result":{"resourceTemplates":[]}}
{"id":3,"jsonrpc":"2.0","result":{"resourceTemplates":[]}}

Submission Checklist

If a section does not apply to this change, mark the item as N/A with a one-line reason. Do not delete items.

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy - 1 helper unit test + 2 wire-through tests (bare + cursor-param tolerance).
  • Diff coverage >= 80% - changed lines (Vitest + cargo-llvm-cov merged via diff-cover) meet the gate enforced by .github/workflows/coverage.yml. All new Rust lines are exercised by the new tests.
  • Coverage matrix updated - added row 11.1.8 in docs/TEST-COVERAGE-MATRIX.md.
  • All affected feature IDs from the matrix are listed in the PR description under ## Related - 11.1.8.
  • No new external network dependencies introduced (mock backend used per Testing Strategy) - pure in-process Rust, no network.
  • Manual smoke checklist updated if this touches release-cut surfaces (docs/RELEASE-MANUAL-SMOKE.md) - N/A: MCP stdio surface only, no release-cut user-facing path; mcp-server.md smoke snippet updated instead.
  • Linked issue closed via Closes #NNN in the ## Related section - Closes MCP server returns -32601 for resources/templates/list #2826.

Impact

  • Runtime: desktop (in-process MCP server) + any external MCP client that connects to openhuman-core mcp. No mobile/web/CLI behaviour change.
  • Performance: handler is a single json! literal returning an empty array; negligible.
  • Security: no new attack surface - method exists in the MCP spec and returns no data.
  • Compatibility: pure addition. Clients that never call resources/templates/list see no change.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Keep this section for AI-authored PRs. For human-only PRs, mark each field N/A.

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: feat/mcp-resources-templates-list
  • Commit SHA: 95f25985b4b3639fa7d284674b7161f4fd555468

Validation Run

  • pnpm --filter openhuman-app format:check - N/A: no app/ files changed.
  • pnpm typecheck - N/A: no TypeScript files changed.
  • Focused tests: cargo test --lib openhuman::mcp_server -> 109 passed / 0 failed (3 new); cargo test --lib list_resource_templates_returns_empty + cargo test --lib templates_list green.
  • Rust fmt/check (if changed): cargo check --manifest-path Cargo.toml clean.
  • Tauri fmt/check (if changed): N/A: no app/src-tauri/ files changed.

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: resources/templates/list returns {resourceTemplates: []} instead of -32601 Method not found.
  • User-visible effect: external MCP clients (Claude Desktop, Cursor, Zed) get a spec-compliant response when probing the catalog; no end-user-facing UI surface in OpenHuman itself.

Parity Contract

  • Legacy behavior preserved: the unimplemented-method default arm still returns -32601 for every other unknown method; only the named arm is added.
  • Guard/fallback/dispatch parity checks: the new arm uses the same success_response(id, ...) + log::debug! shape as the sibling resources/list and resources/read arms.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): none.
  • Canonical PR: this one.
  • Resolution (closed/superseded/updated): N/A.

Summary by CodeRabbit

  • New Features

    • Added support for the resources/templates/list MCP method, which returns the server's resource template catalog (currently empty).
  • Documentation

    • Documented that the resource template catalog is static and always empty.
    • Updated smoke test examples to include the new method call.
  • Tests

    • Added test coverage for the new MCP method, verifying it returns an empty catalog and ignores unknown parameters.

Review Change Stack

Compliant MCP clients probe resources/templates/list whenever the
resources capability is advertised. The current catalog is fully
static, so the spec-compliant response is an empty array. Without
the handler the server returns -32601 and pollutes client debug
surfaces.

Fixes tinyhumansai#2826
@obchain obchain requested a review from a team May 28, 2026 08:33
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4e0a1519-ea19-4ebe-85d1-d1d9b7d4b1c0

📥 Commits

Reviewing files that changed from the base of the PR and between 145e768 and 95f2598.

📒 Files selected for processing (5)
  • docs/TEST-COVERAGE-MATRIX.md
  • gitbooks/developing/mcp-server.md
  • gitbooks/developing/mcp-server.zh-CN.md
  • src/openhuman/mcp_server/protocol.rs
  • src/openhuman/mcp_server/resources.rs

📝 Walkthrough

Walkthrough

This PR implements the missing resources/templates/list MCP method to return an empty resourceTemplates array (reflecting a fully static catalog). The method is wired through the JSON-RPC dispatcher with handler tests, integration tests, and comprehensive documentation updates across English, Chinese, and test coverage matrix.

Changes

Resource Templates List Handler

Layer / File(s) Summary
Resource templates handler implementation
src/openhuman/mcp_server/resources.rs
New list_resource_templates_result() function returns {resourceTemplates: []} with a unit test verifying the JSON array shape and empty state.
JSON-RPC dispatcher wiring and integration tests
src/openhuman/mcp_server/protocol.rs
Routes resources/templates/list through handle_request, logs the call, and includes integration tests verifying the response shape and tolerance of unknown params.
Documentation and test coverage matrix
docs/TEST-COVERAGE-MATRIX.md, gitbooks/developing/mcp-server.md, gitbooks/developing/mcp-server.zh-CN.md
Adds explanation of static resource templates, updates smoke-test examples with the new method call, and documents coverage in the matrix.

Sequence Diagram

sequenceDiagram
  participant Client
  participant handle_request
  participant list_resource_templates_result
  Client->>handle_request: JSON-RPC resources/templates/list
  handle_request->>list_resource_templates_result: route to handler
  list_resource_templates_result->>list_resource_templates_result: return {resourceTemplates: []}
  handle_request->>Client: success response
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • tinyhumansai/openhuman#2745: Landed resources/list and resources/read methods to the same handle_request JSON-RPC dispatcher; this PR extends that surface with resources/templates/list.
  • tinyhumansai/openhuman#1760: Added baseline MCP method dispatch handling in protocol.rs; this PR adds an additional resource-discovery method to that dispatcher.

Suggested labels

feature, working

Suggested reviewers

  • senamakel

Poem

🐰 A hollow request flies through the wire,
templates/list returns naught but [] to inspire—
Static resources, no schemes to unfold,
Yet specs now kept, and clients consoled! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: implementing the resources/templates/list MCP method as a static empty catalog.
Linked Issues check ✅ Passed All acceptance criteria from issue #2826 are met: resources/templates/list returns {resourceTemplates: []}, unknown/cursor params are tolerated, unit and wire-through tests are added, docs are updated, and diff coverage requirements are satisfied.
Out of Scope Changes check ✅ Passed All changes directly support the implementation of resources/templates/list as specified in #2826; no unrelated modifications are present.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added feature Net-new user-facing capability or product behavior. working A PR that is being worked on by the team. labels May 28, 2026
Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean, well-scoped fix. This is exactly what a spec-compliance stub should look like.

The new arm follows the same dispatch shape as resources/list and resources/read — consistent logging prefix, success_response wrapper, delegate to a pure helper. list_resource_templates_result() is correctly side-effect-free aside from the debug trace. Three tests cover the helper directly, the bare wire-through, and the cursor-param tolerance case — all the acceptance criteria from #2826 are hit.

One minor observation worth noting: list_resource_templates_result() emits its own log::debug! trace from inside the helper, while the dispatch arm in protocol.rs already logs the request entry. That means every resources/templates/list call produces two debug lines. For the sibling resources/list handler the count is dynamic so the helper-level trace carries information; here it will always print count=0. Not a blocker — debug noise only — but worth cleaning up in a follow-up if log verbosity becomes a concern.

Docs are thorough: English + zh-CN both updated, coverage matrix row added, smoke snippet exercises the new method. Nothing left loose.

Approved.

@YellowSnnowmann YellowSnnowmann merged commit f345f54 into tinyhumansai:main May 28, 2026
35 of 38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Net-new user-facing capability or product behavior. working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP server returns -32601 for resources/templates/list

3 participants