LearnNewsExamplesServices
Frontmatter
id13745
titleMCP tool-level allowlist mechanism (Agent.allowedTools) — slice of #9980
stateClosed
labels
enhancementaiarchitecture
assigneesneo-opus-vega
createdAtJun 21, 2026, 12:00 PM
updatedAtJun 21, 2026, 12:16 PM
githubUrlhttps://github.com/neomjs/neo/issues/13745
authorneo-opus-vega
commentsCount0
parentIssue9980
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 21, 2026, 12:16 PM

MCP tool-level allowlist mechanism (Agent.allowedTools) — slice of #9980

Closed v13.1.0/archive-v13-1-0-chunk-5 enhancementaiarchitecture
neo-opus-vega
neo-opus-vega commented on Jun 21, 2026, 12:00 PM

Context

Slice of #9980 (Architect MCP Capability Gating by Model Tier). #9980 wants a tiered capability matrix so a local lower-parameter worker (e.g. a Gemma Librarian) is not exposed to the full github-workflow MCP surface it cannot navigate safely.

The gap (V-B-A'd live): Agent.servers: [...] selects MCP servers all-or-nothingLoop.initAsync (ai/agent/Loop.mjs) pushes every tool of every connected client to the model. The Librarian profile already restricts to servers: ['knowledge-base'], but there is no way to expose a subset of a server's tools (e.g. a worker limited to the signal_state_transition trap endpoint that #9980 names).

Scope (this slice — the enabling MECHANISM)

  • Pure core ai/agent/resolveAllowedTools.mjsresolveAllowedTools({tools, allowedTools, serverName}) → the permitted subset. null = no filtering (backward-compatible); {[serverName]: String[]} = per-server opt-in allowlist. Side-effect-free, fully unit-tested.
  • allowedTools config on Agent.mjs (the contract) + pass-through to Loop, with the filter applied at tool-assembly so a gated-out tool is not even registered in toolRegistry (not routable).

Semantics (Tier-2, additive, reversible): fail-open per server — a server absent from a non-null map keeps its full surface; only named servers are constrained, so forgetting one is not a silent capability loss.

Out of scope (stays on parent #9980 for design-convergence)

The tier→tool policy matrix itself — which concrete tools each model tier gets, and wiring tier-specific allowlists into the real profiles (Librarian etc.) + the orchestrator that selects a tier. That is the high-blast security policy (deny-by-default vs fail-open-per-server is a policy the matrix layers on top); the mechanism here supports both. Not a unilateral build.

Acceptance

  • resolveAllowedTools pure module + unit spec (backward-compat default, per-server opt-in, trap-endpoint subset, explicit-deny empty list, non-mutation).
  • Agent.allowedTools config + Loop wiring at tool-assembly; default null = no behavior change for existing profiles.
  • Green unit suite; no regression to existing Agent/Loop behavior.

Refs #9980. Authored by @neo-opus-vega.

tobiu referenced in commit dc896cc - "feat(ai): tool-level MCP capability-gating mechanism (#13745) (#13747) on Jun 21, 2026, 12:16 PM
tobiu closed this issue on Jun 21, 2026, 12:16 PM