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 strategic visions with cursor pagination: the company vision first, then product visions. Optionally filter by kind (company, product).
Get a vision
Version snapshots of a vision, newest first, with cursor pagination. Every name or narrative edit creates one.
The objectives anchored to this vision, with cursor pagination.
List strategic objectives with cursor pagination. Optionally scope to a vision.
Get an objective
The opportunities linked to this objective, with their link metadata.
List metrics tracked by the organisation, with cursor pagination.
Get a metric
Recorded values for a metric, ascending by recorded time; when limit caps the count, the newest values are kept. Optionally filter by date (since).
List strategies with cursor pagination. Optionally filter by status (draft, active, archived).
Get a strategy
Version snapshots of a strategy, newest first, with cursor pagination. Every content edit creates one.
List opportunities with cursor pagination. Optionally filter by lifecycle state or team.
Get a specific opportunity by id.
The tasks attached to this opportunity, with cursor pagination.
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).
Get an opportunity's scorecard: the org's active scoring criteria (name, weight, invert), the shared 1-5 values with attribution, and the computed 0-100 total (null until every criterion is scored).
List tasks with cursor pagination. 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 recurring-task definitions with cursor pagination: each one's schedule (human-readable cadence + next occurrence), team, owner, and template. These are the definitions a background sweep materializes into real tasks; use list to see the tasks they produced.
Get a recurring-task definition by id.
List customer insights (the customer-voice evidence layer). Optionally filter by lifecycle status or customer.
Get an insight with its demand root, links, tags, and committed impacts.
List tags (with usage counts) so you can cluster insights onto existing tags instead of minting duplicates.
List customers with cursor pagination. Optionally filter by status.
Get a customer
List the named people on a customer account, primary contact first, then newest. Use a contact's id to attribute an insight to the person who said it.
List teams in the organisation, with cursor pagination.
Get a team
List team members
List org members with cursor pagination.
Get a user
List the rooms the authenticated user is a member of (DMs, group channels, system rooms), with unread counts and your per-room state, most recently active first.
Get a room by UUID with your membership role. Members always read; any org user reads an open group channel; a private group, DM, or system room without a membership row is forbidden.
List a room's top-level messages, newest first, with cursor pagination (service-capped at 100 per page). Rows carry author, reactions, attachments, and thread reply counts; fetch a thread's replies with the thread action. Requires read access to the room (member, or any org user for an open group channel).
List the replies threaded under a top-level message, newest first, with cursor pagination. Requires read access to the message's room.
List the org's workflow templates with cursor pagination, each with its category label.
Get a workflow template with its ordered steps. The terminal Completed/Cancelled pair is system-managed and not included.
List the org's workflow categories in display order (used to group workflows and to classify time entries).
Get a workflow category
List the PRD templates visible to the key's user: shared (org-wide) templates plus those owned by the user's teams.
Get a PRD template
List time entries in a date range (from/to, max 366 days), newest first, with cursor pagination. Defaults to the authenticated user's own entries. engineerId reads another engineer's entries and requires the salary read permission (compensation:read); a team-scoped grant admits only engineers on the caller's teams.
Total hours in a date range bucketed by workflow category, across all engineers in the org (optionally filtered to one team's members). Cost reporting: requires an org-wide cost:read grant.
Hydrated time entries for every engineer in a date range (hours, derived cost, engineer, category, target), capped at 5000 rows; `truncated` flags the cap. Cost reporting: requires an org-wide cost:read grant.
Sum of hours times each entry's snapshotted hourly rate for every time entry logged against the opportunity. Returns 0 when nothing is logged. Requires an org-wide cost:read grant.
Sum of hours times each entry's snapshotted hourly rate for every time entry logged against the task. Returns 0 when nothing is logged. Requires an org-wide cost:read grant.
List the org's outbound webhook subscriptions. Secrets are write-once and never returned.
List the authenticated user's notifications, newest first, with cursor pagination. Filter to unread only, pinned only, or a set of notification types.
Count the authenticated user's unread notifications.
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.
Create a customer account (name plus optional profile, owner, ARR, and lifecycle status; status defaults to prospect).
Update a customer's profile, owner, ARR, health, or lifecycle status. Moving to churned/lost requires a reason (stored as an insight rooted at the customer); moving to onboarding activates the org's default onboarding workflow.
Hard-delete an account and its insights. Contacts, events, reviews, updates, and opportunity links go with it; linked opportunities survive.
Add a named person to a customer account (name plus optional title, role, email, phone, and notes). Marking the contact primary demotes the account's existing primary.
Update a contact's details. Promoting a contact to primary demotes the account's existing primary.
Remove a contact from a customer account. Insights attributed to the contact survive and fall back to the customer as their demand root.
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. Owner-only; ACL enforced by the service.
Publish a draft strategy, making it the active version. Owner-only; ACL enforced by the service.
Archive a strategy, retiring it from the active set. Owner-only; ACL enforced by the service.
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 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 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 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.
Set one scorecard value on an opportunity: a shared 1-5 value for one of the org's scoring criteria (last write wins, attributed to the caller). Use get_opportunity_scorecard for criteria ids and the computed total.
Clear one scorecard value on an opportunity (the total returns to null until re-scored).
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.
Post a status update on an opportunity, authored by the key's user. It lands in the opportunity's updates stream and flows into every linked customer's feed. For a plain discussion comment, use create_comment.
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-status, which also auto-assigns an owner to ownerless work.
Permanently delete a task. Its time entries, tags, checklist items, and insight links go with it, and its dependency edges are cleared; any subtasks are detached and survive as standalone tasks. To retire work without losing the record, set its status to cancelled instead.
Set a task's status. Moving an ownerless task to todo/in_progress assigns the caller as its owner — work in flight is never ownerless.
Post the handoff note for a completed subtask in a sequential task, briefing the next owner. Complete the subtask first (set-status), then write the note; it lands on the parent task's thread and clears the pending-note reminder.
Define a recurring task: an RRULE schedule plus a task template. A background sweep creates one real task for the given team on every occurrence (status todo, due = occurrence + dueOffsetDays). This creates the DEFINITION, not a single task — use create for a one-off. rrule is an iCal RRULE string (e.g. 'FREQ=WEEKLY;BYDAY=MO'); dtstart/tzid default to now/UTC and it never backfills.
Update a definition's schedule, template, or active flag. Editing the schedule recomputes forward from now, never retroactively.
Pause or resume a recurring-task definition. Paused definitions stop materializing tasks; resuming never backfills the paused gap.
Delete a recurring-task definition. Tasks it already created stay; no new ones are generated.
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 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.
Create a tag for clustering insights. List existing tags first (list_tags) and reuse them rather than minting duplicates.
Post a comment on a task or opportunity, authored by the key's user. It lands on the entity's discussion thread. For an opportunity status broadcast that flows into linked customers' feeds, use post_opportunity_update instead.
Record a customer insight (one discrete signal, not a whole document). Roots at exactly one demand source: a customer, an internal stakeholder (org user), or an other stakeholder (externalStakeholderId — a named voice with no Telos seat). Optionally set source, moscow priority, deadline, tagIds for clustering, a reviewTeamId to route it into a team's review queue, and attach to an opportunity/task/objective.
Update an insight's verbatim, source, demand root, contact, moscow priority, or deadline. The service keeps exactly one demand root after the merge.
Permanently delete an insight and its links. Prefer the review lifecycle (reject/archive) to record an outcome; delete is for mistakes.
Link an existing insight to an opportunity, task, or objective (optionally pinned).
Create a PRD template (markdown scaffold for opportunity PRDs). teamId scopes it to a team; omit for a shared org-wide template, which requires the prd_template:update capability.
Update a PRD template's name, content, or team scope.
Delete a PRD template. Opportunities that already applied it keep their PRD content.
Subscribe an HTTPS endpoint to outbound events. Deliveries are signed with the secret (t=/v1= scheme); the secret is encrypted at rest and never returned, so store it now.
Delete a webhook subscription. Deliveries stop immediately.
Create a workflow template. Optionally set a categoryId to group it. Every workflow closes with system-managed Completed and Cancelled steps; add real steps with create-step.
Update a workflow's name, description, category, or default entity type.
Delete a workflow template. Refused while active tasks or opportunities are using it.
Append a step to a workflow, ahead of the terminal pair. Owner defaults to the caller when defaultDriUserId is omitted.
Update a step's title, description, position, owner, or SLA. Terminal steps are system-managed and can't be edited.
Delete a step and close the position gap. Refused for terminal steps and for steps active work is currently on.
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.
Create a workflow category. The slug is derived from the label; color is a theme token or hex value.
Update a category's label, color, or sort order. The slug never changes.
Delete a workflow category. The system Bug and Incident categories can't be deleted, nor can a category time entries still reference.
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.
Log time for the authenticated user against exactly one target: an opportunity (opportunityId), a task (taskId), or a misc workflow category (miscCategoryId, which requires a note). Hours are 0-24 per entry.
Update one of your own time entries (entryDate, hours, note). Only the engineer who logged an entry may edit it.
Delete one of your own time entries. Only the engineer who logged an entry may delete it.
Create a group channel with at least one other org member; the creator becomes its admin. Visibility 'open' (default) lets any org user read and join; 'private' is invite-only. DMs are started in-app, not here.
Rename a group channel or edit its description. Room-admin only; DMs and system rooms cannot be edited.
Archive a group channel, removing it from everyone's room list. Terminal: rooms have no hard delete. Room-admin only; DMs and system rooms cannot be archived.
Post a message to a room you can read, authored by the key's user. Pass parentId (a top-level message UUID) to reply in its thread; threads are two-level. @Name mentions in the body notify the named org members.
Edit one of your own messages; it is marked edited. Only the author may edit a message, and system messages cannot be edited.
Delete one of your own messages (soft delete; attachments are swept). Only the author may delete it on this surface.