Skip to content

release: v0.22.0 (MCP proxy operator allowlist/denylist for tools/list and tools/call)#113

Merged
vaaraio merged 1 commit into
mainfrom
release/v0.22.0
May 20, 2026
Merged

release: v0.22.0 (MCP proxy operator allowlist/denylist for tools/list and tools/call)#113
vaaraio merged 1 commit into
mainfrom
release/v0.22.0

Conversation

@vaaraio
Copy link
Copy Markdown
Owner

@vaaraio vaaraio commented May 20, 2026

Summary

Adds operator-side tool filtering to the MCP proxy via two new repeatable CLI flags:

  • --allow-tool NAME: if any are given, only those tools pass through.
  • --deny-tool NAME: those tools are filtered. Denylist wins on overlap.

Effects:

  • tools/list responses are filtered before the client sees them. The LLM never learns that hidden tools exist.
  • tools/call to a filtered tool is rejected at the perimeter with an MCP isError: true payload (decision: "FILTERED", reason: "Tool filtered by operator policy"). The upstream is not contacted and the risk pipeline is not invoked.

Backward compatible: no flags means current passthrough behavior. The pipeline-based interception path is unchanged for non-filtered tool calls.

Why

The proxy already governs each tools/call through the risk pipeline at runtime. That covers the "is this specific call safe right now" question. It does not cover the "should the LLM ever see this tool at all" question.

Example: an MCP client running against github/github-mcp-server is exposed to write tools like delete_repository, create_branch, merge_pull_request. A deployment may want a read-only posture without depending on the LLM to refrain. Denying those tools at the perimeter shapes the LLM's tool surface to match operator policy, independent of the risk score.

Small surface, real policy-semantic upgrade: from "score every call" to "score every call AND control what's reachable."

Usage

python -m vaara.integrations.mcp_proxy \
  --upstream /path/to/github-mcp-server \
  --upstream-arg stdio \
  --allow-tool search_repositories \
  --allow-tool get_pull_request \
  --allow-tool list_issues

Read-only against GitHub MCP. Anything else returns Tool filtered by operator policy on call, and never appears in tools/list to begin with.

Test plan

  • pytest tests/test_integrations_mcp_proxy.py — 14 tests pass (8 new, covering denylist drops, allowlist restricts, denylist-wins-on-overlap, no-policy passthrough, filtered tools/call returns block, allowlist tools/call still pipelines)
  • Full suite: 726 passed, 12 skipped, no regressions
  • Smoke against real github-mcp-server with --deny-tool delete_repository and verify tools/list and tools/call both reject (deferred to follow-up unless reviewer wants it pre-merge)

Summary by CodeRabbit

Release Notes v0.22.0

  • New Features

    • Added operator-side MCP tool filtering with repeatable --allow-tool and --deny-tool CLI flags to control tool exposure
    • Filtered tools are removed from tool lists and requests targeting them are rejected at the proxy perimeter before reaching upstream
    • Denylist takes precedence when rules overlap; passthrough behavior maintained when no filters are specified
  • Documentation

    • Updated CHANGELOG and README with new tool filtering feature documentation

Review Change Stack

…t and tools/call

Bumps version 0.21.0 → 0.22.0 across pyproject.toml and
clients/ts/package.json. Promotes the [Unreleased] CHANGELOG entry to
[0.22.0] - 2026-05-20 with explicit Added / Verified / Use case
subsections. Updates README MCP proxy section with a paragraph on the
new --allow-tool / --deny-tool flags. Extends the mcp_proxy.py module
docstring to note the optional filtering behaviour.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

📝 Walkthrough

Walkthrough

Release v0.22.0 documents the operator-side MCP tool filtering feature. Changelog and README describe the new allow/deny tool flags, their effect on tools/list and tools/call, and denylist precedence behavior. Module docstring and version bumps in both TypeScript and Python manifests complete the release.

Changes

Release v0.22.0 Documentation and Versioning

Layer / File(s) Summary
Feature documentation and release notes
CHANGELOG.md, README.md, src/vaara/integrations/mcp_proxy.py
v0.22.0 release notes document operator-side MCP tool filtering with Theme, Added items, and use case. README explains the repeatable --allow-tool/--deny-tool flags and their filtering behavior on tools/list and tools/call, with denylist precedence. Module docstring describes perimeter rejection with FILTERED payload.
Package version updates
clients/ts/package.json, pyproject.toml
Version fields bumped from 0.21.0 to 0.22.0 in TypeScript client package manifest and Python project configuration.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

  • vaaraio/vaara#112: The main PR implementing operator-side tool filtering feature (allow/deny lists, filtering tools/list, rejecting tools/call with FILTERED before forwarding) that this PR documents for v0.22.0 release.
  • vaaraio/vaara#100: Prior MCP tools/call interception work that v0.22.0 builds upon with the addition of operator-side allow/deny tool filtering.

Poem

🐰 A release note hops with care,
Documenting filters in the air,
Version bumps from .21 to .22,
MCP tool allowlists—feature shiny and new!
Denylists take the lead when they meet,
Now operators keep their toolbox neat. 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically describes the main feature addition in this release: operator-side tool filtering for MCP proxy using allowlist/denylist functionality.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/v0.22.0

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/vaara/integrations/mcp_proxy.py`:
- Around line 9-12: The module docstring incorrectly says the proxy "forwards
every request" while the implementation optionally filters and blocks some
requests; update the top-level docstring in mcp_proxy.py to state that the proxy
normally forwards requests but, when operator-side filtering
(--allow-tool/--deny-tool) is enabled, it will filter the upstream tools/list
response and may block tools/call at the perimeter (returning a FILTERED block
payload) instead of forwarding them upstream; mention the relevant endpoints
(tools/list, tools/call) and the filtering flags so the contract is unambiguous.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0c22e8fc-5779-47ee-ba1f-50305d8e8d68

📥 Commits

Reviewing files that changed from the base of the PR and between bd51f59 and b9550be.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • README.md
  • clients/ts/package.json
  • pyproject.toml
  • src/vaara/integrations/mcp_proxy.py

Comment on lines +9 to +12
Optional operator-side filtering (``--allow-tool``/``--deny-tool``): when set,
the proxy filters the upstream's ``tools/list`` response before the client
sees it, and rejects ``tools/call`` to a filtered tool at the perimeter with
a ``FILTERED`` block payload, without contacting the upstream.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Docstring now conflicts with forwarding semantics.

With filtering enabled, not every request is forwarded upstream (tools/call can be blocked at the perimeter). Please adjust the earlier “Forwards every request” sentence so the module contract is unambiguous.

✏️ Proposed wording adjustment
-Forwards every request to the upstream, but
-routes ``tools/call`` through Vaara's interception pipeline first. Allowed
-calls flow through transparently. Blocked calls return an MCP tool error.
+Forwards MCP traffic to the upstream, with ``tools/call`` routed through
+Vaara's interception pipeline first. Allowed calls flow through transparently.
+Blocked calls (policy or operator filter) return an MCP tool error without
+contacting the upstream.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/vaara/integrations/mcp_proxy.py` around lines 9 - 12, The module
docstring incorrectly says the proxy "forwards every request" while the
implementation optionally filters and blocks some requests; update the top-level
docstring in mcp_proxy.py to state that the proxy normally forwards requests
but, when operator-side filtering (--allow-tool/--deny-tool) is enabled, it will
filter the upstream tools/list response and may block tools/call at the
perimeter (returning a FILTERED block payload) instead of forwarding them
upstream; mention the relevant endpoints (tools/list, tools/call) and the
filtering flags so the contract is unambiguous.

@vaaraio vaaraio merged commit 2b1f335 into main May 20, 2026
10 checks passed
@vaaraio vaaraio deleted the release/v0.22.0 branch May 20, 2026 09:53
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