MCP sidecar (LCDL in Cursor)

Connect forge-lcdl to Cursor (or any MCP client) via a local stdio server that exposes LCDL operations as tools. The cheap model can call lcdl.create_contract, lcdl.build_context_pack, lcdl.decompose, lcdl.verify…

Updated

Related: to use forge-lcdl as an MCP client (e.g. call Playwright MCP from Python scripts), see MCP-CLIENT.md.

MCP sidecar versus client paths

Cursor hosts LCDL tools in-process via stdio while Python scripts call external MCP servers as consumers.

  1. Cursor MCP hostCursor launches and manages the local stdio MCP server.
  2. launches stdio serverstdio bridge connects Cursor to forge-lcdl in the project workspace.
  3. LCDL tools in-processGoverned LCDL operations run inside the sidecar without external MCP hops.
  4. Python scriptsApplication code that consumes MCP servers rather than hosting them.
  5. MCP client libraryforge-lcdl MCP client calls remote servers from Python.
  6. external Playwright MCP servers consumer-ownedPlaywright and other MCP servers run outside forge-lcdl.

What ships

Tool Purpose
lcdl.create_contract Load bundled ContractSpec (task_id, optional version). “Create” = in memory, not writing files.
lcdl.build_context_pack build_context_pack (task, repo_path, optional budget_chars).
lcdl.decompose create_patch_units (task_description, optional context_pack stub).
lcdl.verify verify_task_result in-process only (task_id, version, input, output).
lcdl.reduce_failure classify_failure + reduce_failure_to_repair from a failed verification_result dict.
lcdl.benchmark mode: dry_run (default) or run_offline (fake chat). live: true is rejected on this surface.
lcdl.graph_status parse_decision_pack + structure summary (decision_pack object).
lcdl.final_report proof_report_from_results / proof_report_to_dict.

Autonomy tools (opt-in)

Registered only when FORGE_LCDL_MCP_FLOW_ALLOWLIST is set (colon-separated directories). Flow paths are resolved with Path.resolve() and must stay under a listed root.

Tool Purpose Env guard
lcdl.run_flow Load allowlisted .lmeta, run via FlowExecutor + in-process run_task; persist sidecar run record. FORGE_LCDL_MCP_FLOW_ALLOWLIST
lcdl.flow_status Lookup run_id in sidecar store (memory + optional FORGE_LCDL_MCP_RUN_DIR JSON). FORGE_LCDL_MCP_FLOW_ALLOWLIST
lcdl.dispatch_fleet_job Thin wrapper → forge_lcdl.dispatch.fleet.submit (argv, meta, optional node_id). allowlist and FORGE_LCDL_MCP_ALLOW_DISPATCH=1

Operator walkthrough (CLI, HTTP, MCP, config samples): forge-dark-factory AUTONOMY-ENTRYPOINTS.md (canonical product doc).

Python API: each *_tool in forge_lcdl.integrations.mcp.tools accepts a dict and returns {"ok": bool, "data"?: ..., "error"?: ...}.

Install

From the forge-lcdl repo root:

pip install -e ".[dev,mcp]"

The core package stays dependency-free; mcp is optional and only needed to run the stdio server module.

Enable in Cursor

  1. Open forge-lcdl as the project (or set cwd to this repo).
  2. Copy .cursor/mcp.json.example to your user or project MCP config, or merge the lcdl-local entry into your existing MCP JSON.
  3. Adjust cwd to the forge-lcdl root and ensure PYTHONPATH includes src (the example sets PYTHONPATH to src relative to cwd).
  4. Restart Cursor or reload MCP servers after changes.

Optional env for autonomy (operator walkthrough: forge-dark-factory AUTONOMY-ENTRYPOINTS):

Variable Effect
FORGE_LCDL_MCP_FLOW_ALLOWLIST Colon-separated dirs; enables lcdl.run_flow / lcdl.flow_status
FORGE_LCDL_MCP_ALLOW_DISPATCH 1 → also register lcdl.dispatch_fleet_job
FORGE_LCDL_MCP_RUN_DIR Optional directory for JSON run records

Use Cursor’s MCP documentation for where user-level vs project-level config lives in your build.

Entry point:

python3 -m forge_lcdl.integrations.mcp.server

If mcp is missing, the process prints a one-line pip install 'forge-lcdl[mcp]' hint and exits non-zero.

Logs and debugging

  • stderr from the server process (tool errors, import failures).
  • Cursor’s MCP / tools UI usually lists connected servers and recent calls.
  • Run tools directly in Python or pytest (see tests/test_mcp_tools.py) without Cursor.

Security

  1. Secrets in env vars only — never embed API keys or tokens in MCP JSON. Prefer process environment inherited by the stdio server.
  2. No .env files are read by the tool layer; do not ask tools to load dotenv into responses.
  3. No shell / arbitrary execution — verification is in-process schema checks only; benchmarks on this surface are offline unless you change the code.
  4. Review src/forge_lcdl/integrations/mcp/tools.py before exposing the server beyond your machine.
  5. Disable by removing lcdl-local from MCP config or toggling the server off in Cursor.

Disable

Remove or disable the lcdl-local server entry from MCP settings and restart Cursor.