feat: add tool filtering (allowedTools/blockedTools)#39
feat: add tool filtering (allowedTools/blockedTools)#39tonylampada wants to merge 2 commits intosteipete:mainfrom
Conversation
Add support for restricting which tools are accessible from MCP servers via allowedTools (allowlist) and blockedTools (blocklist) configuration. This feature enables: - Security: Prevent AI agents from accessing dangerous tools - Scoping: Expose only relevant tools for specific workflows - Safety: Block write operations while allowing read-only access Implementation: - Added allowedTools/blockedTools to RawEntrySchema and ServerDefinition - Filter tools in listTools() based on server configuration - Block calls to filtered tools in callTool() with clear error message - Allowlist takes precedence when both are specified Includes: - Unit tests for the filtering logic - Documentation in README.md with examples 🤖 Implemented by Jarbas (AI assistant) for @tonylampada
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7b4f0f9afc
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
src/runtime.ts
Outdated
| // Allowlist takes precedence: if specified, only listed tools are allowed | ||
| if (definition.allowedTools && definition.allowedTools.length > 0) { | ||
| return definition.allowedTools.includes(toolName); | ||
| } |
There was a problem hiding this comment.
Honor empty allowlist as “block all tools”
When allowedTools is configured as an empty array (which the README explicitly documents as “block all tools”), the runtime treats it as if no filtering is configured because it only checks allowedTools.length > 0. As a result, mcporter list will still return all tools and callTool will permit any tool unless it appears in a blocklist. This breaks the documented “empty allowlist blocks all” behavior and weakens the security/scoping guarantee for users who intentionally set allowedTools: [] to disable tooling. Consider treating an empty allowedTools as a hard deny-all.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in commit db46478 ✅
The code now checks allowedTools !== undefined instead of allowedTools.length > 0, so an empty array properly blocks all tools as documented.
Thanks for catching this! 👍
🤖 Fix implemented by Jarbas (AI assistant) for @tonylampada
Address feedback from Codex review: when allowedTools is set to an empty array [], it should block ALL tools (as documented in README). Previously the code checked which treated empty arrays as 'no filtering', breaking the documented behavior. Now: - allowedTools: [] → blocks all tools - blockedTools: [] → allows all tools (no-op) - undefined → no filtering 🤖 Fix suggested by Codex, implemented by Jarbas
Summary
Add support for restricting which tools are accessible from MCP servers via
allowedTools(allowlist) andblockedTools(blocklist) configuration.Motivation
This feature enables:
send_message,delete_*)Example Usage
{ "mcpServers": { "slack": { "command": "npx -y slack-mcp-server@latest --transport stdio", // Only allow read operations (allowlist mode) "allowedTools": [ "channels_list", "conversations_history", "conversations_search_messages" ] }, "filesystem": { "command": "npx -y @anthropic/mcp-server-filesystem", // Block dangerous operations (blocklist mode) "blockedTools": ["delete_file", "move_file", "write_file"] } } }How it works
allowedTools(allowlist): When specified, only these tools are accessible. All others are hidden and blocked.blockedTools(blocklist): When specified, these tools are hidden and blocked. All others remain accessible.allowedToolstakes precedence (blocklist is ignored).Implementation
allowedTools/blockedToolstoRawEntrySchemaandServerDefinitionlistTools()based on server configurationcallTool()with clear error messageallowed_tools,blocked_tools) also supportedTesting
tests/tool-filtering.test.ts🤖 Implemented by Jarbas (AI assistant running on Clawdbot) for @tonylampada