Skip to content

examples: demonstrate pre-tool approval for MCP calls - #723

Open
jiezeng2004-design wants to merge 3 commits into
lastmile-ai:mainfrom
jiezeng2004-design:agent/mcp-tool-approval-gateway
Open

examples: demonstrate pre-tool approval for MCP calls#723
jiezeng2004-design wants to merge 3 commits into
lastmile-ai:mainfrom
jiezeng2004-design:agent/mcp-tool-approval-gateway

Conversation

@jiezeng2004-design

@jiezeng2004-design jiezeng2004-design commented Jul 25, 2026

Copy link
Copy Markdown

Summary

  • demonstrate application approval with the existing AugmentedLLM.pre_tool_call hook
  • use exact allowlists for filesystem reads and approval-gated filesystem changes
  • fail closed for delete, shell, Git, package, and unknown tools
  • pin the example filesystem server and persist owner-only JSONL audit events with argument digests
  • test hook decisions, approval and rejection, exact-name blocking, sensitive paths, and audit permissions

Why

Tool filtering controls which tools the model sees, but applications may also
need a decision immediately before dispatch. This example shows how a subclass
can delegate that decision to injected approval and audit components.

The example is intentionally limited to the configured filesystem MCP server.
It does not attempt to parse shell commands or provide a general security policy
engine, and it does not add a new mcp-agent public API.

Enforcement boundary

The hook covers calls dispatched through this augmented LLM instance. Direct
Agent.call_tool calls, another LLM instance, or a client connected directly
to the MCP server bypass the example. Server-initiated
sampling/createMessage is a separate protocol path.

The sensitive-path check is illustrative, not workspace confinement or a
sandbox. The filesystem server should be rooted at the intended workspace, and
OS or container isolation remains the containment boundary.

Validation

  • ruff check examples/basic/mcp_tool_approval tests/examples/test_mcp_tool_approval.py
  • ruff format --check examples/basic/mcp_tool_approval tests/examples/test_mcp_tool_approval.py
  • pytest tests/examples/test_mcp_tool_approval.py -q (8 passed)
  • python -m compileall for the example and focused tests
  • git diff --check
  • npm registry metadata verified for @modelcontextprotocol/server-filesystem@2026.7.10

The focused tests use fake approval and audit components and do not start an MCP
server or call an LLM.

Summary by CodeRabbit

  • New Features

    • Added a runnable MCP tool-approval example with configurable allow, approval, and block policies.
    • Added safeguards for unknown tools, write operations, and sensitive file paths.
    • Added redacted JSONL audit logging using argument digests instead of raw arguments.
    • Added configuration and setup instructions for running the example.
  • Tests

    • Added coverage for approval flows, blocked operations, sensitive paths, audit redaction, and secure log-file permissions.

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds an MCP filesystem tool approval example with fail-closed policy decisions, optional interactive approval, SHA-256 argument digests, JSONL audit logging, configuration, documentation, and tests covering allowed, approved, declined, blocked, redacted, and permission-restricted outcomes.

Changes

MCP tool approval flow

Layer / File(s) Summary
Policy contracts and filesystem decisions
examples/basic/mcp_tool_approval/policy_gateway.py
Defines authorization models, normalizes and hashes tool arguments, detects sensitive paths, and applies filesystem allow, approval, or block decisions.
Approval authorization and audit flow
examples/basic/mcp_tool_approval/policy_gateway.py
Routes tool calls through ApprovalGate, optionally invokes interactive approval, records JSONL audit events with restricted file permissions, and returns the authorized request or False.
Runnable example and environment wiring
examples/basic/mcp_tool_approval/main.py, examples/basic/mcp_tool_approval/mcp_agent.config.yaml, examples/basic/mcp_tool_approval/mcp_agent.secrets.yaml.example, examples/basic/mcp_tool_approval/requirements.txt
Wires the approval hook into an OpenAI-backed MCP agent and configures the filesystem server, model, logging, secrets placeholder, and requirements.
Approval behavior tests and usage documentation
tests/examples/test_mcp_tool_approval.py, examples/basic/mcp_tool_approval/README.md
Documents execution and enforcement boundaries, and tests read access, write approval, unknown-tool blocking, sensitive-path blocking, redacted auditing, and audit file permission repair.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant ApprovalHook
  participant ApprovalGate
  participant filesystem_policy
  participant JsonlAuditSink
  Agent->>ApprovalHook: pre_tool_call tool request
  ApprovalHook->>ApprovalGate: authorize request
  ApprovalGate->>filesystem_policy: evaluate normalized operation
  filesystem_policy-->>ApprovalGate: policy decision
  ApprovalGate->>JsonlAuditSink: append audit event
  ApprovalGate-->>ApprovalHook: allow or reject
  ApprovalHook-->>Agent: original request or False
Loading

Suggested reviewers: saqadri

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the example’s main change: demonstrating pre-tool approval for MCP calls.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@jiezeng2004-design jiezeng2004-design changed the title examples: add human approval gate for high-risk MCP tool calls examples: demonstrate pre-tool approval for MCP calls Jul 25, 2026

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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 `@examples/basic/mcp_tool_approval/mcp_agent.config.yaml`:
- Around line 14-15: Update the MCP filesystem server command in the
configuration by pinning `@modelcontextprotocol/server-filesystem` to a specific
tested version in the args value, rather than resolving the latest release
dynamically. Keep the existing npx invocation and approval configuration
unchanged.

In `@examples/basic/mcp_tool_approval/policy_gateway.py`:
- Around line 145-148: Update the audit log append logic in _append to create
newly opened log files with owner-only permissions (0600), and explicitly
validate or repair existing files that have looser permissions before writing.
Preserve the current append behavior and JSON serialization while ensuring no
group or other-user access remains.

In `@examples/basic/mcp_tool_approval/README.md`:
- Around line 21-25: Update the Run prerequisites in the README to state that
Node.js/npm must be installed and npx must be available on PATH before executing
the example. Keep the existing Python/uv setup and command flow unchanged.

In `@examples/basic/mcp_tool_approval/requirements.txt`:
- Line 1: Update the mcp-agent dependency specifier in requirements.txt to use a
supported relative filesystem path, such as ../.., instead of the file:// URI
containing .. in its authority.
🪄 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: 94541e4c-9ad1-4265-9956-413168eae9f7

📥 Commits

Reviewing files that changed from the base of the PR and between f62d849 and 5d1528e.

📒 Files selected for processing (7)
  • examples/basic/mcp_tool_approval/README.md
  • examples/basic/mcp_tool_approval/main.py
  • examples/basic/mcp_tool_approval/mcp_agent.config.yaml
  • examples/basic/mcp_tool_approval/mcp_agent.secrets.yaml.example
  • examples/basic/mcp_tool_approval/policy_gateway.py
  • examples/basic/mcp_tool_approval/requirements.txt
  • tests/examples/test_mcp_tool_approval.py

Comment thread examples/basic/mcp_tool_approval/mcp_agent.config.yaml Outdated
Comment thread examples/basic/mcp_tool_approval/policy_gateway.py
Comment thread examples/basic/mcp_tool_approval/README.md
Comment thread examples/basic/mcp_tool_approval/requirements.txt Outdated
@jiezeng2004-design

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@jiezeng2004-design
jiezeng2004-design marked this pull request as ready for review July 25, 2026 11:46
Copilot AI review requested due to automatic review settings July 25, 2026 11:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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