# feat: add an agent-native Strix skill and MCP runtime (proof of concept)#700
# feat: add an agent-native Strix skill and MCP runtime (proof of concept)#700kaddour-youcef wants to merge 2 commits into
Conversation
enabling seamless integration with coding agents for enhanced functionality and automation. This commit includes new modules for agent launching, MCP installation, server management, and service handling, along with updated documentation and test cases to ensure robust performance.
Greptile SummaryThis PR adds an agent-native Strix runtime through skills, MCP, and coding-agent launchers. The main changes are:
Confidence Score: 4/5The MCP proxy boundary and exact report dedupe path need fixes before merging.
strix/mcp/service.py and strix/tools/reporting/tool.py
|
| Filename | Overview |
|---|---|
| strix/mcp/service.py | Adds the MCP scan lifecycle, sandbox execution, proxy dispatch, reporting bridge, and cleanup behavior. |
| strix/mcp/server.py | Registers the public MCP tools and custom stdio transport for agent-native scans. |
| strix/tools/reporting/tool.py | Adds an exact, model-free duplicate check for MCP finding creation while preserving legacy model dedupe by default. |
| strix/interface/agent_launcher.py | Builds Codex and Claude Code commands with an ephemeral Strix MCP server and scan prompt. |
| strix/interface/main.py | Adds runtime selection with --agent and routes coding-agent scans before legacy startup. |
| pyproject.toml | Adds MCP dependencies, console scripts, and wheel packaging for the Strix skill. |
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 3
strix/mcp/service.py:282-284
**Proxy Scope Is Advisory**
After `start_scan`, proxy calls receive only the Caido client and no authorized target data, so `repeat_proxy_request` can replay a captured request with a caller-supplied URL outside the initialized scope. A scan authorized for one host can therefore send requests to another reachable host, while the skill boundary remains only a prompt instruction instead of a server-side check.
### Issue 2 of 3
strix/tools/reporting/tool.py:249-252
**Missing Endpoint Collapses Identity**
When MCP callers omit `endpoint` and `method`, the exact dedupe key becomes only `title` plus `target`. Two separate source-code findings with the same title on the same target, such as hardcoded secrets in different files, will be treated as duplicates and the later verified finding will be dropped from the report.
### Issue 3 of 3
strix/mcp/service.py:84
**Resume Reuses Temp Clones**
Repository scans store cloned paths under `/tmp/strix_repos`, but resume reuses the persisted `local_sources` without checking that those temp directories still exist. After a reboot or temp cleanup, a valid run can fail sandbox startup with a generic error instead of recloning the repository or returning an actionable resume error.
Reviews (1): Last reviewed commit: "Harden agent-native MCP proof of concept" | Re-trigger Greptile
| context = SimpleNamespace(context={"caido_client": self.bundle["caido_client"]}) | ||
| try: | ||
| raw = await tool.on_invoke_tool(context, json.dumps(arguments)) |
There was a problem hiding this comment.
After start_scan, proxy calls receive only the Caido client and no authorized target data, so repeat_proxy_request can replay a captured request with a caller-supplied URL outside the initialized scope. A scan authorized for one host can therefore send requests to another reachable host, while the skill boundary remains only a prompt instruction instead of a server-side check.
Prompt To Fix With AI
This is a comment left during a code review.
Path: strix/mcp/service.py
Line: 282-284
Comment:
**Proxy Scope Is Advisory**
After `start_scan`, proxy calls receive only the Caido client and no authorized target data, so `repeat_proxy_request` can replay a captured request with a caller-supplied URL outside the initialized scope. A scan authorized for one host can therefore send requests to another reachable host, while the skill boundary remains only a prompt instruction instead of a server-side check.
How can I resolve this? If you propose a fix, please make it concise.| identity = tuple( | ||
| str(candidate.get(field) or "").strip().casefold() | ||
| for field in ("title", "target", "endpoint", "method") | ||
| ) |
There was a problem hiding this comment.
Missing Endpoint Collapses Identity
When MCP callers omit endpoint and method, the exact dedupe key becomes only title plus target. Two separate source-code findings with the same title on the same target, such as hardcoded secrets in different files, will be treated as duplicates and the later verified finding will be dropped from the report.
Prompt To Fix With AI
This is a comment left during a code review.
Path: strix/tools/reporting/tool.py
Line: 249-252
Comment:
**Missing Endpoint Collapses Identity**
When MCP callers omit `endpoint` and `method`, the exact dedupe key becomes only `title` plus `target`. Two separate source-code findings with the same title on the same target, such as hardcoded secrets in different files, will be treated as duplicates and the later verified finding will be dropped from the report.
How can I resolve this? If you propose a fix, please make it concise.| targets_info = persisted.get("targets_info") or [] | ||
| if not targets_info: | ||
| return {"success": False, "error": f"Run {run_name!r} has no persisted targets"} | ||
| local_sources = persisted.get("local_sources") or collect_local_sources(targets_info) |
There was a problem hiding this comment.
Repository scans store cloned paths under /tmp/strix_repos, but resume reuses the persisted local_sources without checking that those temp directories still exist. After a reboot or temp cleanup, a valid run can fail sandbox startup with a generic error instead of recloning the repository or returning an actionable resume error.
Prompt To Fix With AI
This is a comment left during a code review.
Path: strix/mcp/service.py
Line: 84
Comment:
**Resume Reuses Temp Clones**
Repository scans store cloned paths under `/tmp/strix_repos`, but resume reuses the persisted `local_sources` without checking that those temp directories still exist. After a reboot or temp cleanup, a valid run can fail sandbox startup with a generic error instead of recloning the repository or returning an actionable resume error.
How can I resolve this? If you propose a fix, please make it concise.
Status
This pull request is intentionally a skeleton and proof of concept. It demonstrates a viable architecture for running Strix through Codex, Claude Code, and other MCP-capable coding agents without giving Strix a separate model API key.
The implementation is usable for experimentation and establishes the core integration boundaries, but it should not be presented as complete production parity with the existing Strix multi-agent runtime. The limitations and follow-up work are documented explicitly below.
Summary
Closes #698.
This change adds an agent-native execution path composed of:
strix-securityskill;strix-mcpstdio server;In this mode, the host coding agent performs all LLM reasoning through its existing authenticated runtime. Strix does not instantiate a model or require
LLM_API_KEY,OPENAI_API_KEY, orANTHROPIC_API_KEY.The legacy provider-backed runtime remains available through
--agent legacyand remains the compatibility path for the existing OpenAI Agents SDK orchestration.Motivation
The existing Strix runtime owns both sides of the application:
That coupling requires users to configure a model API key even when they already have an authenticated coding agent capable of planning, tool use, source analysis, and long-running engineering work.
This proof of concept tests a different boundary:
Goals
strix --target ...workflow through an authenticated coding agent.Non-goals
This PR does not attempt to:
AgentCoordinatorover MCP;Architecture
flowchart LR User --> CLI[Strix CLI] CLI --> Launcher[Agent launcher] Launcher --> Host[Codex / Claude Code] Skill[Strix skill] --> Host Host <-->|MCP stdio| Server[strix-mcp] Server --> Knowledge[Strix knowledge] Server --> Sandbox[Docker sandbox] Sandbox --> Proxy[Caido proxy] Server --> Reports[ReportState and artifacts]Ownership model
The host agent owns:
The MCP server owns:
Implementation details
1. Runtime selection and launcher
strix/interface/main.pyadds--agentwith four modes:auto: use legacy mode whenSTRIX_LLMis configured; otherwise select a coding agent;codex: launch Codex explicitly;claude: launch Claude Code explicitly;legacy: force the existing provider-backed runtime.strix/interface/agent_launcher.py:STRIX_AGENTbefore the Codex/Claude fallback order;--mcp-configvalues from the positional prompt with--.Codex receives
mcp_servers.strix.*overrides. Claude Code receives inline JSON through--mcp-config. Both launch the samepython -m strix.mcp.serverimplementation.2. Portable skill
skills/strix-security/SKILL.mddefines the reusable host-agent workflow:references/mcp-tools.mdholds the larger tool and CVSS reference so the core skill remains concise.agents/openai.yamlsupplies Codex-facing metadata and declares thestrixMCP dependency.The wheel packages the skill under
strix/agent_skills/strix-security, andstrix-skill-pathprints its installed location for Codex, Claude Code, or another agent.3. MCP service
strix/mcp/service.pycontains the model-free stateful service. It owns one scan per MCP process and reuses existing Strix modules instead of duplicating their behavior.start_scanperforms:ReportStatecreation or hydration;The service then exposes execution, knowledge, proxy, finding, status, finish, stop, and cleanup operations.
4. MCP server and transport
strix/mcp/server.pyregisters 15 FastMCP tools:start_scansandbox_execlist_knowledgeload_knowledgelist_proxy_requestsview_proxy_requestrepeat_proxy_requestlist_sitemapview_sitemap_entrymanage_scopecreate_vulnerability_reportlist_findingsscan_statusfinish_scanstop_scanThe server uses MCP JSON-RPC over stdio. A small event-loop-backed stdio adapter replaces the SDK's worker-thread file wrapper because that wrapper can hang in some managed shells. FastMCP still owns tool schemas, protocol initialization, request routing, and tool invocation.
5. Model-free reporting boundary
The existing reporting tool normally performs semantic deduplication through the configured Strix model. MCP mode must not call that path.
create_findingtherefore passesallow_model_dedupe=false. The reporting implementation performs deterministic exact matching over normalized title, target, endpoint, and method. The host agent is instructed to calllist_findingsand perform semantic review before filing.This is a deliberate proof-of-concept compromise and should be improved without reintroducing a hidden Strix-owned model call.
6. Lightweight imports
strix/interface/__init__.pynow loads the legacy CLI lazily. The MCP service imports shared target utilities, and eager CLI import previously initialized the legacy model stack during MCP startup. The lazy boundary keeps stdio startup fast and avoids unrelated provider behavior.7. Packaging and dependencies
The project now:
strix-mcp;strix-skill-path;uv.lock.User experience
Existing CLI
When
STRIX_LLMis unset, this also works:Direct Codex installation
Direct Claude Code installation
Compatibility retained
host.docker.internal.Security considerations
sandbox_execcapability is intentionally powerful and requires further threat modeling before production rollout.Tests and validation
Implemented tests cover:
Validation performed during development:
uv lock --checkpassed;strix/modules;git diff --checkpassed;make check-alldoes not currently complete because its final Pyright step exposes arepository-wide strict-type baseline. In this checkout, Pyright reports unresolved or
partially unknown types across legacy agent, configuration, TUI, and tool modules. Supplying
the project virtual environment explicitly reduces dependency-resolution noise but still
leaves hundreds of existing strict errors. This PR does not hide those failures by weakening
the global Pyright policy or broadly excluding modules. The passing MyPy, Ruff, Bandit,
pre-commit, lockfile, skill, documentation, and test results above are reported separately.
The test suite does not yet contain a complete Docker-backed scan from initialization through proxy traffic, finding creation, finalization, resume, and cleanup. That is a required follow-up before calling this production-ready.
Known limitations
Runtime parity
ReportState.UX parity
Tool parity
sandbox_execis synchronous and has no background handle orwrite_stdinequivalent.Platform and operational hardening
Follow-up roadmap
Review guidance
Suggested review order:
skills/strix-security/SKILL.mdfor the intended host-agent workflow.strix/interface/agent_launcher.pyfor CLI/host integration and argument safety.strix/mcp/server.pyfor the public MCP schema and transport.strix/mcp/service.pyfor lifecycle and reuse of existing Strix components.strix/tools/reporting/tool.pyfor the model-free dedupe boundary.Reviewers should focus especially on:
start_scan;Rollback
The new path is additive. Users can immediately return to the previous runtime with:
At code level, rollback consists of removing the coding-agent branch and new entry points; legacy runner, agent factory, coordinator, sessions, tools, and provider configuration remain present.
Checklist
make check-allremains blocked at this step).