MCP Integration
SetGet speaks the Model Context Protocol in both directions:
- Outbound — register external MCP servers (Slack, GitHub, Jira, custom HTTP endpoints) in workspace settings. SetGet's chat AI discovers their tools and can invoke them as part of an action plan.
- Inbound — mint workspace-scoped bearer tokens and connect external LLM hosts (Claude Desktop, ChatGPT, custom agents) to SetGet's own action surface. They get a curated 26-tool catalog covering issues, cycles, modules, pages, comments, docs, and staffing.
Where to find it
- Outbound MCP servers:
Workspace settings → Developer → MCP Servers - Inbound bearer tokens:
Workspace settings → Developer → MCP Tokens
Both pages are admin-only.
Outbound — connect an external MCP server
1. Add the server
Open Workspace settings → Developer → MCP Servers and click Add server. Fill in:
| Field | Notes |
|---|---|
| Name | Short label that shows up in the chat AI's tool catalog (e.g. Slack — production) |
| Endpoint | The remote MCP server's HTTPS URL |
| Transport | HTTP for unary JSON-RPC, SSE for streamed responses |
| Auth | none, bearer, or header (custom header name + value) |
| Secret | The bearer token or header value — stored encrypted, never shown again |
| Description | Optional one-liner shown beneath the row |
| Enabled | Disabled servers are not advertised to the chat AI |
Click Add server. SetGet runs an initial tools/list discovery against the endpoint right away.
2. Verify the tool catalog
Each server row shows:
- A status pill (
enabled/disabled). - Transport + auth type.
- The endpoint URL.
- The last discovery timestamp and any last error (auth, network, schema).
- An expandable Show tools list once discovery has succeeded.
If the row shows a last_error, fix the credentials / URL and click Discover to retry.
3. Use the tool from chat
Inside any project chat in BUILD mode, ask the AI in plain language:
"Use Slack to send a message to #releases saying we just shipped 1.4.0."
The AI picks the matching tool (Slack — send_message), proposes a mcp_call action, and waits for confirmation:
I'll send that to #releases via Slack.
:::action
{"type":"mcp_call","data":{"server_id":"…","tool_name":"send_message","arguments":{"channel":"#releases","text":"Just shipped 1.4.0 🎉"}}}
:::On confirm the call leaves SetGet, the response comes back as a chat turn summarising the result.
4. Rotate or revoke
- Rotate the secret: Edit the server, enter a new value in the Secret field. Empty Secret preserves the existing credential.
- Pause the integration: toggle Enabled off. The server stays in the registry but is no longer advertised to chat.
- Remove it entirely: click Delete. Both the server row and the encrypted secret row are dropped.
Inbound — let an external LLM host drive SetGet
1. Mint a bearer token
Open Workspace settings → Developer → MCP Tokens and click Generate token.
Give the token a label that names who will hold it — e.g. Claude Desktop on Alice's MacBook, or Marketing ChatGPT Connector. This is the only handle you'll have when you need to revoke it later.
Copy the token now
The raw token (kmt_…) is shown to you exactly once. SetGet stores only its SHA-256 hash; if you close the banner before copying, you have to mint a new token. Store it in your password manager or paste it straight into the LLM client.
2. Connect the LLM host
Configure your MCP client to point at SetGet's inbound endpoint:
URL: https://<your-setget-domain>/mcp/v1/
Auth: Authorization: Bearer kmt_<your-token>For Claude Desktop, add a server to claude_desktop_config.json:
{
"mcpServers": {
"setget": {
"url": "https://app.setget.ai/mcp/v1/",
"headers": {
"Authorization": "Bearer kmt_<your-token>"
}
}
}
}Restart the host. It will run initialize + tools/list against SetGet and surface 26 tools.
3. What tools are exposed
The inbound catalog covers the safe subset of SetGet's native actions:
- Issues —
setget.issue.create,update,change_state,assign,add_label,remove_label,update_priority,set_due_date. - Cycles & modules —
setget.cycle.create,setget.cycle.add_issues,setget.cycle.remove_issues, plus the equivalent module trio. - Pages —
setget.page.create,setget.page.update. - Comments —
setget.comment.create. - Workspace docs —
setget.doc.rename,archive,restore,duplicate,set_access,toggle_favorite,create_child. - Staffing —
setget.position.assign,setget.position.unassign.
Each tool's input_schema mirrors the native action's data contract, so an external LLM can plan its calls correctly using just the schema.
4. What is NOT exposed (and why)
Five action types are deliberately excluded:
| Excluded | Reason |
|---|---|
bulk_update_issues | Runs a multi-stage LLM planner inside SetGet; external hosts should plan their own bulk operations. |
generate_project | Multi-minute multi-agent project generation; needs the in-app review UI. |
apply_doc_edit_plan | Channel-isolated to the doc editor; calling it from outside corrupts the document. |
translate_entire_doc, extract_action_items_to_issues | Sibling channel-specific operations. |
mcp_call | Recursion footgun — would let an external host chain calls through SetGet to another MCP server. |
5. Security model
- Tokens are workspace-scoped. A leaked token cannot reach data in another workspace.
- Cross-workspace argument references are rejected at the inbound handler (
mcp.inbound.unauthorizedfor bad auth,ai.action.workspace_scopefor cross-workspace ids) — even if a native executor has a leaky scope check, the bearer gate catches it. - Tokens never appear in plaintext after creation. The list view shows only
kmt_***<last_four>. - Revoke sets
revoked_aton the row; the bearer-auth middleware rejects revoked tokens immediately on the next request. The row stays in the audit log.
Troubleshooting
Outbound: "auth" stage failure on discovery
The remote server returned 401 or 403. Verify the Secret + (for custom headers) the Auth header name match what the upstream MCP server expects. After updating, click Discover to retry.
Outbound: "dial" stage failure
DNS or TCP failure — the endpoint URL is unreachable from SetGet's servers. Check the URL and that the remote service is online.
Inbound: external host returns mcp.inbound.unauthorized
The token was revoked, mistyped, or the workspace it points to was deleted. Mint a fresh token from settings.
Inbound: tool call returns ai.action.workspace_scope
The external LLM passed an id (project, issue, cycle, …) that lives in a different workspace from the bearer token's. This is the cross-workspace guard rejecting the request. Have the external host fetch ids via tools/call first instead of caching them across workspaces.
Related
- SetGet AI overview — what the chat AI can do on its own.
- AI actions reference — the full native action catalog (only a curated subset is exposed inbound).
- ADR 009 (internal docs) — architecture, security model, deferred items.