Cursor IDE loads pi-subagents (NDJSON) but not agentctl/jev which replied with Content-Length framing. Align send() and mark type=stdio in mcp.json.
68 lines
3.8 KiB
Markdown
68 lines
3.8 KiB
Markdown
# MCP servers (stdio)
|
|
|
|
Zero-dependency Node MCP wrappers used by Cursor (see [`.cursor/mcp.json`](../../.cursor/mcp.json)).
|
|
|
|
| Server | Script | Purpose |
|
|
|---|---|---|
|
|
| `agentctl` | `agentctl-mcp.mjs` | Lease / docs apply / validate / queue |
|
|
| `jev` | `jev-mcp.mjs` | Typed decide/health against local or remote jev-service |
|
|
| `pi-subagents` | `pi-subagents-mcp.mjs` | Local PI subagent roles/run/result (engineering tool; not product Runner) |
|
|
|
|
```bash
|
|
# from repo root
|
|
node scripts/mcp/agentctl-mcp.mjs
|
|
node scripts/mcp/jev-mcp.mjs
|
|
node scripts/mcp/pi-subagents-mcp.mjs
|
|
```
|
|
|
|
## pi-subagents
|
|
|
|
Markdown model config is the sole editable source: `.doc/ops/2026-09-24-subagent-model-config.md`.
|
|
|
|
| Tool | Behavior |
|
|
|---|---|
|
|
| `pi_subagent_roles` | Read-only catalog; never invokes PI; executor binary from **this server's INSTALL_ROOT** |
|
|
| `pi_subagent_run` | Non-blocking; request JSON in OS tmp; wraps **discovered main worktree** `scripts/agentctl.py with` (governance SSOT lease entry) + **INSTALL_ROOT** `scripts/pi_subagents.py run` |
|
|
| `pi_subagent_result` | Read-only receipt; `running` is not `isError`; terminal failure/`UNKNOWN_REQUEST` after a settled supervisor rejection surfaces the child's typed error (ROLE_DISABLED, LEASE_REQUIRED, …) |
|
|
|
|
**Install vs main:** When the MCP server lives in a linked task worktree, INSTALL_ROOT may differ from the repo main tip. Cross-repo worktrees (different `git-common-dir`) are refused. Optional `config` is worktree-relative registered model config only. `request.config_path` is rejected (use tool `config`).
|
|
|
|
CLI:
|
|
|
|
```bash
|
|
python3 -B scripts/pi_subagents.py roles --config .doc/ops/2026-09-24-subagent-model-config.md
|
|
python3 -B scripts/agentctl.py with --task <id> \
|
|
--resource path:.doc/test-reports/assets/pi-subagents/<id>/<request_id> -- \
|
|
python3 -B scripts/pi_subagents.py run --request /path/to/req.json \
|
|
--config .doc/ops/2026-09-24-subagent-model-config.md
|
|
python3 -B scripts/pi_subagents.py result --task <id> --request-id <request_id>
|
|
```
|
|
|
|
The executor resolves `agentctl` helpers from the git main worktree scripts directory (not a stale colocated copy beside itself when running from a feature worktree).
|
|
|
|
Scoped reads: `scripts/pi-subagent-readonly.ts` — builtin `path` only; `@`/`~` denied; directory walks must contain only allowlisted regular files. Approved tests use a separate snapshot; model evidence stays pristine.
|
|
|
|
### Cursor CLI / IDE compatibility
|
|
|
|
Real Cursor CLI `2026.09.18+` does **not** expand `${workspaceFolder}` in MCP `args`. All Node MCP entries use workspace-relative `args: ["scripts/mcp/….mjs"]` with `"type": "stdio"`.
|
|
|
|
**Response framing:** Cursor stdio MCP expects **newline-delimited JSON-RPC** responses (same as `pi-subagents-mcp.mjs`). `agentctl-mcp.mjs` / `jev-mcp.mjs` historically replied with `Content-Length` framing, which prevented IDE loading even after path fixes; they now emit NDJSON while still accepting Content-Length *requests* on stdin.
|
|
|
|
After reload + enable: `agent mcp list-tools agentctl` / `jev` / `pi-subagents` should list tools. Older Connection-failed notes that only cited `${workspaceFolder}` are incomplete without the framing check.
|
|
|
|
### Limitations (v1)
|
|
|
|
- No shared environment ops (`SHARED_ENV_UNSUPPORTED`).
|
|
- Process-group governance, not an OS sandbox.
|
|
- Unit suite uses fake PI; Cursor UI MCP connectivity requires reload after checkout and host smoke.
|
|
- Host owns live paid-model checks.
|
|
|
|
## jev credentials (not in git)
|
|
|
|
- `~/.secrets/jev/api.key` (chmod 600) or env `JEV_API_KEY`
|
|
- `~/.secrets/jev/base-url` or env `JEV_BASE_URL` (default `http://127.0.0.1:8767`)
|
|
|
|
Reload MCP after checkout. See skill `.cursor/skills/jev-decide/SKILL.md`.
|
|
|
|
`lease_run` / `validate` take `command` as an argv array (no shell). Set `AGENTCTL_REPO` only when the agentctl script is not under the repo tree.
|