Skip to content

Connecting MCP clients

conmcp is a standard MCP server over stdio. Any MCP client can launch it; the only decision is how the client starts the process and which directories you grant it.

There are two ways to launch the server:

  • uvx from git — no install step, always pulls the pinned source. Best for client configs.
  • From a local cloneuv run --directory /path/to/conmcp conmcp serve. Best if you're developing conmcp itself.

Always set CONMCP_ALLOWED_DIRS

The server only reads files inside the directories listed in CONMCP_ALLOWED_DIRS (colon-separated). If unset, it defaults to the server's working directory — which for GUI-launched clients like Claude Desktop is rarely where your plans live. Set it explicitly to just your plans folder. Details in Privacy & safety.

Claude Desktop

Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json; Windows: %APPDATA%\Claude\claude_desktop_config.json):

{
  "mcpServers": {
    "conmcp": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/ContractorKeith/conmcp.git",
        "conmcp",
        "serve"
      ],
      "env": {
        "CONMCP_ALLOWED_DIRS": "/Users/you/plans"
      }
    }
  }
}

Or, launching from a local clone:

{
  "mcpServers": {
    "conmcp": {
      "command": "uv",
      "args": ["run", "--directory", "/Users/you/code/conmcp", "conmcp", "serve"],
      "env": {
        "CONMCP_ALLOWED_DIRS": "/Users/you/plans"
      }
    }
  }
}

Restart Claude Desktop after editing. The conmcp tools appear in the tools menu, and fence_takeoff shows up in the prompts picker.

Note

Claude Desktop launches servers with a minimal PATH. If it can't find uvx, use the absolute path (e.g. /Users/you/.local/bin/uvx — find yours with which uvx).

Claude Code

One command:

claude mcp add conmcp \
  --env CONMCP_ALLOWED_DIRS="$HOME/plans" \
  -- uvx --from git+https://github.com/ContractorKeith/conmcp.git conmcp serve

Add --scope user to make it available in every project instead of just the current one. From a local clone instead:

claude mcp add conmcp \
  --env CONMCP_ALLOWED_DIRS="$HOME/plans" \
  -- uv run --directory "$HOME/code/conmcp" conmcp serve

Verify with claude mcp list, then use /conmcp:fence_takeoff or just ask Claude to run a takeoff.

Cursor

Create .cursor/mcp.json in your project (or ~/.cursor/mcp.json for all projects):

{
  "mcpServers": {
    "conmcp": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/ContractorKeith/conmcp.git",
        "conmcp",
        "serve"
      ],
      "env": {
        "CONMCP_ALLOWED_DIRS": "/Users/you/plans"
      }
    }
  }
}

Enable the server under Settings → MCP if Cursor doesn't pick it up automatically.

Other MCP clients (generic stdio)

Any client that can spawn a stdio MCP server — Grok Build, OpenHands, a custom agent on the MCP SDK — needs three things:

  • Command: uvx --from git+https://github.com/ContractorKeith/conmcp.git conmcp serve (or conmcp serve if you installed it on PATH, or uv run --directory /path/to/conmcp conmcp serve from a clone)
  • Transport: stdio (that's what conmcp serve speaks)
  • Environment: CONMCP_ALLOWED_DIRS=/path/to/your/plans

For example, with the Python MCP SDK:

from mcp import StdioServerParameters

server = StdioServerParameters(
    command="uvx",
    args=["--from", "git+https://github.com/ContractorKeith/conmcp.git", "conmcp", "serve"],
    env={"CONMCP_ALLOWED_DIRS": "/Users/you/plans"},
)

Optional environment variables

Set these in the same env block if you need them:

Variable Default What it does
CONMCP_ALLOWED_DIRS server working directory Colon-separated list of directories the server may read/write. Set it.
CONMCP_MAX_RENDER_DPI 300 Hard cap on render_page resolution.
CONMCP_MAX_PAGES_PER_CALL 20 Max pages one extract_quantities call scans.
CONMCP_AUDIT on Set to off to disable the file-access audit log.
CONMCP_AUDIT_LOG ~/.conmcp/audit.jsonl Where the audit log is written.

Smoke test

Whichever client you use, this prompt should exercise the whole loop (adjust the path to wherever you ran conmcp sample):

Call get_plan_overview on /Users/you/plans/sample_plan.pdf and tell me what sheets are in it.

If the client reports a sandbox error, your CONMCP_ALLOWED_DIRS doesn't cover the PDF's folder — fix the env block and restart the client.