Directory : src/api/rest/
Express application mounted on the same HTTP server alongside MCP routes. All endpoints are prefixed with /api/.
See Authentication for details on auth middleware.
JWT cookie (from UI login) — checked first
Bearer apiKey header — for programmatic access
Anonymous — uses server.defaultAccess
List endpoints : { results: [...] }
Single endpoints : direct object
DELETE endpoints : 204 No Content
Errors : { error: "message" } with appropriate HTTP status
Method
Path
Description
GET
/api/auth/status
Auth status (required, authenticated, userId, name). Does not include apiKey
GET
/api/auth/apikey
Returns { apiKey } for authenticated user. Requires valid JWT cookie
POST
/api/auth/login
Login with email + password → sets JWT cookies
POST
/api/auth/refresh
Refresh access token using refresh cookie
POST
/api/auth/logout
Clear auth cookies
/api/auth/status and /api/auth/apikey are accessible before the auth middleware (they verify JWT internally).
Method
Path
Description
GET
/.well-known/oauth-authorization-server
OAuth 2.0 Authorization Server discovery manifest
POST
/api/oauth/authorize
Begin authorization — returns { redirectUrl } (JSON). Body: response_type, client_id, redirect_uri, code_challenge, code_challenge_method, state
POST
/api/oauth/token
Exchange authorization code or refresh token for access/refresh tokens
GET
/api/oauth/userinfo
Bearer token → { sub, name, email }
POST
/api/oauth/introspect
RFC 7662 token introspection. Body: { token } → { active, sub, token_type, exp, iat } or { active: false }
POST
/api/oauth/revoke
Token revocation stub — always returns 200
POST
/api/oauth/end-session
End session stub — always returns 200
POST /api/oauth/authorize never issues an HTTP redirect; callers must follow the returned redirectUrl themselves. This keeps the flow compatible with non-browser MCP clients.
Method
Path
Description
GET
/api/projects
List projects with stats and graph info (includes readonly field per graph)
GET
/api/projects/:id/stats
Per-graph node/edge counts
GET
/api/projects/:id/team
List team members from .team/ directory
GET
/api/workspaces
List all workspaces with their project IDs
Method
Path
Description
GET
/api/projects/:id/knowledge/notes
List notes (query: filter, tag, limit)
POST
/api/projects/:id/knowledge/notes
Create note (body: title, content, tags)
GET
/api/projects/:id/knowledge/notes/:noteId
Get note by ID
PUT
/api/projects/:id/knowledge/notes/:noteId
Update note (partial)
DELETE
/api/projects/:id/knowledge/notes/:noteId
Delete note (204)
GET
/api/projects/:id/knowledge/search?q=...
Search notes (query: q, topK, minScore, searchMode, bfsDepth, maxResults, bfsDecay)
POST
/api/projects/:id/knowledge/relations
Create relation (body: fromId, toId, kind, targetGraph?)
DELETE
/api/projects/:id/knowledge/relations
Delete relation (body: fromId, toId, targetGraph?)
GET
/api/projects/:id/knowledge/notes/:noteId/relations
List note relations
GET
/api/projects/:id/knowledge/linked
Find linked notes (query: targetGraph, targetNodeId)
POST
/api/projects/:id/knowledge/notes/:noteId/attachments
Upload attachment (multipart)
GET
/api/projects/:id/knowledge/notes/:noteId/attachments
List attachments
GET
/api/projects/:id/knowledge/notes/:noteId/attachments/:filename
Download attachment
DELETE
/api/projects/:id/knowledge/notes/:noteId/attachments/:filename
Delete attachment
Method
Path
Description
GET
/api/projects/:id/tasks
List tasks (query: status, priority, tag, filter, assignee, limit)
POST
/api/projects/:id/tasks
Create task
GET
/api/projects/:id/tasks/:taskId
Get task (enriched with subtasks/blocks/related)
PUT
/api/projects/:id/tasks/:taskId
Update task (partial)
DELETE
/api/projects/:id/tasks/:taskId
Delete task (204)
POST
/api/projects/:id/tasks/:taskId/move
Move task status (body: status)
POST
/api/projects/:id/tasks/:taskId/reorder
Reorder task (body: beforeId?, afterId?)
POST
/api/projects/:id/tasks/bulk/move
Bulk move tasks (body: taskIds, status)
POST
/api/projects/:id/tasks/bulk/priority
Bulk set priority (body: taskIds, priority)
POST
/api/projects/:id/tasks/bulk/delete
Bulk delete tasks (body: taskIds)
GET
/api/projects/:id/tasks/search?q=...
Search tasks
POST
/api/projects/:id/tasks/links
Create task link
DELETE
/api/projects/:id/tasks/links
Delete task link
GET
/api/projects/:id/tasks/:taskId/relations
List task relations
GET
/api/projects/:id/tasks/linked
Find linked tasks (query: targetGraph, targetNodeId)
POST
/api/projects/:id/tasks/:taskId/attachments
Upload attachment
GET
/api/projects/:id/tasks/:taskId/attachments
List attachments
GET
/api/projects/:id/tasks/:taskId/attachments/:filename
Download attachment
DELETE
/api/projects/:id/tasks/:taskId/attachments/:filename
Delete attachment
Method
Path
Description
GET
/api/projects/:id/epics
List epics (query: status, priority, tag, filter, limit)
POST
/api/projects/:id/epics
Create epic (body: title, description, priority, status, tags)
GET
/api/projects/:id/epics/search?q=...
Search epics
GET
/api/projects/:id/epics/:epicId
Get epic (includes linked tasks)
PUT
/api/projects/:id/epics/:epicId
Update epic (partial)
DELETE
/api/projects/:id/epics/:epicId
Delete epic (204)
POST
/api/projects/:id/epics/:epicId/link
Link task to epic (body: taskId)
DELETE
/api/projects/:id/epics/:epicId/link
Unlink task from epic (body: taskId)
GET
/api/projects/:id/epics/:epicId/tasks
List tasks belonging to epic
Method
Path
Description
GET
/api/projects/:id/skills
List skills (query: source, tag, filter, limit)
POST
/api/projects/:id/skills
Create skill
GET
/api/projects/:id/skills/:skillId
Get skill (enriched)
PUT
/api/projects/:id/skills/:skillId
Update skill (partial)
DELETE
/api/projects/:id/skills/:skillId
Delete skill (204)
GET
/api/projects/:id/skills/search?q=...
Search skills
GET
/api/projects/:id/skills/recall?q=...
Recall skills (lower minScore)
POST
/api/projects/:id/skills/:skillId/bump
Bump usage counter
POST
/api/projects/:id/skills/links
Create skill link
DELETE
/api/projects/:id/skills/links
Delete skill link
GET
/api/projects/:id/skills/:skillId/relations
List skill relations
GET
/api/projects/:id/skills/linked
Find linked skills
POST
/api/projects/:id/skills/:skillId/attachments
Upload attachment
GET
/api/projects/:id/skills/:skillId/attachments
List attachments
GET
/api/projects/:id/skills/:skillId/attachments/:filename
Download attachment
DELETE
/api/projects/:id/skills/:skillId/attachments/:filename
Delete attachment
Method
Path
Description
GET
/api/projects/:id/docs/topics
List indexed doc files (query: filter, limit)
GET
/api/projects/:id/docs/toc/*fileId
Get table of contents for a doc file
GET
/api/projects/:id/docs/nodes/*nodeId
Get a specific doc node by ID
GET
/api/projects/:id/docs/search?q=...
Search docs
Method
Path
Description
GET
/api/projects/:id/files
List files (query: directory, extension, language, filter, limit)
GET
/api/projects/:id/files/search?q=...
Search files by path
GET
/api/projects/:id/files/info?path=...
Get file metadata by path
Method
Path
Description
GET
/api/projects/:id/team
List team members
Method
Path
Description
GET
/api/projects/:id/code/files
List indexed code files
GET
/api/projects/:id/code/files/:fileId/symbols
List symbols for a file
GET
/api/projects/:id/code/symbols/:symbolId
Get symbol detail
GET
/api/projects/:id/code/symbols/:symbolId/edges
Get edges for a symbol (imports, contains, extends, implements)
GET
/api/projects/:id/code/search?q=...
Search code symbols
Method
Path
Description
GET
/api/projects/:id/tools
List available MCP tools with categories
GET
/api/projects/:id/tools/:toolName
Tool details + input schema
POST
/api/projects/:id/tools/:toolName/call
Call a tool with arguments (returns result + duration)
The tools router creates a lazy in-memory MCP client per project to proxy tool calls.
Method
Path
Description
POST
/api/embed
Embed texts (requires embeddingApi.enabled)
See Embeddings for details.
All request bodies and query params are validated with Zod schemas (src/api/rest/validation.ts). Invalid requests return 400 with error details.
Static files + SPA fallback
Non-API routes serve UI from ui/dist/. Unknown paths return index.html for client-side routing.
Configurable via server.corsOrigins. When not set, allows all origins. Credentials are always enabled (credentials: true).