Skip to content

Privacy & safety

Plan sets are frequently confidential bid documents. conmcp's security posture is built around that fact. This page explains where your plan data actually goes, what the server will and won't do, and why the output is designed to be checked by a human.

Local-first by design

The conmcp server runs on your machine and processes plan PDFs entirely locally. It never uploads plan content anywhere itself, and in v0.1 it never calls an LLM directly. Any code change that would transmit document content off-machine is treated as a vulnerability, not a feature (see the security policy).

Where your plan data actually goes

Be clear-eyed about the full pipeline, though: conmcp hands rendered page images and extracted text to your MCP client, and the client sends them to whatever LLM it uses.

  • Cloud client (Claude Desktop, Claude Code, Cursor with a hosted model, etc.): the pages you render and the text you extract are sent to that provider's servers as part of the conversation. If your plan set is under an NDA or bid-confidentiality terms, that's a decision you need to make deliberately — same as uploading the PDF to any cloud service.
  • Local model (a client wired to Ollama, MLX, or another local vision model): the whole loop stays on your machine.

conmcp is agnostic — it does the same deterministic work either way. The choice of where the vision reasoning happens (and where the images go) belongs to you and your client configuration.

The path sandbox: CONMCP_ALLOWED_DIRS

Every file the server touches — plan PDFs in, rendered reports out — goes through a sandbox check. Paths are resolved (symlinks and .. included) and must land inside a directory listed in CONMCP_ALLOWED_DIRS, a colon-separated list:

CONMCP_ALLOWED_DIRS="/Users/you/plans:/Users/you/bids"

If the variable is unset, the sandbox defaults to the server's working directory only — deliberately narrow (fail-closed) so an unconfigured server can't wander your account. That works for CLI use from your plans folder; for MCP clients, set it explicitly in each client's env block (see client setup).

Anything outside the sandbox is refused with a SandboxError, and the denied attempt is recorded in the audit log. Sandbox bypasses are treated as high-severity security bugs — report them privately.

The audit log

Because bid documents are sensitive, the server keeps an append-only JSONL log of every file access — including denied ones — so you have a record of what it touched:

{"ts": "2026-07-10T14:30:00+00:00", "event": "path_access", "path": "/Users/you/plans/sample_plan.pdf"}
{"ts": "2026-07-10T14:31:12+00:00", "event": "sandbox_denied", "path": "/etc/passwd"}
Variable Default Effect
CONMCP_AUDIT on Set to off (or 0/false) to disable auditing
CONMCP_AUDIT_LOG ~/.conmcp/audit.jsonl Relocate the log file

Auditing never raises — a full disk won't break your tool calls — but ways to make the server read files without leaving an audit trail are in scope for security reports.

Prompt injection via PDF content

A known, inherent consideration of the vision-first design: conmcp extracts text and images from PDFs and returns them to your client's LLM. A malicious or tampered PDF could embed text meant to steer that model — "ignore previous instructions," fake tool directives, misleading quantities.

conmcp cannot fully sanitize adversarial natural language. What limits the blast radius:

  • The server itself never executes instructions found in PDFs and has no LLM of its own to hijack.
  • Its filesystem reach is capped by the path sandbox.
  • The audit log records everything it touched.

Practical guidance: only process plan sets from sources you trust, and treat plan-derived LLM output as untrusted input. If you find a way conmcp could amplify injection (e.g., blending untrusted PDF text into tool instructions in a way that hides its origin), report it privately via the Security tab.

A bidding aid, not a bid

The takeoff schema bakes skepticism in:

  • Every item defaults to needs_review: true and 50% confidence — trust is opt-in, claimed by the model per item and verified by you.
  • Every item carries a source sheet reference so you can check it against the drawing in seconds.
  • The playbook's standing order to the model: "Be conservative — a wrong quantity is worse than a flagged one."
  • Exclusions (BY OTHERS, NIC) are recorded as Excluded items so scope you're not carrying is documented, not silent.
  • Plan/schedule mismatches become Flag items and risks entries — RFI candidates, not silent coin flips.

A human estimator reviews the flagged rows, spot-checks the sources, and owns the number that goes on the bid. conmcp's job is to make that review fast, not to replace it.

Reporting a vulnerability

Please don't open public issues for security problems. Use GitHub's private vulnerability reporting on the Security tab, and reproduce with a synthetic PDF — never a real plan document. Full details in SECURITY.md.