Skip to content

feat(mcp): opt-in group-based tool gating#254

Merged
jacob-bd merged 2 commits into
jacob-bd:mainfrom
KoscheiiB:feat/tool-group-gating
Jul 10, 2026
Merged

feat(mcp): opt-in group-based tool gating#254
jacob-bd merged 2 commits into
jacob-bd:mainfrom
KoscheiiB:feat/tool-group-gating

Conversation

@KoscheiiB

Copy link
Copy Markdown
Contributor

feat(mcp): opt-in group-based tool gating

Summary

Adds an optional way to hide MCP tools by group or by name through
environment variables, so a client can expose only the subset it needs
and save context. Gating is opt-in: with no configuration every tool
stays visible and current behavior is unchanged.

Motivation

The README already carries a context-window warning: "This MCP provides
39 tools. Disable it when not using NotebookLM to preserve context."
Today the only lever is all-or-nothing (toggle the whole server off with
@notebooklm-mcp). A query-first client that wants the read and chat
tools but not the studio, research, or management tools has no way to
trim the set without editing code.

This change gives that lever without changing the default for anyone.

What changed

  • src/notebooklm_tools/mcp/tool_groups.py (new): a read/manage taxonomy
    mapping every registered tool into exactly one named group, plus the
    resolution logic and an apply(mcp) entry point.
  • src/notebooklm_tools/mcp/server.py: calls tool_groups.apply(mcp)
    once at the end of _register_tools(), after all tools are registered.
  • tests/test_tool_groups.py (new): unit tests for env resolution,
    precedence, the no-op path, and taxonomy disjointness.
  • README.md, docs/MCP_GUIDE.md: document the three environment
    variables and add a "Selective tool exposure" section with examples
    and the full group list.

Behavior

Three environment variables, resolved in this order (later wins for a
given tool):

  1. NOTEBOOKLM_DISABLED_GROUPS: comma-separated group names to hide.
  2. NOTEBOOKLM_DISABLED_TOOLS: comma-separated single tool names to hide.
  3. NOTEBOOKLM_ENABLED_TOOLS: comma-separated tool names to re-enable,
    overriding the two above.

Tools are hidden through FastMCP's visibility transform
(mcp.local_provider.disable(names=...)), so nothing is unregistered,
only hidden. Unknown group names are ignored. With none of the variables
set, apply() is a no-op and all 39 tools remain visible.

Usage

# Query-first setup: hide mutating groups, keep read + chat tools
export NOTEBOOKLM_DISABLED_GROUPS="notebooks_manage,sources_manage,studio,research,sharing,notes"

# Hide one extra tool, but keep studio_status from an otherwise-hidden group
export NOTEBOOKLM_DISABLED_TOOLS="tag"
export NOTEBOOKLM_ENABLED_TOOLS="studio_status"

Testing

  • uv run pytest tests/test_tool_groups.py: 9 new tests pass.
  • Full suite: no regressions from this change (one unrelated failure in
    tests/services/test_sources.py exists on main before this branch;
    reported separately, not touched here).
  • uv run ruff check . and uv run ruff format --check .: clean.
  • Manual MCP verification: started the server and listed tools through
    the client. With no env vars set, 39 tools are visible. With
    NOTEBOOKLM_DISABLED_GROUPS set to the six manage/studio/research/etc.
    groups, the client-facing list drops to the read and chat core with no
    disabled tool leaking through.

This feature does not call the NotebookLM API; it only changes which
already-registered tools are advertised to the MCP client. There is no
CLI surface for it.

Notes

  • No version bump (leaving versioning to the maintainer).
  • No new dependencies (standard library only).
  • Additive and opt-in: existing deployments see no change unless they set
    one of the new variables.

KoscheiiB added 2 commits July 9, 2026 20:03
The server registers 39 tools; clients that only need a subset can now
hide whole groups or individual tools via NOTEBOOKLM_DISABLED_GROUPS,
NOTEBOOKLM_DISABLED_TOOLS, and NOTEBOOKLM_ENABLED_TOOLS. Gating is
opt-in: with no configuration every tool stays visible, so existing
behavior is unchanged. Tools are hidden through FastMCP's visibility
transform rather than unregistered.
Add the three gating environment variables to the MCP guide and a
"Selective tool exposure" section with examples and the group list;
link to it from the README context-window warning.
@jacob-bd jacob-bd merged commit edb53ba into jacob-bd:main Jul 10, 2026
3 checks passed
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.

2 participants