Skip to content

[BUG] tool_blocklist in agent.toml not filtering MCP tools from LLM context #666

@Abhishek21k

Description

@Abhishek21k

Bug

tool_blocklist in agent.toml does not prevent MCP tools from being presented to the LLM or executed. The agent can still call blocked tools successfully.

Steps to Reproduce

  1. Configure the ops agent with a tool_blocklist for Notion write tools:
# agents/ops/agent.toml
tool_blocklist = [
  "mcp_notion_api_patch_block_children",
  "mcp_notion_api_patch_page",
  "mcp_notion_api_post_page",
  "mcp_notion_api_delete_block",
]

[capabilities]
tools = ["*"]
  1. Restart the daemon
  2. Ask the ops agent to write to a Notion page
  3. The agent successfully calls mcp_notion_api_patch_block_children — the blocklist is ignored

Expected Behavior

  • Blocked tools should be removed from the tool definitions sent to the LLM (so it doesn't even know they exist)
  • If somehow called, blocked tools should return a permission denied error

Actual Behavior

  • The LLM still sees all Notion tools including write tools
  • The agent successfully executes mcp_notion_api_patch_block_children

Investigation

The filtering logic in kernel.rs available_tools() (line ~4891) looks correct:

if !tool_blocklist.is_empty() {
    all_tools.retain(|t| !tool_blocklist.iter().any(|b| b == &t.name));
}

Possible causes:

  1. TOML parsing issue: tool_blocklist placed after [capabilities] gets parsed as capabilities.tool_blocklist (swallowed by serde #[serde(default)]). Moving it before [capabilities] didn't help either — the field may not be loading from agent.toml at all.
  2. Agent manifest loading: The tool_blocklist field may not be deserialized from the on-disk agent.toml during agent registration/spawn. Need to verify the manifest loading path actually reads this field.
  3. MCP tool name mismatch: The actual MCP tool names at runtime may differ from what's in the blocklist. Need a way to inspect the exact tool names the MCP server registers.

Suggested Fix

  • Add debug logging in available_tools() to log the blocklist and which tools get filtered
  • Verify tool_blocklist round-trips through agent.toml → manifest deserialization
  • Consider adding GET /api/agents/{id}/available-tools endpoint that returns the post-filtered tool list (not just the config)

Environment

  • Branch: fix/all-tools-integration
  • Notion MCP: @notionhq/notion-mcp-server@2.2.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions