Skip to content

fix(server): honor disable() on resource templates across list, read and completion requests - #2697

Open
Grit03 wants to merge 9 commits into
modelcontextprotocol:mainfrom
Grit03:fix/2696-resource-template-disable-ignored
Open

fix(server): honor disable() on resource templates across list, read and completion requests#2697
Grit03 wants to merge 9 commits into
modelcontextprotocol:mainfrom
Grit03:fix/2696-resource-template-disable-ignored

Conversation

@Grit03

@Grit03 Grit03 commented Aug 21, 2026

Copy link
Copy Markdown

Motivation and Context

Tools, prompts, resources and resource templates registered on McpServer can all be toggled with enable()/disable(). A disabled one drops out of its list verb and is rejected when invoked.

Resource templates are the exception. RegisteredResourceTemplate has the enabled field and disable() does flip it, but none of these four handlers read it.

resources/list      : ["demo://users/1"]                                // expected []
templates/list      : ["demo://users/{id}"]                             // expected []
read demo://users/1 : { uri: "demo://users/1", text: "profile of 1" }   // expected a throw
complete {id}       : ["1","2","3"]                                     // expected a throw

As a result, a disabled resource template is still exposed in the four responses above.

In order to fix, the missing enabled check at all four sites, in two shapes:

  • resources/list and resources/templates/list filter disabled templates out. Nothing was addressed specifically, so there is nobody to report a failure to.
  • resources/read and completion/complete throw ProtocolError(InvalidParams), since the client named a specific resource template.

How Has This Been Tested?

Four tests in test/integration/test/server/mcp.test.ts, one per request path, each committed ahead of its fix so it can be checked red → green.

  • resources/list: a disabled static resource and a disabled template drop out, the enabled template stays
  • resources/templates/list: the disabled template's URI pattern is gone
  • resources/read: a URI matching a disabled template is rejected with InvalidParams + disabled
  • completion/complete: a completion aimed at a disabled template is rejected the same way

The first testcase(resources/list) also covers the static-resource filtering. That already worked, but it sits in the same handler as the template path, so pinning it down keeps a fix on one side from breaking the other.

  • pnpm --filter @modelcontextprotocol/test-integration exec vitest run test/server/mcp.test.ts
  • pnpm check:all

Breaking Changes

No API change.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

For completion/complete I went with throwing, following the disabled prompt case. The branch below in the same handler returns EMPTY_COMPLETION_RESULT for static resources.

If that's the better fit here, I'm happy to change it. Let me know.

if (!template) {
    if (this._registeredResources[ref.uri]) {
        // Attempting to autocomplete a fixed resource URI is not an error in the spec (but probably should be).
        return EMPTY_COMPLETION_RESULT;
    }

    throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Resource template ${request.params.ref.uri} not found`);
}

fixes: #2696

@pkg-pr-new

pkg-pr-new Bot commented Aug 21, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/@modelcontextprotocol/client@2697

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/@modelcontextprotocol/codemod@2697

@modelcontextprotocol/core

npm i https://pkg.pr.new/@modelcontextprotocol/core@2697

@modelcontextprotocol/server

npm i https://pkg.pr.new/@modelcontextprotocol/server@2697

@modelcontextprotocol/server-legacy

npm i https://pkg.pr.new/@modelcontextprotocol/server-legacy@2697

@modelcontextprotocol/express

npm i https://pkg.pr.new/@modelcontextprotocol/express@2697

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/@modelcontextprotocol/fastify@2697

@modelcontextprotocol/hono

npm i https://pkg.pr.new/@modelcontextprotocol/hono@2697

@modelcontextprotocol/node

npm i https://pkg.pr.new/@modelcontextprotocol/node@2697

commit: cd3d9e1

@changeset-bot

changeset-bot Bot commented Aug 21, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cd3d9e1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@modelcontextprotocol/server Patch
@modelcontextprotocol/core Patch
@modelcontextprotocol/client Patch
@modelcontextprotocol/server-legacy Patch
@modelcontextprotocol/codemod Patch
@modelcontextprotocol/core-internal Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@Grit03 Grit03 changed the title fix(server): honor disable() on resource templates across list, read and completion fix(server): honor disable() on resource templates across list, read and completion requests Aug 21, 2026
@Grit03
Grit03 marked this pull request as ready for review August 21, 2026 14:13
@Grit03
Grit03 requested a review from a team as a code owner August 21, 2026 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v2] disable() has no effect on resource templates

1 participant