kas serve
Start an HTTP server that exposes the kasmos task store over a REST API backed by SQLite. Optionally starts a second MCP server on a separate port.
kas serve [flags]
flags
| flag | default | description |
|---|---|---|
--port | 7433 | port for the REST API |
--bind | 0.0.0.0 | address to bind to |
--db | ~/.config/kasmos/taskstore.db | path to the SQLite database file |
--repo | none | repo root to serve; repeat for multiple project-scoped repos |
--mcp | true | enable the MCP server (Streamable HTTP) |
--mcp-port | 7434 | port for the MCP server |
--admin-dir | embedded | path to the built admin SPA dist/ directory |
examples
# start with defaults (port 7433, embedded admin UI)
kas serve
# use a custom port and database
kas serve --port 8080 --db /data/kasmos/tasks.db
# serve one or more repo-scoped projects
kas serve --repo /srv/kasmos/repos/app --repo /srv/kasmos/repos/docs
# bind to localhost only, disable MCP
kas serve --bind 127.0.0.1 --mcp=false
# use a separately built admin UI
kas serve --admin-dir /opt/kasmos/admin/dist
rest api
All task endpoints use the project-scoped URL prefix /v1/projects/{project}/tasks.
health
| method | path | description |
|---|---|---|
GET | /v1/ping | health check — returns 200 if the store is reachable |
tasks
| method | path | description |
|---|---|---|
GET | /v1/projects/{project}/tasks | list tasks; accepts ?status=<s> and ?topic=<t> query params |
POST | /v1/projects/{project}/tasks | create a task (JSON body: TaskEntry) |
GET | /v1/projects/{project}/tasks/{filename} | get a single task |
PUT | /v1/projects/{project}/tasks/{filename} | update task metadata |
task content
| method | path | description |
|---|---|---|
GET | /v1/projects/{project}/tasks/{filename}/content | retrieve plan content (returns text/markdown) |
PUT | /v1/projects/{project}/tasks/{filename}/content | replace plan content (raw markdown body) |
architect decisions
| method | path | description |
|---|---|---|
GET | /v1/projects/{project}/tasks/{filename}/architect-decisions | return the cached architect decision_audit, final task markdown, and any planner draft decisions recorded for hq task details |
The endpoint reads .kasmos/cache/<task>-architect.json from the resolved repo root. Older tasks without architect metadata return available: false with a stable reason instead of failing the task detail page.
subtasks
| method | path | description |
|---|---|---|
GET | /v1/projects/{project}/tasks/{filename}/subtasks | list subtask entries |
PUT | /v1/projects/{project}/tasks/{filename}/subtasks | replace subtask list (JSON array) |
PUT | /v1/projects/{project}/tasks/{filename}/subtasks/{taskNumber}/status | update a single subtask status |
task metadata
| method | path | description |
|---|---|---|
PUT | /v1/projects/{project}/tasks/{filename}/goal | set task goal text |
PUT | /v1/projects/{project}/tasks/{filename}/phase-timestamp | record a phase timestamp |
PUT | /v1/projects/{project}/tasks/{filename}/clickup-task-id | set ClickUp task ID |
POST | /v1/projects/{project}/tasks/{filename}/increment-review-cycle | increment review cycle counter |
PUT | /v1/projects/{project}/tasks/{filename}/pr-url | store the PR URL |
PUT | /v1/projects/{project}/tasks/{filename}/pr-state | update PR review decision and check status |
POST | /v1/projects/{project}/tasks/{filename}/rename | rename the task (changes stored filename) |
pr reviews
| method | path | description |
|---|---|---|
POST | /v1/projects/{project}/tasks/{filename}/pr-reviews | record a PR review (idempotent by review ID) |
GET | /v1/projects/{project}/tasks/{filename}/pr-reviews/pending | list reviews not yet dispatched to a fixer |
GET | /v1/projects/{project}/tasks/{filename}/pr-reviews/{reviewID}/processed | check if a review has been processed |
POST | /v1/projects/{project}/tasks/{filename}/pr-reviews/{reviewID}/reacted | mark that a reaction was posted to a review |
audit events
| method | path | description |
|---|---|---|
GET | /v1/projects/{project}/audit-events | query audit log entries |
Query parameters: repeated kind= values, task, instance, after, before, and limit. after and before accept RFC3339 timestamps with optional fractional seconds; limit defaults to 100 and is capped at 500. Responses include stable id values for idempotent pollers. Because after is a strict timestamp filter, pollers should overlap windows and de-duplicate by id instead of relying on timestamp-only checkpoints.
linear webhooks
| method | path | description |
|---|---|---|
POST | /v1/projects/{project}/linear/webhook | ingest a signed Linear webhook delivery for the project |
the webhook endpoint is active only in repo-scoped serve mode (--repo, or daemon repo auto-detection when --db is not set). bare --db mode returns 503 for this route because kasmos cannot load the repo-local .env and [linear.triggers] configuration needed to verify and route Linear deliveries.
webhook requests must include Linear's signature and delivery headers and use the secret configured by [linear.triggers.webhook]. accepted deliveries are recorded quickly, queued, and drained asynchronously through the same guarded Linear trigger path as the poller. see linear triggers for setup and response details.
instances
Live-preview and permission endpoints for daemon-managed SDK instances. These routes
bridge the daemon control API to the browser-facing kas serve stack. Only
daemon-managed SDK instances support the structured presentation response; tmux
instances return supported: false.
| method | path | description |
|---|---|---|
GET | /v1/projects/{project}/instances/{title}/presentation | retrieve the current structured turn snapshot for a daemon-managed SDK instance; returns { supported, turns, captured_at } |
POST | /v1/projects/{project}/instances/{title}/permission | submit the user's permission choice for a pending prompt; body: { "choice": <0|1|2> } where 0 = allow once, 1 = allow always, 2 = reject |
Daemon instance rows returned through status/listing APIs may include last_activity and health_reason. health_reason is empty when the instance is healthy, or one of stale, paused_old, or exited.
permission choice values:
| value | meaning |
|---|---|
0 | allow once (allow_once) |
1 | allow always (allow_always) |
2 | reject (reject) |
the presentation response shape:
{
"supported": true,
"captured_at": "2026-01-01T10:00:00Z",
"turns": [
{
"id": "turn-1",
"number": 1,
"started_at": "2026-01-01T10:00:00Z",
"completed_at": "2026-01-01T10:00:05Z",
"interrupted": false,
"tool_count": 2,
"rows": [
{ "kind": "tool", "text": "reading file", "tool_name": "Read", "timestamp": null, "is_error": false },
{ "kind": "result", "text": "contents", "tool_name": "", "timestamp": null, "is_error": false },
{ "kind": "response", "text": "", "tool_name": "", "timestamp": null, "is_error": false },
{ "kind": "prose", "text": "I found the file.", "tool_name": "", "timestamp": null, "is_error": false }
]
}
]
}
row kind values: thinking, tool, result, system, permission, response, prose, status.
admin ui
A built-in web admin UI is served at /admin/. To use an externally built admin SPA, pass --admin-dir pointing to the dist/ directory (must contain index.html).
mcp server
When --mcp is true (the default), a Streamable HTTP MCP server starts on --mcp-port (default 7434). The MCP endpoint is at http://<bind>:<mcp-port>/mcp. It exposes the task store and signal gateway as MCP tools, plus filesystem tools scoped to the current working directory and repo root.
The task MCP tools include lifecycle and content operations such as task_list, task_show, task_create, task_update_content, task_delete, and task_transition. They also expose explicit Linear linking operations: task_link_linear fetches and stores a Linear issue link, while task_unlink_linear clears the stored link. In multi-project mode these tools accept an optional project argument to select the target project namespace.
When [linear.receipts] is enabled, transitions driven through both the task actions REST endpoints and the MCP task_transition tool fire the same Linear receipt hooks as the CLI. See linear receipts for configuration and event allowlist details.