whoami
Get the identity of the authenticated user.
Telos exposes curated tools over the Model Context Protocol so external agents can ground decisions in your product state and act on it. Every tool is gated by the calling key's capabilities; every write is idempotent and attributed to the key's user, through the same service layer as REST.
POST /api/mcp speaks the Streamable HTTP MCP transport. Auth is the same bearer token you use for REST: Authorization: Bearer telos_live_… (or an OAuth app token, telos_oat_…, limited to its granted scopes). Rate limits apply as on REST, and every tool below is gated by the calling key's capabilities — a read-only key sees writes returned as permission errors.
https://www.telos-app.com/api/mcpThree steps to wire Telos into an MCP client. The same endpoint and token work for any client that speaks the Model Context Protocol — pick yours in step 2.
Issue a key from inside the app at Configurations → API Keys. Keys start with telos_live_and carry the role that decides which tools and fields you see — copy it now, it's shown only once. The endpoint is the same origin you use Telos on, with /api/mcp appended — there's no per-account host. For this workspace that's https://www.telos-app.com/api/mcp, which is what the snippets below use.
Select your client. Most speak Streamable HTTP natively, so you give them the endpoint and token directly — only Claude Desktop's config launches local commands, so it bridges through mcp-remote.
Register the endpoint with one CLI command — run it from any project, or add --scope user to make it available everywhere.
claude mcp add --transport http telos \
https://www.telos-app.com/api/mcp \
--header "Authorization: Bearer telos_live_…"Add this to claude_desktop_config.json (Settings → Developer → Edit Config), then fully restart the app. The token lives in env because mcp-remote splits --header on the first space, which would otherwise break Bearer <token>.
{
"mcpServers": {
"telos": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://www.telos-app.com/api/mcp",
"--header",
"Authorization:${TELOS_AUTH}"
],
"env": {
"TELOS_AUTH": "Bearer telos_live_…"
}
}
}
}Add an [mcp_servers.telos] table to your Codex config. It takes the name of an env var holding the token, so export TELOS_TOKEN=telos_live_… in the same shell.
# ~/.codex/config.toml
[mcp_servers.telos]
url = "https://www.telos-app.com/api/mcp"
bearer_token_env_var = "TELOS_TOKEN"Add a workspace .vscode/mcp.json. The ${input:telos_token} reference makes VS Code prompt for the key the first time the server starts, then store it securely.
// .vscode/mcp.json
{
"servers": {
"telos": {
"type": "http",
"url": "https://www.telos-app.com/api/mcp",
"headers": { "Authorization": "Bearer ${input:telos_token}" }
}
},
"inputs": [
{
"type": "promptString",
"id": "telos_token",
"description": "Telos API key",
"password": true
}
]
}In a client, the Telos tools should now appear in the tool list. To check the endpoint and token directly, send the protocol handshake with curl — a 200 with a result confirms both connectivity and auth; a 401 means the key is missing or invalid:
curl -sN https://www.telos-app.com/api/mcp \
-H 'Authorization: Bearer telos_live_…' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'Once connected, ask the agent to call whoami to confirm which user and role the key resolves to. The full tool list is below.
Auto-rendered from the source registry. Every input parameter is validated against a Zod schema on the server.
Get the identity of the authenticated user.
List teams in the organisation.
List users in the organisation.
List visions in the organisation, most recent first.
Get a specific vision by id.
List the version history for a vision.
List strategic objectives. Optionally scope to a vision.
Get a specific strategic objective by id.
List metrics tracked by the organisation.
Get a specific metric by id.
List strategies in the organisation. Defaults to active.
List opportunities. Optionally filter by lifecycle state (active/completed/rejected) or team.
Get a specific opportunity by id.
Get everything needed to act on an opportunity in one call: the opportunity and PRD, linked objectives, the customer(s), comments, linked insights, the active workflow step, and any linked PRs. Sections you lack the read capability for (e.g. customers, insights) come back null. Pass the opportunity ref (e.g. OPP-23).
List tasks. Optionally filter by opportunity, status, priority, or team.
Get a specific task by id.
Get everything needed to act on a task in one call: the task spec, its parent opportunity and PRD, the customer(s), comments, linked insights, the active workflow step, and any linked PRs. Sections you lack the read capability for (e.g. the parent opportunity, customers, insights) come back null. Pass the task ref (e.g. TF-24).
List intake items. Optionally filter by status.
Get intake queue counts grouped by status and category.
List customers. Optionally filter by status.
Get a specific customer by id.
Each write wraps the same scoped service the REST API uses, so every mutation is typed, validated, audited, and attributed to the key's user — never a system actor. Each tool requires a specific capability; supply an idempotencyKey on any write you might retry so a repeat returns the first result instead of writing again.
Post a comment or update on a task or opportunity, authored by the key's user. Kind 'update' on an opportunity is a status broadcast: it lands in the updates stream and flows into every linked customer's feed. Kind 'user' (or any task post) is a plain comment on the entity's thread.
Create a task, attached to an opportunity (opportunityId) or standalone (bug fixes and maintenance are first-class). Optionally seed subtasks, owner, team, category, workflow, and tags in the same call.
Update a task's fields (title, description, content, priority, opportunity, team, category, subtask mode, estimate, due date). For a bare status move prefer set_task_status, which also auto-assigns an owner to ownerless work.
Set a task's status. Moving an ownerless task to todo/in_progress assigns the key's user as its owner — work in flight is never ownerless.
Move an opportunity or customer-onboarding workflow to a step and post a handoff message for it. Jumps to the target step instance (optionally completing the rest) and records the handoff note on the entity's thread. For a subtask sequence inside a task, use write_task_handoff instead.
Post the handoff note for a completed subtask in a sequential task, briefing the next owner. Complete the subtask first (set_task_status), then write the note; it lands on the parent task's thread and clears the pending-note reminder.
Create a work opportunity. The description seeds the PRD (or a PRD template does, when omitted). Optionally set lead, team, workflow, category, initial objective links, and tags. Financial fields are ACL-gated.
Update an opportunity's title, lead, team, or PRD body. Lifecycle moves go through write_handoff (workflow steps) or reject_opportunity, not here.
Permanently delete an opportunity and its dependency edges. Prefer reject_opportunity to record a won't-build decision; delete is for mistakes, not outcomes.
Tie an opportunity to an objective (membership only: 'this bet claims to matter for that number'). Impact evidence lives on insights, not the link.
Repoint an opportunity's objective link at a different objective.
Remove the tie between an opportunity and an objective.
Reject an opportunity: skips remaining workflow steps, lands it on the Cancelled terminal step (or flips a workflow-less one to cancelled), and records the categorized won't-build decision on the thread.
Create a strategic objective under a vision. The objective IS the commitment to a number: it requires a DRI and a metric block (metricId, operator, target).
Update an objective's title, description, deadline, DRI, or status.
Permanently delete an objective.
Replace which metric an objective points at, and/or change its target shape (operator, target, start value). An objective has exactly one metric.
Create a metric (name, unit, optional data source and steward).
Update a metric's name, description, unit, data source, or steward.
Permanently delete a metric.
Record an observed value for a metric. recordedAt defaults to now; pass it to backfill history.
Create a strategy (name plus a markdown content body). Starts as a draft.
Update a strategy's name or content. An optional changeNote labels the version this edit creates.
Publish a draft strategy, making it the active version.
Archive a strategy, retiring it from the active set.
Create a vision: the company vision (kind 'company', one per org) or a product vision (kind 'product'). The narrative is the persuasive 2-5 year story, not a slogan.
Update a vision's name or narrative. Edits are versioned.
Create a team. The 2-4 character prefix becomes the team's task ref prefix (e.g. ENG-42).
Update a team's name, description, ref prefix, or default PRD template.
Delete a team. Its opportunities/tasks/intake keep their rows (team unset, refs stable); memberships and team-scoped config are removed. Refuses to delete the org's only team.
Add a user to a team's roster.
Remove a user from a team's roster.
Update an org member's profile (name, weekly hours). Salary fields require a leadership role and travel as a pair; role changes need org:manage, which API keys never carry.
Record a customer insight (one discrete signal, not a whole document). Requires a customerId; optionally set source, moscow priority, deadline, tagIds for clustering, and attach to an opportunity/task/objective.
Link an existing insight to an opportunity, task, or objective (optionally pinned).
Create a tag for clustering insights. List existing tags first (list_tags) and reuse them rather than minting duplicates.
Mark one of your notifications read.
Mark all of your notifications read.
Pin one of your notifications so it stays at the top of the inbox.
Unpin one of your notifications.
Unsubscribe from the entity a notification came from, muting its future notifications for you.