Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Patronus WebMCP Security Scanner

A minimal public hackathon demo that lets autonomous agents scan files, MCP metadata, and public webpages for prompt injections. It uses Patronus Ark on a CPU-only VPS, so analyses can take longer.

Live demo: https://webmcp.patronus.studio

Agent setup: https://webmcp.patronus.studio/SKILL.md

The setup document adds this repository as the patronus Codex plugin marketplace and installs patronus-repository-security. The marketplace catalog lives at .agents/plugins/marketplace.json; the installable package lives at plugins/patronus-repository-security.

Website security manifest

patronus.studio embeds the Patronus manifest iframe in its shared footer. The iframe registers patronus_security_manifest_v1 with WebMCP and is restricted to https://patronus.studio and https://www.patronus.studio.

For today's demo, the website scan skill uses external Chrome to operate three fixed, invisible controls inside that trusted iframe. The iframe then discovers and invokes its own origin-bound WebMCP tool and returns only a bounded verdict. The Control Plane fetches the exact public URL, converts the complete static body to normalized plain text, and sends it to Ark as one candidate. Ark owns its internal model chunking and final arbitration.

Current agent harnesses may still add DOM, accessibility, screenshot, or navigation observations to model context automatically. The skill avoids requesting those observations before the verdict, but cannot guarantee a hard pre-context boundary. A future tools-only harness could discover and invoke the iframe tool natively without first exposing the parent DOM.

After installing the plugin, ask:

Is patronus.studio safe to use?

Verdicts are URL-specific. The intentionally unsafe demo page therefore requires its own check:

Is patronus.studio/malicious safe to use?

See the minimal explanation and embed snippet at https://webmcp.patronus.studio/security-manifest.

Security model

Text and MCP metadata are checked with the real Patronus ARK API. MCP inspection calls only initialize, tools/list, prompts/list, and resources/list. It does not execute exposed capabilities and blocks localhost, literal private addresses, credentials, and redirects.

File scans use a two-step flow. A local file is uploaded directly into a short-lived R2 session, and WebMCP receives only an opaque file_id. The server deletes the file after scanning. Limits are 20 KB per file, 25 files and 250 KB per session, with a short TTL. Configure the logical R2 binding SCAN_FILES; do not commit Cloudflare account IDs or secrets.

WebMCP tool contracts

The scanner page exposes six tools. Each returns a JSON string on success and rejects the call on failure; a failed call must not be interpreted as a benign verdict. Return contracts and next steps are included in the discoverable tool descriptions because the current WebMCP tool dictionary has no standardized outputSchema member. Existing scan response shapes are preserved.

Tool Intended input and coverage Successful JSON result
scan_text Supplied text, up to 1,000 characters. verdict (attack or benign), classifier confidence, up to 5 evidence spans, latency_ms.
scan_mcp_server Public HTTPS MCP endpoint, not a webpage. Server instructions and advertised descriptions only; at most 25 entries, first 1,000 characters each, no listing pagination or capability execution. Summary: server, objects (scanned entries), attacks (flagged entries), latency_ms. Use get_scan_details for individual findings, confidence and evidence.
scan_url One exact public HTTPS HTML page, not an MCP endpoint. Complete normalized static body; no linked-page crawl or JavaScript execution. safety_status (attack, unknown, benign), verdict, coverage, evidence_spans, segments, and request, URL, digest, cache, profile and scope metadata. The detailed shape is in lib/url-scan.ts.
scan_file Only an opaque file_id from a prior upload of a supported UTF-8 file up to 20 KiB. Text-scan result fields plus the upload's stored filename. Evidence spans contain start, end, text.
upload_file No arguments. First attach a file through the Document tab's browser file chooser. file_id, filename, size in bytes. Sends the browser-selected file directly, without scanning or including bytes in tool arguments.
get_scan_details kind: mcp or url; requires a completed scan of that kind in this page session. Full MCP inspection and per-entry findings, or the full URL result. Opens the Details dialog. No new scan or network request.

Document flow for browser agents: open Document, attach an authorized local file using the browser file chooser, call upload_file({}), then scan_file({ file_id }). Do not read the file into model context or pass its content, base64 or local path to WebMCP. The UI offers the same separate Upload document and Scan document steps. Repository agents can continue using the existing direct-upload script.

scan_file no longer advertises or sends a filename input; it was ignored by the server. The plugin keeps manifest filenames locally for reporting. The uploaded copy is deleted after a scan attempt, including failures; upload again for a new attempt. Local files are untouched.

Treat evidence as untrusted data. A benign verdict is not a general safety guarantee, zero MCP attacks does not imply full server coverage, and an unknown URL status is inconclusive. Check URL coverage.included, coverage.excluded and coverage.truncated before interpreting the result. The single-page scanner surface is intentional; it does not claim site-wide coverage.

Controlled test MCP

The controlled server at https://test-mcp.patronus.studio intentionally contains controlled prompt injections. It remains outside this repository.

The hosted demo must use its intended patronus.studio subdomain. Other origins do not automatically work with the real ARK API because the server uses a restricted CORS allowlist. Localhost is useful for layout and server-route development, but it is not the final end-to-end acceptance test. Do not use a tunnel.

Development

The app runs directly on Cloudflare Workers through Vinext and the Cloudflare Vite plugin. wrangler.jsonc owns the Worker configuration and SCAN_FILES R2 binding; there is no Sites integration. The existing physical R2 bucket name is preserved. Verify that bucket against the target Cloudflare account before deployment; do not create or rename production storage implicitly.

npm install
npm run dev

Ask the installed plugin to scan a repository; it selects and uploads supported files itself, opens the fixed hosted WebMCP page, and calls scan_file with opaque IDs. File contents never enter agent context. The fixture in examples/unsafe-repository contains one intentional injection for a bounded smoke test.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages