Skip to content

enforce client tool permissions#25

Merged
philipnee merged 1 commit intomainfrom
feat/router-policy-enforcement
Apr 26, 2026
Merged

enforce client tool permissions#25
philipnee merged 1 commit intomainfrom
feat/router-policy-enforcement

Conversation

@philipnee
Copy link
Copy Markdown
Owner

Why

The client identity work lets mvmt know who is calling, but the MCP tool surface still needed to enforce what that client is allowed to see and call. This PR makes per-client policy load-bearing at the router
layer.

What changed

  • Make ToolRouter client-aware for both tools/list and tools/call.
  • Add source/action metadata to routed tools.
  • Filter raw tool visibility by:
    • resolved client identity
    • rawToolsEnabled
    • source/action permissions
  • Deny unauthorized raw tool calls before they reach connectors.
  • Add denied-call audit entries with clientId and deniedReason.
  • Thread client identity through HTTP MCP sessions.
  • Reject MCP session reuse across different client identities.
  • Make /health report the visible tool count for the authenticated client.
  • Preserve legacy behavior when no clients[] policy is configured.

How

Runtime connector loading now carries a policy source ID for each connector. The router infers a required action for each raw tool (search, read, write, or memory_write) and checks that against the
resolved client identity.

When clients[] is absent, the synthesized legacy client keeps the previous global tool behavior. When clients[] is configured, raw tools are visible and callable only if the client has raw tools enabled and
the matching source/action grant.

Changed files

src/server/router.ts - add policy-aware tool metadata, filtered listing, denied-call handling, and audit metadata.

src/server/index.ts - pass resolved client identity into MCP server/session handling and health responses.

src/cli/connector-loader.ts - carry stable policy source IDs for loaded connectors.

src/cli/start.ts - construct the router with connector/source ID pairs.

src/utils/audit.ts - add optional clientId and deniedReason fields.

tests/router.test.ts - cover raw tool filtering, raw-tools-disabled denial, missing-permission denial, and client ID audit logging.

tests/server.test.ts - cover MCP-level filtered listing and denied calls using resolved client identity.

Verification

npm test -- tests/router.test.ts tests/server.test.ts tests/connector-loader.test.ts
npm run verify

Base automatically changed from followup/auth-tests-and-resource-defaulting to main April 26, 2026 18:23
@philipnee philipnee force-pushed the feat/router-policy-enforcement branch from 64f6dbb to 3730556 Compare April 26, 2026 18:24
@philipnee philipnee merged commit 1b22d01 into main Apr 26, 2026
7 checks passed
@philipnee philipnee deleted the feat/router-policy-enforcement branch April 26, 2026 18:26
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.

1 participant