Skip to content

REST API & MCP tools

API Reference

All endpoints are under /api/v1/. The MCP endpoint is POST /mcp. The default bind is 127.0.0.1:8080.

Authentication

Forge ships a real auth system. Every endpoint except POST /api/v1/auth/register, POST /api/v1/auth/login, and POST /api/v1/auth/refresh requires a bearer token. The first user to register becomes the admin and inherits any orphan resources (bootstrap), so the first call after install should be POST /api/v1/auth/register.

Three token types, all sent as Authorization: Bearer <token>:

TokenWhere it comes fromUse for
JWT access tokenPOST /api/v1/auth/loginWeb UI / short-lived scripts. Refresh via POST /api/v1/auth/refresh.
Personal Access Token (fg_…)POST /api/v1/auth/tokensforge-ctl, MCP clients, long-running scripts.
Daemon registration tokenReturned at daemon registrationDaemon POST /api/v1/daemons/{id}/report only.

The MCP endpoint accepts a PAT or JWT in Authorization: Bearer … or as a ?token= query parameter (some MCP clients can only pass query strings). MCP requests are scoped to the authenticated user’s project memberships.

The CLI list endpoint (GET /api/v1/clis) filters daemons to those visible to the caller (global visibility or owner match).

For the conceptual model behind these endpoints see architecture.

REST endpoints

Auth & users

MethodPathDescription
POST/api/v1/auth/registerRegister a user (first user becomes admin / bootstraps orphan resources)
POST/api/v1/auth/loginIssue a JWT + refresh token
POST/api/v1/auth/refreshRotate refresh token, return new access token
POST/api/v1/auth/logoutRevoke the current refresh token
GET/api/v1/auth/meReturn the current user (includes is_admin)
POST/api/v1/auth/tokensMint a fg_… Personal Access Token
GET/api/v1/auth/tokensList PATs
DELETE/api/v1/auth/tokens/{id}Revoke a PAT

Projects, repos, members, integrations

MethodPathDescription
POST/GET/PATCH/api/v1/projects …/{id}CRUD project (and paused_at)
POST/GET/api/v1/projects/{id}/reposRepos under a project
GET/POST/DELETE/api/v1/projects/{id}/membersProject membership
GET/POST/api/v1/projects/{id}/integrationsGitHub / Gitea external issue sync config
GET/PATCH/api/v1/projects/{id}/settingsProject settings (hooks, review defaults, redaction patterns)

Tasks

MethodPathDescription
POST/api/v1/projects/{id}/tasksCreate task
GET/api/v1/projects/{id}/tasksList tasks (paginated, filterable)
GET/PATCH/DELETE/api/v1/tasks/{id}Get / update / soft-delete task
POST/api/v1/tasks/{id}/claimClaim task (auto-dispatches the executor)
POST/api/v1/tasks/{id}/cancelCancel task (idempotent)
POST/api/v1/tasks/{id}/archiveArchive task (hidden from default lists)
POST/api/v1/tasks/{id}/transitionTransition status; entering review returns {task, review} inline
POST/api/v1/tasks/{id}/reviewRe-run the CI steps without changing state
POST/api/v1/tasks/{id}/gates/{state}/approveApprove a generic gate
POST/api/v1/tasks/{id}/gates/{state}/rejectReject a generic gate (consumes retry budget)
GET/api/v1/tasks/{id}/transitionsAudit log of state transitions
GET/POST/DELETE/api/v1/tasks/{id}/dependenciesTask dependencies
GET/POST/api/v1/tasks/{id}/commentsTask comments
GET/POST/DELETE/api/v1/tasks/{id}/rolesPer-task role assignments (coder, reviewer, …)
GET/api/v1/tasks/{id}/workspaceWorktree status + diff

Agents, daemons, executions, CLIs

MethodPathDescription
POST/GET/api/v1/agentsRegister / list agents
GET/api/v1/agents/{id}Get agent
GET/api/v1/daemonsList daemons (filtered by membership)
POST/api/v1/daemons/{id}/reportDaemon CLI inventory + heartbeat (registration-token auth)
GET/api/v1/clisCLIs visible to the caller
GET/api/v1/tasks/{id}/executionsList executions
GET/api/v1/executions/{id}Get execution
GET/api/v1/executions/{id}/logsGet JSONL execution logs
POST/api/v1/executions/{id}/stopStop an execution
POST/api/v1/executions/{id}/follow-upCreate a follow-up execution
GET/api/v1/executor_typesList adapter types (claude_code, codex, …)
GET/api/v1/profilesExecutor profile presets

Conversations, notifications, operations

MethodPathDescription
GET/POST/api/v1/projects/{id}/conversationsChat conversations
POST/api/v1/conversations/{id}/messagesSend chat message
GET/api/v1/notificationsList notifications
POST/api/v1/notifications/{id}/readMark notification read
GET/api/v1/projects/{id}/operationsOperations snapshot (effective policies, exceptions)
GET/POST/api/v1/workflow_templatesWorkflow templates
POST/api/v1/projects/{id}/workflowApply / update a project workflow definition
GET/api/v1/eventsServer-sent events stream
POST/mcpMCP JSON-RPC endpoint

Pagination

All list endpoints use opaque keyset cursors: base64-encoded JSON {sort_by, sort_order, last_value, last_id}. The db layer queries limit + 1 rows to determine has_more. The response field is items (not data).

Query parameters

ParamDescription
cursorOpaque pagination cursor returned from the previous page
limitPage size (default 20, max 100)
sort_bycreated_at, updated_at, priority, board_position, title, status, agent, task_type, id
sort_orderasc, desc
statusComma-separated status filter
agent_idComma-separated agent filter
assignee_typeComma-separated assignee type filter (agent, user)
assignee_idComma-separated assignee id / user-handle filter
include_cancelledInclude cancelled tasks (default false unless status includes cancelled)
include_archivedInclude archived tasks (default false)
include_totalInclude total count in response

Errors

All errors render as:

{
"code": "version_conflict",
"message": "task version mismatch",
"details": { "expected": 3, "actual": 4 },
"request_id": "req_..."
}

Common HTTP mappings:

StatusWhen
400Validation failure
404Resource not found
409Optimistic version conflict, role assignment conflict
412Workflow guard rejection (before_exit blocked the transition)
422Illegal state transition
500Internal error

Server-Sent Events

GET /api/v1/events streams ForgeEvent payloads from the in-memory event bus. Useful for the web UI and for long-running scripts that want to react to state changes (task.status_changed, execution.completed, …) without polling.

MCP tools

Forge exposes a JSON-RPC 2.0 tool surface at POST /mcp (PAT or JWT auth required — see Authentication). The MCP server has its own McpState and does not depend on the api crate. Disable it entirely with forge --no-mcp.

ToolPurpose
forge_create_taskCreate a new task (uses the project’s primary repo)
forge_list_tasksList tasks with optional status / sort filters
forge_get_taskGet task detail
forge_update_taskUpdate title, description, priority, or plan
forge_assign_agentAtomic claim — assign an agent to a task
forge_transition_taskMove a task to a new workflow status
forge_cancel_taskCancel a task
forge_get_task_diffGet the code diff for a task’s worktree
forge_list_executionsList executions for a task
forge_follow_up_executionSend a follow-up message to resume an agent session
forge_create_sub_tasksCreate ordered subtasks under a parent task
forge_add_task_dependencyDeclare that a task depends on another task
forge_remove_task_dependencyRemove a dependency between two tasks
forge_list_task_dependenciesList prerequisite tasks for a task
forge_register_agentRegister an agent executor
forge_list_agentsList registered agents with optional status filter
forge_list_projectsList projects
forge_create_projectCreate a project
forge_get_projectGet a project including settings and lifecycle hooks
forge_update_projectUpdate project name, settings, or paused state
forge_update_project_lifecycle_hooksReplace a project’s lifecycle hooks

For the conceptual model see MCP for agents (how to wire Claude Code, Codex, Cursor, etc.).

Execution logs

Execution chat history is backed by Forge JSONL logs plus execution prompt metadata, not by agent-private transcript storage. See execution logs for the adapter-specific details and log schema.