Skip to content

feat(security): per-tool audience gating for MCP servers#500

Merged
Aaronontheweb merged 9 commits into
devfrom
claude-wt-mcp-audience
Mar 31, 2026
Merged

feat(security): per-tool audience gating for MCP servers#500
Aaronontheweb merged 9 commits into
devfrom
claude-wt-mcp-audience

Conversation

@Aaronontheweb

Copy link
Copy Markdown
Collaborator

Summary

  • Add McpServerToolGrants to ToolAudienceProfile for per-server tool allowlists that vary by audience. When a server has an entry in the grants dictionary, only listed tools are exposed to that audience. Composes with the existing AllowedMcpServers gate. Backward-compatible — null/omitted grants means all tools exposed (current behavior). Closes feat: per-tool audience gating for MCP servers #490.
  • Enforce per-tool check in ToolAccessPolicy.IsToolExposed and AuthorizeInvocation with deny reason mcp_tool_not_allowed_for_audience_profile
  • Log tool drift warnings in McpClientManager when discovered tools diverge from configured grants
  • Add doctor advisory for MCP servers with no tool grants on any audience profile
  • Add netclaw mcp tools <server> CLI command showing per-audience grant status table
  • Add netclaw mcp tools <server> --snapshot to baseline grants from discovered tools
  • Add netclaw mcp tools TUI mode for interactive tool permission management
  • Add ToolAudienceProfiles.GetAllProfiles() to centralize audience tier enumeration
  • 17 unit tests covering enforcement, deny reasons, search_tools/load_tool filtering, config deserialization, and cross-audience behavior

Test plan

  • 17 new McpToolAudienceGrantsTests covering all enforcement paths
  • 2 new ToolAudienceProfilesDoctorCheckTests for grant advisory
  • All existing tests pass (including daemon constructor changes)
  • Manual binary swap test: netclaw mcp tools memorizer displays grant table, --snapshot writes config correctly
  • CI green
  • TUI mode manual test (netclaw mcp tools with no args)

Add McpServerToolGrants to ToolAudienceProfile for per-server tool
allowlists that vary by audience. When a server has an entry in the
grants dictionary, only listed tools are exposed to that audience.
Composes with the existing AllowedMcpServers gate.

- Add McpServerToolGrants property to ToolAudienceProfile config
- Enforce per-tool check in ToolAccessPolicy.IsToolExposed and
  AuthorizeInvocation with deny reason mcp_tool_not_allowed_for_audience_profile
- Add IsMcpToolAllowed to ToolAudienceProfileResolver
- Log tool drift warnings in McpClientManager when discovered tools
  diverge from configured grants across audience profiles
- Add doctor advisory for MCP servers with no tool grants on any
  audience profile
- Update JSON schema with McpServerToolGrants property
Add ToolAudienceProfiles.GetAllProfiles() to avoid brittle manual
enumeration of Public/Team/Personal in multiple callsites. Replaces
inline array literals in LogToolDrift and FindUngatedMcpServers so
new audience tiers are not silently missed. Also removes misleading
null-conditional on non-nullable profile property in LogToolDrift.
Add tests for integration paths and edge cases missed in initial
coverage: FilterExposedTools session hot path with EffectiveTrustContext,
load_tool denial for blocked MCP tools, Public audience with grants,
multi-server grant independence, and JSON config deserialization
round-trip with end-to-end policy enforcement.
Add CLI and TUI modes for viewing and managing McpServerToolGrants:

- `netclaw mcp tools <server>` — displays discovered tools with
  per-audience grant status table (✓ granted, ✱ all, - blocked)
- `netclaw mcp tools <server> --snapshot` — populates McpServerToolGrants
  for all audiences that allow the server from currently discovered tools
- `netclaw mcp tools` (no args) — launches interactive Termina TUI with
  server selection, tool checkboxes, audience cycling, and save to config

Supporting changes:
- Add McpClientManager.GetToolNames() and /api/mcp/tools/{name} endpoint
- Add DaemonApi.GetMcpToolNamesAsync() client method
- Wire TUI mode in Program.cs for bare `netclaw mcp tools` invocation
TUI improvements:
- Replace hidden Tab cycling with [◀ personal ▶] audience selector
  using left/right arrows, matching the channel wizard pattern
- Add Ctrl+Q quit from any state, Esc quit from server list
- Show proper footer hints with keyboard shortcuts

CLI improvements:
- Add --audience flag to filter list/snapshot to a specific audience
- Add --grant and --revoke flags for surgical per-audience tool edits
- Validate tool names against discovered tools before writing config
- Show targeted error when audience doesn't allow the server
- Show tools as unchecked only when server has explicit grant list,
  not when server is simply absent from grants dictionary
- Check server-level AllowedMcpServers gate before showing tool
  checkboxes — display "server not allowed" message for audiences
  that don't permit the server
- Use manual cursor rendering (channel wizard pattern) to preserve
  cursor position across toggles
- Add [A] toggle-all shortcut (select all / deselect all)
- Subscribe footer hints to state changes so they display correctly
- Match ToggleTool initializer to IsToolGranted semantics
- Add [E] key to toggle server access per audience (adds/removes from
  AllowedMcpServers), enabling operators to expose MCP servers to
  Team/Public audiences directly from the TUI
- When enabling a server for a new audience, start with empty tool
  grants so the operator explicitly selects which tools to expose
- Check server-level AllowedMcpServers gate in IsToolGranted to
  prevent tools showing as granted for audiences that don't allow
  the server
- Show [✓]/[ ] Server enabled indicator with [E] toggle hint
- Dim all tools when server is disabled for the selected audience
- Save both AllowedMcpServers and McpServerToolGrants changes on [S]
- Add [A] toggle-all shortcut
- netclaw-mcp: add per-tool audience filtering, search_tools/load_tool
  enforcement, and tool change detection logging requirements
- netclaw-acl: update tool and data grants requirement with per-tool
  MCP grant scenarios and deny reason codes
- netclaw-cli: add MCP tool permissions CLI, TUI, and doctor advisory
  requirements including server access toggle and secure-by-default
@Aaronontheweb Aaronontheweb marked this pull request as ready for review March 31, 2026 18:16
@Aaronontheweb Aaronontheweb merged commit 6508722 into dev Mar 31, 2026
3 checks passed
@Aaronontheweb Aaronontheweb deleted the claude-wt-mcp-audience branch March 31, 2026 18:16
@Aaronontheweb Aaronontheweb added the security Security-related changes label Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security Security-related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: per-tool audience gating for MCP servers

1 participant