MCP Server
xpntl exposes a full MCP tool surface so coding agents can read issues, post updates, and transition state. Interactive clients connect over OAuth; headless agents and CI use a scoped harness key.
Hosted Setup
The xpntl MCP server runs at https://api.xpntl.dev/mcp — no infrastructure
required. It uses Streamable HTTP transport with per-session state and is
an OAuth 2.1 protected resource, so most clients connect without any key to copy.
Connect with OAuth (recommended)
Add xpntl as a custom connector and sign in — the client discovers the OAuth endpoints, bounces you through xpntl sign-in, lets you pick a workspace, and you approve. The connection then acts as you in that workspace.
-
claude.ai / Claude Desktop: Settings → Connectors →
Add custom connector → URL
https://api.xpntl.dev/mcp. -
Claude Code:
claude mcp add --transport http xpntl https://api.xpntl.dev/mcp— the OAuth flow opens in your browser on first use. -
Any OAuth-capable MCP client: point it at
https://api.xpntl.dev/mcp. The server answers an unauthenticated request with401+ aWWW-Authenticatechallenge pointing at its discovery document (/.well-known/oauth-protected-resource), which kicks off the flow automatically.
Connect with a harness key (headless / CI)
For agents that can't run an interactive browser flow, authenticate with a workspace-scoped
harness key passed in the Authorization header. Generate one from
Settings → Team (add an agent, then Connect) or under
Settings → Plan & Billing in Coding Harness Keys.
The key starts with xpntl_hk_ and is shown only once.
{
"mcpServers": {
"xpntl": {
"type": "url",
"url": "https://api.xpntl.dev/mcp",
"headers": {
"Authorization": "Bearer xpntl_hk_..."
}
}
}
}
Any MCP client
Point your client at https://api.xpntl.dev/mcp using the
Streamable HTTP transport. The server responds to POST
with JSON-RPC. Sessions are identified by the Mcp-Session-Id header
returned in the initialize response. Every connection must present a bearer token —
an OAuth access token or a harness key.
Self-Hosted Setup
If you self-host xpntl, the MCP server is built into the API container.
It's mounted at /mcp on whatever host your API runs on.
# If your API runs at https://xpntl.example.com
# MCP endpoint is https://xpntl.example.com/mcp
# Health check
curl https://xpntl.example.com/mcp/health
# → { "status": "ok", "sessions": 0 }
Standalone mode
The MCP server can also run standalone via stdio (for local development or custom setups):
# Stdio transport (pipes)
node apps/mcp/dist/index.js
# HTTP transport (port 3100)
node apps/mcp/dist/http.js
Tool Reference
The xpntl MCP server exposes 74 tools spanning issues, comments, your agent inbox, workflow states, labels, projects, cycles, agent loops, workspace docs, imports, teams, and users. The session is authenticated from your bearer token (OAuth access token or harness key) when the connection opens, so tools are ready immediately. Each tool is annotated with a title and read-only / destructive hints so clients can surface and auto-approve safe calls.
Authentication
| Tool | Description |
|---|---|
xpntl_authenticate |
Authenticate with a harness key. Must be called before any other tool. Params: key (string) — your xpntl_hk_... key |
xpntl_whoami |
Return the authenticated identity (user, role, workspace) and a capability map. Call before attempting an admin-gated mutation. |
Issues
| Tool | Description |
|---|---|
xpntl_issue_list |
List/search issues with full-text search and filters. Params: q, stateType, priority, assigneeId, includeSubIssues, limit |
xpntl_issue_get |
Get a single issue by key (e.g. ACME-42).Params: key |
xpntl_issue_create |
Create a new issue with optional state, assignee, project, labels, and parent. Params: title, description, priority, stateId, assigneeId, projectId, labelIds, parentKey |
xpntl_issue_update |
Update an existing issue by key. Params: key, title, description, priority, stateId, assigneeId |
xpntl_issue_bulk_update |
Update multiple issues at once. Params: keys, stateId, priority, assigneeId |
xpntl_issue_delete |
Soft-delete an issue (can be restored later). Params: key |
xpntl_issue_assign |
Assign a user to an issue. Params: key, userId |
xpntl_issue_unassign |
Remove a user from an issue. Params: key, userId |
Comments
| Tool | Description |
|---|---|
xpntl_comment_list |
List comments on an issue. Params: key |
xpntl_comment_create |
Post a comment on an issue (markdown supported). Params: key, body |
xpntl_comment_delete |
Delete a comment by id (there is no edit — delete & repost to fix). Params: commentId |
Inbox & Notifications
Agents pick up work the same way humans do — through @mentions, assignments, and comment replies.
xpntl_inbox is the one-call way to do it: poll it, act, reply, and mark items read.
| Tool | Description |
|---|---|
xpntl_inbox |
Your actionable inbox in one call — unread @mentions, assignments, and comment replies, each already enriched with the issue (key, title, state, priority, URL), the comment/mention text, and who triggered it, so you can act with no follow-up lookups. Params: types, includeRead, limit |
xpntl_notification_list |
List raw notifications for the authenticated user/agent. Params: unreadOnly, limit |
xpntl_notification_mark_read |
Mark a notification as read after acting on it, so you don't process it again. Params: id |
Workflow States
| Tool | Description |
|---|---|
xpntl_workflow_state_list |
List all workflow states. Use these IDs when creating/updating issues. Returns: id, name, type, position |
xpntl_workflow_state_create |
Create a workflow state (appended to the board). Admins only. Params: name, type, wipLimit |
xpntl_workflow_state_update |
Update a state's name, type, or WIP limit. Admins only. Params: id, name, type, wipLimit |
xpntl_workflow_state_delete |
Delete a state. Refuses if any issue is still in it, or if it is the last state. Admins only. Params: id |
xpntl_workflow_state_reorder |
Reorder the board — pass every state id in the desired order. Admins only. Params: orderedIds |
Labels
| Tool | Description |
|---|---|
xpntl_label_list |
List all labels in the workspace. |
xpntl_label_create |
Create a new label. Admins only. Params: name, color, description |
xpntl_label_update |
Update a label's name, color, or description. Admins only. Params: labelId, name, color, description |
xpntl_label_delete |
Delete a label and remove it from all issues. Admins only. Params: labelId |
xpntl_label_add |
Add a label to an issue. Params: key, labelId |
xpntl_label_remove |
Remove a label from an issue. Params: key, labelId |
Projects & Teams
| Tool | Description |
|---|---|
xpntl_project_list |
List all projects in the workspace. |
xpntl_project_get |
Get a single project (name, key, status, description). Params: projectId |
xpntl_project_create |
Create a new project. Params: name, key (2–10 uppercase chars), description |
xpntl_project_update |
Rename a project or change its key, description, or status. Members and above. Params: projectId, name, key, description, status |
xpntl_project_delete |
Delete a project and everything in it. Irreversible. Admins only. Params: projectId |
xpntl_team_get |
Get a single team. Params: teamId |
xpntl_team_create |
Create a team. Admins only. Params: name, key, description, icon |
xpntl_team_update |
Update a team's name, description, or icon. Admins only. Params: teamId, name, description, icon |
xpntl_team_delete |
Delete a team. Admins only. Params: teamId |
xpntl_team_member_list / xpntl_team_member_add / xpntl_team_member_remove |
List, add, or remove team members. Add/remove are admins only. Params: teamId, userId, role |
xpntl_team_list |
List all teams in the workspace. |
Docs
Workspace docs are the nestable wiki pages shown under Docs in the web app.
Agents can read and maintain them — specs, runbooks, ADRs — the same way they manage issues.
Docs are markdown; xpntl_doc_list returns metadata only, so fetch a doc to read its body.
| Tool | Description |
|---|---|
xpntl_doc_list |
List workspace docs (metadata only — id, title, projectId, parentId, updatedAt). parentId lets you reconstruct the page tree.Params: projectId (optional filter) |
xpntl_doc_get |
Get a single doc by id, including its full markdown content. Params: id |
xpntl_doc_create |
Create a new doc (markdown), optionally scoped to a project or nested under a parent. Params: title, content, projectId, parentId |
xpntl_doc_update |
Update a doc by id. Editing content saves the previous version as a revision; pass parentId to move it in the tree.Params: id, title, content, parentId |
xpntl_doc_delete |
Delete a doc by id (admin only). Sub-pages are re-homed under the deleted doc's parent. Params: id |
Users
| Tool | Description |
|---|---|
xpntl_user_list |
List workspace members. Use these IDs when assigning issues. Returns: id, email, displayName, role |
Priority Values
| Value | Meaning |
|---|---|
0 | No priority |
1 | Urgent |
2 | High |
3 | Medium |
4 | Low |
Workflow State Types
| Type | Default State |
|---|---|
triage | Triage |
backlog | Backlog |
unstarted | Todo |
started | In Progress |
completed | Done |
canceled | Canceled |
Health Check
GET /mcp/health
→ { "status": "ok", "sessions": 3 }
Returns the number of active MCP sessions. Use this to verify the server is running and reachable.