REST API Reference
Every REST endpoint the Plan Forge MCP server exposes, grouped by subsystem, with verb, path, request body shape, response shape, and status codes. The companion to Appendix V — Event Catalog (which covers the WebSocket side) and Appendix Q — API Surface Index (which catalogs the MCP tool surface).
pforge-mcp/server.mjs serves three concurrent surfaces on the same process: stdio MCP for IDE agents, REST + WebSocket on port 3100 for the dashboard and any external integration, and a Forge-Master HTTP surface for the conversational entrypoint. This appendix covers the REST + Forge-Master surfaces; the MCP tool surface is documented in Appendix Q.
Orientation
Plan Forge exposes ~91 REST endpoints across 16 subsystems. Every one of the 106 MCP tools can also be invoked over REST through the generic dispatcher (POST /api/tool/:name), the explicit endpoints below are the "first-class" surfaces the dashboard and CLI use, with response shapes shaped for direct UI consumption rather than tool-call envelopes.
| Subsystem | Count | What it covers |
|---|---|---|
| Discovery | 4 | Liveness, version, capability manifest, well-known endpoint. |
| Plan execution & runs | 10 | List/trigger/abort plan runs, traces, replay, plans, workers. |
| Cost | 1 | Token-spend report across providers and months. |
| Search, timeline, hub | 3 | Cross-surface search, unified timeline, WebSocket upgrade. |
| Memory (L1/L2/L3) | 7 | Capture, drain, search, presets, OpenBrain stats and replay. |
| Crucible | 10 | Idea smelt lifecycle (submit, ask, preview, finalize, abandon, governance). |
| LiveGuard | 14 | Drift, incidents, deploy journal, regression guard, runbooks, hotspots, triage, secret scan, dep watch, env diff. |
| Quorum & fix proposals | 4 | Read/write quorum prompts, list/propose fix plans. |
| Tempering & bugs | 3 | Tempering artifact, bug stub from finding, bug list. |
| Skills (decision tray) | 5 | Pending decisions, accept/reject/defer, full skill catalog. |
| Inner loop | 7 | Reviewer calibration, gate suggestions, cost anomalies, proposed fixes, federation. |
| Bridge & approvals | 3 | Pending approvals, programmatic + browser-link approval. |
| Copilot integration | 5 | copilot-instructions.md read/preview/sync, OpenClaw snapshot/config. |
| GitHub & team coordination | 4 | GitHub metrics, readiness, team dashboard, team activity. |
| Notifications, audit, dashboard, settings | 13 | Notification config, audit config/drain, dashboard state, config, secrets, extensions, update, server restart. |
| Generic MCP dispatcher | 3 | The POST /api/tool/:name escape hatch that exposes any of the 106 MCP tools over REST. |
| Forge-Master | 10 | The conversational entrypoint, chat sessions, prompts, prefs, cache stats. |
| Image generation | 1 | Generate images via xAI Grok Aurora or OpenAI DALL-E. |
Authentication, binding, and CORS
The trust model is local user. The server binds explicitly to 127.0.0.1 (loopback only) and runs no authentication layer of its own, the operating system's user account is the access boundary. Concretely:
- Binding:
app.listen(HTTP_PORT, "127.0.0.1", ...), remote hosts cannot reach the API; only processes running as the same OS user can. - Port:
3100by default; override withPLAN_FORGE_HTTP_PORT(see Appendix U — Server Ports). - CORS: not enabled. Browser dashboards served from
http://127.0.0.1:3100/dashboardshare the same origin. - Bridge approvals (the only endpoint family that crosses a trust boundary) are protected by the per-run HMAC token in
PFORGE_BRIDGE_SECRET, see Bridge & approvals.
If you need to expose the API beyond loopback (rare; usually it's the wrong solution), put a reverse proxy in front of it that handles TLS and authentication. Do not change the bind address; it's a deliberate safety boundary.
POST/PUT endpoints expect Content-Type: application/json. The server uses express.json() with default 100 KB body limit; payloads larger than that return 413 Payload Too Large.
Error response shape
Endpoint handlers wrap exceptions in a consistent envelope:
// 4xx / 5xx
{
"error": "Human-readable message",
"code": "OPTIONAL_MACHINE_CODE", // e.g. ASK_QUESTION_MISMATCH, PLAN_ALREADY_EXISTS
"details": { ... } // optional structured context
}
Status codes follow standard HTTP semantics: 400 for malformed input, 404 for missing resources, 409 for state conflicts (most common in Crucible finalize), 413 for body limits, 500 for unexpected server errors. The complete error-code table lives in the Errors & Exit Codes appendix (forthcoming Appendix X).
Discovery
Lightweight endpoints intended for liveness checks, build identification, and capability negotiation. These are safe to poll, none of them allocate workers or write files.
| Method | Path | Purpose | Response |
|---|---|---|---|
| GET | /.well-known/plan-forge.json | Public discovery manifest | { version, capabilities, dashboard } |
| GET | /api/capabilities | Full capability catalog (mirrors forge_capabilities) | { tools[], workflows[], config, memory } |
| GET | /api/version | Running server version | { version, framework, build } |
| GET | /api/status | Liveness + last error | { ok, lastError, uptimeMs } |
Plan execution and runs
The lifecycle surface for pforge run-plan. Triggering a run returns immediately with a run ID; subscribe to the lifecycle event family over the WebSocket hub for progress.
| Method | Path | Purpose | Request / response notes |
|---|---|---|---|
| GET | /api/runs | List recent runs (last 50) | Returns { runs: [{ id, plan, status, startedAt, endedAt }] }. |
| GET | /api/runs/latest | Latest run with full status | Includes current slice, gate result, cost so far. |
| GET | /api/runs/:runIdx | Specific run by index | runIdx matches .forge/runs/<idx>.jsonl. |
| POST | /api/runs/trigger | Kick off a plan run | Body: { plan, mode, quorum, assisted, dryRun, escalate }. Returns { runIdx, pid }. |
| POST | /api/runs/abort | Abort the active run | Body: { runIdx? } (defaults to current). Sends SIGTERM, then SIGKILL after grace. |
| GET | /api/replay/:runIdx/:sliceId | Session replay log for a slice | Returns the journaled stdout/stderr stream for one slice, used by the dashboard's session-replay view. |
| GET | /api/plans | Enumerate hardened plans | Walks docs/plans/ and parses Scope Contract headers. |
| GET | /api/workers | Active worker processes | PIDs, model, slice, elapsed. |
| GET | /api/traces | List execution traces (run index) | Top-level summary: run, slice count, gate pass/fail. |
| GET | /api/traces/:runId | Trace detail for one run | Per-slice timing, model, tokens in/out, cost. |
Cost
Plan Forge tracks token spend per provider, per model, per run, aggregated monthly. The single REST endpoint mirrors forge_cost_report; richer estimation lives in MCP tools (see Generic MCP dispatcher).
| Method | Path | Purpose | Response |
|---|---|---|---|
| GET | /api/cost | Cost report (token spend per model + monthly aggregation) | { thisMonth, lastMonth, perModel: {...}, perRun: [...] } |
Estimation endpoints (forge_estimate_quorum, forge_estimate_slice) are MCP-only; invoke via POST /api/tool/<name>.
Search, timeline, hub
Cross-surface search and the unified timeline are the dashboard's primary navigation aids. The hub endpoint is where browsers (and any other client) upgrade to a WebSocket to receive live events, see Appendix V — Consuming the Stream for a Node example.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| GET | /api/search | Cross-surface search (plans, events, bugs, incidents, memory) | Query string: ?query=&source=&limit=. Returns { hits: [{ source, recordRef, snippet, score, timestamp }], total, truncated, message }, the gold-standard ACI shape. |
| GET | /api/timeline | Unified event timeline | Cursor-paged: ?cursor=&limit=. Merges nine sources (runs, slices, deploys, incidents, drift, memory, bugs, crucible, tempering). |
| GET | /api/hub | WebSocket upgrade for live events | HTTP GET returns hub status + client count; same path accepts Upgrade: websocket for streaming. |
Memory (L1 / L2 / L3)
The capture-and-recall surface that backs OpenBrain integration and the auto-skills system. See Chapter 22 — How the Shop Remembers for the architectural overview.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| GET | /api/memory | Memory landing, recent captures + state | Dashboard primary view. |
| GET | /api/memory/report | Aggregate stats | Captures/day, hit rate, top thoughts. |
| POST | /api/memory/search | Search L2 captures (and L3 if OpenBrain configured) | Body: { query, limit, source? }. |
| POST | /api/memory/capture | Capture a thought | Body: { content, tags, source }. Broadcasts memory-captured hub event. |
| POST | /api/memory/drain | Drain pending memory queue | Forces a flush of buffered captures to disk + L3. |
| GET | /api/memory/presets | Capture-rule presets | Predefined tag bundles (debugging, architecture, etc.). |
| GET | /api/brain/stats | OpenBrain integration stats | L3 connection state, capture count, embedding model. |
Crucible (idea smelting)
The conversational planner surface. The full lifecycle is submit → ask → preview → finalize. See Chapter 5 — Crucible (Idea Smelting) for the workflow.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| POST | /api/crucible/submit | Start a new smelt | Body: { idea, source? }. Returns { smeltId, firstQuestion }. |
| POST | /api/crucible/ask | Answer current question, get next | Body: { smeltId, answer, questionId? }. Mismatched questionId returns 409 ASK_QUESTION_MISMATCH. |
| GET | /api/crucible/preview | Render current draft + unresolved fields | Query: ?smeltId=. Returns plan draft + criticalGaps[]. |
| POST | /api/crucible/finalize | Atomically claim phase + write plan file | Returns 409 + criticalGaps[] if gaps remain; 409 + PLAN_ALREADY_EXISTS if file exists (pass overwrite: true). |
| POST | /api/crucible/abandon | Mark smelt abandoned | Frees the phase number for the next smelt. |
| GET | /api/crucible/list | List all smelts (filter by status) | Query: ?status=draft|finalized|abandoned. |
| GET | /api/crucible/config | Read Crucible config | Interview model, question budget, autopilot threshold. |
| POST | /api/crucible/config | Write Crucible config | Partial updates merged into .forge.json#crucible. |
| GET | /api/crucible/manual-imports | List manually-imported smelts | Spec Kit, hand-authored briefs. |
| GET | /api/crucible/governance | Governance summary | Autopilot rate, fallback rate, mean question count. |
LiveGuard (drift, incidents, deploys)
The production-companion surface. Every endpoint here emits at least one event in the LiveGuard event family; subscribe over the hub to see real-time alerts.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| GET | /api/drift | Current drift score vs architecture rules | Returns { score, breakdown, asOf }. Score range 0–100. |
| GET | /api/drift/history | Drift trend over time | One entry per forge_drift_report invocation. |
| GET | /api/incidents | List incidents (severity, MTTR) | Sorted newest first; includes resolution timestamp + MTTR ms. |
| POST | /api/incident | Capture a new incident | Body: { title, severity, source, body }. Emits liveguard-incident. |
| GET | /api/deploy-journal | List deploys | Version, deployer, notes, linked run. |
| POST | /api/deploy-journal | Record a deploy | Body: { version, deployer, notes, runIdx? }. |
| POST | /api/regression-guard | Run regression gates against codebase | Body: { scope, baseline? }. Returns pass/fail per rule. |
| GET | /api/runbooks | List operational runbooks | One per alert class. |
| POST | /api/runbook | Generate or update a runbook | Body: { alertClass, content }. |
| GET | /api/health-trend | Health DNA aggregator | Drift + cost + incidents + test pass-rate over time. |
| GET | /api/hotspots | Git churn hotspots | Files with high change frequency, refactor candidates. |
| GET | /api/triage | Prioritized alert list | Drift + incidents + secrets + deps, ranked. |
| GET | /api/liveguard/traces | LiveGuard execution traces | One per forge_liveguard_run invocation. |
| GET | /api/secret-scan | Latest secret-scan results | Values redacted; returns { findings: [{ file, line, severity }] }. |
| POST | /api/secret-scan/run | Trigger a fresh scan | Body: { paths? }. Default scans full repo. |
| GET | /api/deps/watch | Latest dependency-vuln snapshot | Returns CVE list grouped by package. |
| POST | /api/deps/watch/run | Trigger a fresh dep scan | Body: { packageManager? }; auto-detects if omitted. |
| GET | /api/env/diff | Env-var key divergence across .env files | Catches the "key in dev but missing in prod" footgun. |
Quorum and fix proposals
The bridge between LiveGuard findings and structured remediation. Quorum prompts gather context across drift/incident/deploy/secret findings; fix proposals materialize that context into an actionable plan slice.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| GET | /api/fix/proposals | List fix proposals | Sorted by recency; filter by ?status=. |
| POST | /api/fix/propose | Generate an actionable fix plan | Body: { findingId, model? }. Returns proposed plan-slice diff. |
| GET | /api/quorum/prompt | Read XSS-validated quorum prompt | Query: ?promptId=. Output is HTML-escaped for safe rendering. |
| POST | /api/quorum/prompt | Build a quorum prompt | Body: { findings: [...], mode }. Returns { promptId, url }. |
Tempering and bugs
The bug-registry surface. Tempering scans for TODO/FIXME/stub markers and produces an artifact; the bug stub endpoint converts a finding into a registered bug. Bug create/update/validate is MCP-only; see Appendix Q.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| GET | /api/tempering/artifact | Latest tempering artifact | Scan results + temper score. |
| POST | /api/tempering/bug-stub | Create a bug stub from a finding | Body: { findingId, title? severity? }. |
| GET | /api/bugs/list | List registered bugs | Query: ?status=&severity=&plan=. |
Skills (decision tray)
Auto-skills surface decisions that the orchestrator wants a human to make, tag the deferred work, accept/reject the proposal, or defer for later review.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| GET | /api/skills | Skill catalog | Includes hand-authored .github/skills/*/SKILL.md and auto-skills. |
| GET | /api/skills/pending | Pending decisions awaiting accept/reject | Query: ?source=. |
| POST | /api/skills/accept | Accept a pending decision | Body: { decisionId, note? }. |
| POST | /api/skills/reject | Reject a pending decision | Body: { decisionId, reason? }. |
| POST | /api/skills/defer | Defer a pending decision | Body: { decisionId, untilTimestamp? }. |
Inner loop
The self-improvement surface. Inner-loop subsystems observe runs and propose tightenings: gate suggestions from observed failures, reviewer-score calibration, cost-anomaly detection, federation across sibling repos.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| GET | /api/innerloop/status | All inner-loop subsystem states | Returns rollup of the six subsystems below. |
| GET | /api/innerloop/reviewer-calibration | Reviewer-score calibration trace | Drift between auto-reviewer and human override decisions. |
| GET | /api/innerloop/gate-suggestions | Gate-tightening suggestions | Patterns where current gates allowed regressions. |
| GET | /api/innerloop/cost-anomalies | Cost anomalies across runs | Slices that cost >3σ above their plan baseline. |
| GET | /api/innerloop/proposed-fixes | Auto-proposed fixes from health-trend signals | Combines drift, incidents, and test trends. |
| GET | /api/innerloop/federation | Federation-mode status | Advisory cross-repo learning when configured. |
| POST | /api/innerloop/federation/toggle | Enable/disable federation | Body: { enabled }. |
Bridge and approvals
The human-in-the-loop surface. When a plan slice is flagged for approval (assisted mode or escalation), the orchestrator emits an approval-requested event and waits. The browser-link variant is opened by VS Code notification; the POST variant is for programmatic clients.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| GET | /api/bridge/status | Pending approvals waiting for a human nudge | Returns { pending: [{ runId, sliceId, reason, createdAt }] }. |
| POST | /api/bridge/approve/:runId | Programmatic approval | Header X-Bridge-Token required (HMAC from PFORGE_BRIDGE_SECRET). Body: { decision: "approve"|"reject", note? }. |
| GET | /api/bridge/approve/:runId | Browser-link approval | Query ?token= with same HMAC; renders a confirm page. Used by VS Code notification & email links. |
PFORGE_BRIDGE_SECRET in your environment (see Appendix U) before enabling assisted runs. Approvals without a valid token return 401 BRIDGE_TOKEN_INVALID.
Copilot integration
The surface that powers the Copilot Integration Trilogy, reading, previewing, and syncing .github/copilot-instructions.md from the project profile + principles. OpenClaw endpoints post LiveGuard snapshots to the optional analytics service.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| GET | /api/copilot-instructions | Read current file | Returns raw markdown. |
| POST | /api/copilot-instructions/preview | Preview a regenerated file | Body: { projectProfile? principles? }. Non-destructive. |
| POST | /api/copilot-instructions/sync | Sync from project profile + principles | Writes the file; emits a hub event for editor refresh. |
| POST | /api/openclaw/snapshot | Post a LiveGuard snapshot to OpenClaw | Body: snapshot envelope. Requires openclaw.endpoint in .forge.json. |
| GET | /api/openclaw/config | OpenClaw endpoint + auth config | Token is masked in response. |
GitHub and team coordination
Team-mode endpoints that wrap the gh CLI for read-only GitHub access plus a per-operator activity feed sourced from .forge/team-activity.jsonl.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| GET | /api/github-metrics | Live GitHub repo metrics | PRs open, stale branches, issue load. Requires gh auth login. |
| GET | /api/github-readiness | Readiness for Copilot Coding Agent dispatch | Validates labels, branch protection, repo settings. |
| GET | /api/team-dashboard | Per-operator stats + conflict risk | Aggregates team-activity.jsonl. |
| GET | /api/team-activity | Recent run summaries from team feed | Cursor-paged: ?cursor=&limit=. |
Notifications, audit, dashboard, settings
The "everything else" administrative surface, notification channels, audit drain loop, dashboard state persistence, config + secrets read/write, extensions, update checks, soft restart.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| GET | /api/notifications/config | Notification channel config | Slack, Teams, PagerDuty, Email per .forge.json. |
| POST | /api/notifications/config | Update channels | Body: partial config; deep-merged. |
| GET | /api/audit/config | Audit drain loop config | Returns drain interval, ring sizes, destinations. |
| PUT | /api/audit/config | Update audit config | Full replacement of audit subtree. |
| POST | /api/audit/drain | Trigger one full drain pass | Useful before shutdown. |
| GET | /api/dashboard-state | Sticky dashboard tab + filter state | Per-user UI prefs. |
| POST | /api/dashboard-state | Persist dashboard state | Body: { tab, filters, layout }. |
| GET | /api/config | Read merged .forge.json | After env-var overlay and computed defaults. |
| POST | /api/config | Update config | Body: partial; deep-merged. Writes .forge.json. |
| GET | /api/secrets | Read .forge/secrets.json keys | Values masked; only key presence returned. |
| POST | /api/secrets | Update local secrets store | Body: { key, value }. Writes the gitignored file. |
| GET | /api/extensions | Installed extensions | From .forge/extensions/. |
| GET | /api/update-status | Update-check status | Latest release, currency, channel. |
| POST | /api/self-update | Trigger self-update install | Runs pforge self-update; restart required afterward. |
| POST | /api/server/restart | Soft-restart the MCP server | HMR-friendly: re-loads code without dropping the WebSocket clients (best-effort). |
Generic MCP dispatcher
The escape hatch. Any of the 106 MCP tools can be invoked over REST through this surface, useful for SDK clients, CI scripts, and any external integration that needs richer tool semantics than the first-class endpoints expose.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| POST | /api/tool/:name | Invoke any of the 106 MCP tools over REST | Body is the tool's input contract (see Appendix Q). Response is the tool's output payload, unwrapped from the MCP envelope. Crucible and Forge-Master tools route through the MCP handler (v2.82.1 fix). |
| POST | /api/tool/org-rules | Aliased convenience, forge_org_rules | Equivalent to POST /api/tool/forge_org_rules. |
| POST | /api/tool/run-plan | Aliased convenience, forge_run_plan | Equivalent to POST /api/tool/forge_run_plan; also surfaced as /api/runs/trigger with a friendlier shape. |
POST /api/runs/trigger and POST /api/tool/forge_run_plan), prefer the first-class endpoint, its response shape is tailored for direct rendering and skips the MCP envelope. Use the dispatcher when the tool has no first-class equivalent (most estimation, bug, and lattice tools).
Forge-Master (conversational entrypoint)
The HTTP surface for the conversational classifier described in the Forge-Master chapter. Lives alongside the main API on the same port; chat sessions are persistent and resumable.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| GET | /api/forge-master/capabilities | Classifier + tool surface metadata | What Forge-Master can do. |
| GET | /api/forge-master/prompts | Suggested starter prompts | Surfaced by the dashboard chat panel. |
| GET | /api/forge-master/sessions | List active chat sessions | Returns { sessions: [{ id, summary, lastTurnAt }] }. |
| GET | /api/forge-master/session/:id | Fetch one session | Full turn history. |
| POST | /api/forge-master/chat | Start a chat or send a turn | Body: { sessionId? message }. Returns { sessionId, response }. |
| GET | /api/forge-master/chat/:sessionId/stream | Server-Sent Events stream of a turn | For incremental rendering. |
| POST | /api/forge-master/chat/:sessionId/approve | Approve a Forge-Master tool call | For tools requiring human approval (e.g. write actions). |
| GET | /api/forge-master/prefs | Read user preferences | Tone, verbosity, classifier mode. |
| PUT | /api/forge-master/prefs | Update preferences | Body: partial prefs. |
| GET | /api/forge-master/cache-stats | Embedding cache liveliness | Hit rate, useful as a Forge-Master health probe. |
Image generation
The single image-generation endpoint. Routes to xAI Grok Aurora (if XAI_API_KEY is set) or OpenAI DALL-E (if OPENAI_API_KEY is set). Auto-detects the available provider.
| Method | Path | Purpose | Notes |
|---|---|---|---|
| POST | /api/image/generate | Generate an image | Body: { prompt, size? count? provider? }. Returns { images: [{ url, b64? }] }. |
Worked examples
Five short recipes that cover the most common external-integration patterns. All examples assume the server is running at http://127.0.0.1:3100.
1. Trigger a plan run from a shell script
curl -X POST http://127.0.0.1:3100/api/runs/trigger \
-H 'Content-Type: application/json' \
-d '{
"plan": "docs/plans/Phase-28-PLAN.md",
"mode": "auto",
"quorum": "auto"
}'
# Returns: { "runIdx": 47, "pid": 18432 }
2. Stream live events with wscat
wscat -c ws://127.0.0.1:3100/api/hub
> {"type":"hello"}
< {"version":1,"type":"connected","timestamp":"2025-06-15T12:34:56.789Z","source":"hub"}
< {"version":1,"type":"slice-started","timestamp":"...","source":"orchestrator", ...}
Full event catalog in Appendix V.
3. Search across memory, plans, and bugs
curl 'http://127.0.0.1:3100/api/search?query=anvil+cache&source=memory&limit=10'
# Returns the gold-standard ACI shape:
# {
# "hits": [ { source, recordRef, snippet, score, timestamp } ],
# "total": 27,
# "truncated": true,
# "message": "Showing 10 of 27 hits across source=memory."
# }
4. Invoke any MCP tool generically
curl -X POST http://127.0.0.1:3100/api/tool/forge_estimate_quorum \
-H 'Content-Type: application/json' \
-d '{ "plan": "docs/plans/Phase-28-PLAN.md" }'
# Returns the tool's output payload unwrapped from the MCP envelope:
# { "modes": { "auto": {...}, "power": {...}, "speed": {...}, "false": {...} } }
5. Approve a bridge-paused run from a browser link
# VS Code notification or email link contains:
# https://127.0.0.1:3100/api/bridge/approve/47?token=<HMAC>
#
# Clicking opens a confirm page that POSTs back with the decision.
# Programmatic equivalent:
curl -X POST http://127.0.0.1:3100/api/bridge/approve/47 \
-H 'Content-Type: application/json' \
-H 'X-Bridge-Token: <HMAC>' \
-d '{ "decision": "approve", "note": "Looks good, ship it" }'
Using the SDK instead
The pforge-sdk wraps the REST API with typed helpers. Prefer it when integrating from JavaScript/TypeScript:
import { client } from 'pforge-sdk';
const c = client({ baseUrl: 'http://127.0.0.1:3100' });
const runs = await c.get('/api/runs/latest');
const estimate = await c.callTool('forge_estimate_quorum', {
plan: 'docs/plans/Phase-28-PLAN.md',
});
See also
- Appendix V — Event Catalog, every event emitted over
/api/hub - Appendix Q — API Surface Index, the MCP tool surface that the dispatcher delegates to
- Appendix T —
.forge.jsonReference, configuration keys that several endpoints read or write - Appendix U — Environment Variables Reference,
PLAN_FORGE_HTTP_PORT,PFORGE_BRIDGE_SECRET, provider keys - Chapter 29 — Integrating from Outside, end-to-end integration patterns
- Chapter — Dashboard, the primary REST consumer, browsable at
http://127.0.0.1:3100/dashboard - docs/REST-API.md on GitHub, auto-generated endpoint dump (regenerated via
node scripts/dump-rest-routes.mjs)