@loom/mcp (0.1.2)
Installation
@loom:registry=https://gitlab.amandy.love/api/packages/werk/npm/npm install @loom/mcp@0.1.2"@loom/mcp": "0.1.2"About this package
@loom/mcp
MCP is the plug. Our policy is the security.
External agents request tools; @loom/mcp enforces policy, path guards, plan gates, session scope, and audit logging before anything runs.
Agent (Cursor / Gemini / Codex)
→ tool request
@loom/mcp (McpSafetyGate)
→ tool policy (read / dry-run-write / write / dangerous)
→ path guard (realpath, symlinks, blocked segments)
→ secret guard (.env, keys, credentials)
→ plan gate (server-registered planId)
→ session gate (createdPlans per connection)
→ audit log
→ execute adapter (workspace / analysis / nerve / deck)
Safety layers
| Layer | Module | Role |
|---|---|---|
| Tool policy | toolPolicy.ts |
Risk class per tool; default deny write/dangerous |
| Permissions | permissions.ts |
Config + session flags, apply: true |
| Path guard | pathGuards.ts |
allowedRoots, realpath, symlink escape, node_modules/.git/… |
| Secret guard | secretGuards.ts |
Block .env, keys, credentials (read and write) |
| Plan gate | planGate.ts |
planEdit registers planId; applyEditPlan only accepts session plans |
| Session | session.ts |
Per-client createdPlans, scoped roots |
| Audit | auditLog.ts |
Every call logged (memory + .loom/mcp-audit.jsonl) |
| Sandbox | @loom/sandbox |
Validation execution uses safe profiles; no host shell execution |
| Gate | McpSafetyGate.ts |
Orchestrates all checks |
Config defaults
{
allowWrite: false,
allowDangerous: false,
allowLiveAi: false,
requirePlanBeforeApply: true,
requireHumanApprovalForWrite: true,
validationSandboxProfile: "none",
maxFileBytes: 2_000_000,
maxResponseBytes: 4_000_000,
timeoutMs: 120_000
}
Environment: LOOM_MCP_ALLOW_WRITE, LOOM_MCP_REQUIRE_PLAN, LOOM_MCP_REQUIRE_HUMAN_APPROVAL, LOOM_MCP_SANDBOX_PROFILE, LOOM_MCP_AUDIT_PATH, LOOM_MCP_CONFIG
Plan → apply flow (Phase 2)
workspace_planEdit / deck_refactorSymbol → returns planId + riskReport (registered in session)
[user / Deck approval]
workspace_applyEditPlan / deck_refactorSymbol → { planId, apply: true, humanApproved: true }
Agents must not invent plans or skip riskReport. Human approval (humanApproved: true) in the tool payload is ignored; approval must come from a trusted server-side source (like Deck UI or local CLI via mcp_approvePlan). High-risk writes remain strictly blocked unless approved.
Agent documentation: docs/AGENT_GUIDE.md (tooling guide, symbol IDs, MCP ↔ workspace mapping). Chat meta prompt guide (EN): docs/METAPROMPT.md (how to instruct normal chats to produce safe MCP plans). Chat meta prompt guide (DE): docs/METAPROMPT.de.md (wie man normale Chats fuer sichere MCP-Plaene anleitet). Reliability status: docs/REFACTOR_RELIABILITY_STATUS.md (implemented vs partial vs pending refactor/write guarantees).
Tool risk levels
| Tool | Mode |
|---|---|
workspace_planEdit, deck_refactorSymbol (dry-run), deck_addTestCase (dry-run), deck_issueList, deck_issueView, deck_issueNext, deck_fileGuidanceView |
read / dry-run-write |
workspace_applyEditPlan, deck_refactorSymbol (apply), deck_addTestCase (apply), deck_issueComment, deck_issueClose, deck_fileGuidanceAnnotate |
write |
| shell / git / live AI | dangerous (not exposed by default) |
Sandbox Validation
Validation during workspace_applyEditPlan, deck_refactorSymbol, or deck_addTestCase is safely routed through @loom/sandbox.
- Argv Only:
workspace_validateand other validation fields strictly require an array of strings (argv). Command strings are rejected to prevent shell-injection. - No Shell Parsing: No shell metacharacters or redirection operators are permitted in any argument segment.
- Default Profile:
none(execution blocked). - Other Profiles:
shadow-only,mock,bwrap-fast,podman-test. - Policy: No host shell execution is allowed. Validation commands are executed via sandbox containers or lightweight process boundaries if explicitly allowed via
validationSandboxProfile. - Allowlist: Only a predefined set of safe commands (e.g.,
bun test,tsc --noEmit) are permitted by default. UseallowDangerous: trueto override.
Test-hang safety defaults (promote post-verify)
workspace_promoteExecutionTarget supports optional postVerify with compact and hang-safe behavior:
resultDetail:full | failures-only | summary(default:failures-only)timeoutMs: per-command timeoutstrictTestMode(default:true) for framework-safe argstestProfile:bun | vitest | jest | playwright
When strict mode is active, anti-watch/anti-hang flags are injected for known frameworks. Timed out commands are tagged with an explicit likely-hang warning.
Execution targets (isolated write/refactor loop)
Execution targets provide long-lived shadow copies under .loom/targets/<id> for safer mutation cycles:
workspace_createExecutionTarget- run checks in target (
workspace_targetRunCommand) - refactor/apply in target (
workspace_refactorSymbolwithoptions.executionTargetId) workspace_promoteExecutionTargetworkspace_disposeExecutionTarget
Promote hardening:
dryRunpreview (wouldCopyFiles,wouldDeleteFiles,conflictFiles)- strategy:
copy-only | mirror-delete - conflict policy:
abort | overwrite - baseline hash guards for source drift detection
Quickstart payload sequence
Minimal safe pipeline:
workspace_createExecutionTargetworkspace_refactorSymbolwithoptions.executionTargetId(apply:true)workspace_promoteExecutionTargetwithdryRun:trueworkspace_promoteExecutionTargetwithapply:true+postVerifyworkspace_disposeExecutionTarget
Recommended promote postVerify shape:
{
"postVerify": {
"commands": [["bun", "run", "typecheck"]],
"resultDetail": "failures-only",
"profile": "mock",
"timeoutMs": 60000,
"strictTestMode": true,
"testProfile": "bun"
}
}
Failure playbook (promote + verify)
dryRunshowsconflictFiles:
- keep
conflictPolicy:"abort"default - repair in target and retry preview
- use
overwriteonly intentionally
- Promote blocked by conflicts:
- inspect target via
workspace_targetRunCommand - either preserve source and rework target, or intentionally overwrite
- Post-verify timed out:
- treat as likely hanging suite
- narrow command scope
- keep
strictTestMode:true - prefer
resultDetail:"failures-only"
- Post-verify failed:
- use
workspace_nextToolInfo - apply targeted repair flow
- re-run targeted validation before broader checks
- Need rollback:
workspace_undoApplywith partial modes (only/exclude)- then
workspace_verifyRefactor
Decision matrix (fast operator mode)
| Situation | Tool | Defaults |
|---|---|---|
| First orientation | workspace_decideNext |
include compact decision signals |
| Dense one-call context | workspace_capsule |
keep to minimum useful scope |
| Single mutation + feedback | workspace_editWithFeedback |
reportMode:"compact-agent" |
| Multi-step automation | workspace_executeActionTree |
stopOnFailure:true |
| Risky refactor | execution target flow | always dryRun before promote apply |
| Verify after promote | workspace_promoteExecutionTarget.postVerify |
resultDetail:"failures-only", strictTestMode:true, timeout set |
| Recovery | workspace_undoApply |
partial undo first |
Commands
bun run mcp:start
bun run mcp:list
bun run mcp:config --target cursor
bun run skills:sync --package @loom/mcp
Phase roadmap
- Now — read + plan; apply blocked by default
- Now — apply with
allowWrite+planId+humanApproved - Next — Deck UI shows
riskReport, user clicks Apply - Later — dangerous tools in separate MCP profile only
Dependencies
Dependencies
| ID | Version |
|---|---|
| @deck/runtime | ^0.1.1 |
| @loom/analysis | ^0.1.0 |
| @loom/package | ^0.1.0 |
| @loom/sandbox | ^0.1.0 |
| @loom/workspace | ^0.1.0 |
| @nerve/pulse | ^0.1.0 |
| @nerve/search | ^1.0.0 |
Development Dependencies
| ID | Version |
|---|---|
| @types/bun | latest |
| @types/node | ^22.15.30 |
| typescript | ^6.0.3 |