Skip to content

feat(mcp-chat): implement tool-level filtering using plugin configuration#8376

Open
MattiaDellOca wants to merge 6 commits intobackstage:mainfrom
MattiaDellOca:main
Open

feat(mcp-chat): implement tool-level filtering using plugin configuration#8376
MattiaDellOca wants to merge 6 commits intobackstage:mainfrom
MattiaDellOca:main

Conversation

@MattiaDellOca
Copy link
Copy Markdown

Hey, I just made a Pull Request!

Addresses #8307.

This PR allows an admin to disable specific tools from a MCP Server when using the mcp-chat plugin.

Example configuration:

mcpChat:
  mcpServers:
    - id: kubernetes-server
      name: Kubernetes Server
      npxCommand: 'kubernetes-mcp-server@latest'
      env:
        KUBECONFIG: ${KUBECONFIG}
      disabledTools:
        - 'pods_delete'
        - 'pods_exec'

✔️ Checklist

  • A changeset describing the change and affected packages. (more info)
  • Added or updated documentation
  • Tests for new functionality and regression tests for bug fixes
  • Screenshots attached (for UI changes)
  • All your commits have a Signed-off-by line in the message. (more info)

@backstage-goalie
Copy link
Copy Markdown
Contributor

Changed Packages

Package Name Package Path Changeset Bump Current Version
@backstage-community/plugin-mcp-chat-backend workspaces/mcp-chat/plugins/mcp-chat-backend minor v0.8.0

Copy link
Copy Markdown
Contributor

@Lucifergene Lucifergene left a comment

Choose a reason for hiding this comment

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

Hey @MattiaDellOca, this is looking really good. The core implementation lines up well with what we discussed. I especially like the eager filtering via filterDiscoveredTools being shared across both branches, and the docs/changeset are nicely done too.

A few things I’d suggest tightening up before we merge:

1. allowedTools on the public MCPServerConfig type

Right now allowedTools is part of MCPServerConfig, which is marked @public and shows up in report.api.md. The tricky part is that this field is computed at runtime (after listTools()), not something an admin would configure.

Having it on the public type makes it look like it belongs in app-config.yaml, which could be confusing.

I’d suggest moving it off the public config. A few ways you could approach it:

  • Introduce an internal/runtime type that extends MCPServerConfig
  • Mark it as @internal so it doesn’t leak into the API report
  • Or avoid mutating the config object and pass it via something like a Map<serverId, string[]>

disabledTools is totally fine where it is since that’s real user config.

2. allowed_tools sent even when nothing is actually disabled

In filterDiscoveredTools, the current logic is:

allowedTools: disabledTools.length > 0
  ? enabledToolsList.map(t => t.name)
  : undefined,

If someone sets something like disabledTools: ['typo_tool'] and nothing matches, we still end up sending allowed_tools with the full list. Not harmful, but a bit unnecessary and slightly off from the intent.

It would be better to gate this on actuallyDisabled.length > 0 instead.

3. A couple of test gaps

The main paths are covered well already. A few edge cases that might be worth adding:

  • disabledTools: [] should behave the same as no config
  • All tools disabled for a server: what does that look like in practice? empty list, server still “connected”, etc.
  • HTTP transport with a Chat Completions provider (right now tests seem focused on STDIO + Responses)

Not blockers, just things that would make the test coverage more complete.

Minor nits (optional)

  • The warning for invalid tool names logs the full discovered list. On larger servers that could get noisy. Maybe cap it or just log a count.
  • If there are duplicates in disabledTools, the logs will repeat them. Converting to a Set early would clean that up.

Overall, this is in great shape. Once the allowedTools API exposure and the gating condition are cleaned up, I think we’re good to merge 👍

@Lucifergene Lucifergene self-assigned this Apr 3, 2026
…rface and improve disabledTools validation

Signed-off-by: Mattia Dell'Oca <mattia.delloca@supsi.ch>
@MattiaDellOca
Copy link
Copy Markdown
Author

Hey @Lucifergene,
thank you for the detailed feedback, it was very useful!
When you have time, let me know what you think of my changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants