Handbook
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.
- Cursor MCP hostCursor launches and manages the local stdio MCP server.
- launches stdio serverstdio bridge connects Cursor to forge-lcdl in the project workspace.
- LCDL tools in-processGoverned LCDL operations run inside the sidecar without external MCP hops.
- Python scriptsApplication code that consumes MCP servers rather than hosting them.
- MCP client libraryforge-lcdl MCP client calls remote servers from Python.
- external Playwright MCP servers consumer-ownedPlaywright and other MCP servers run outside forge-lcdl.
Cursor MCP host ─ launches stdio server ─ LCDL tools in-process
Python scripts ─ MCP client library ─ external Playwright MCP servers consumer-ownedWhat 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
- Open forge-lcdl as the project (or set
cwdto this repo). - Copy
.cursor/mcp.json.exampleto your user or project MCP config, or merge thelcdl-localentry into your existing MCP JSON. - Adjust
cwdto the forge-lcdl root and ensurePYTHONPATHincludessrc(the example setsPYTHONPATHtosrcrelative tocwd). - 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
- Secrets in env vars only — never embed API keys or tokens in MCP JSON. Prefer process environment inherited by the stdio server.
- No
.envfiles are read by the tool layer; do not ask tools to load dotenv into responses. - No shell / arbitrary execution — verification is in-process schema checks only; benchmarks on this surface are offline unless you change the code.
- Review
src/forge_lcdl/integrations/mcp/tools.pybefore exposing the server beyond your machine. - Disable by removing
lcdl-localfrom MCP config or toggling the server off in Cursor.
Disable
Remove or disable the lcdl-local server entry from MCP settings and restart Cursor.
Related
- CURSOR-INTEGRATION.md — rules, skills, subagents in Cursor.
- BENCHMARKS.md — full benchmark CLI including optional live runs (not exposed by
lcdl.benchmark).