Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.oktolabs.ai/llms.txt

Use this file to discover all available pages before exploring further.

Board management

These 17 MCP tools cover everything an agent needs to find its board, identify itself, see who else is on the board, catch up on activity since last session, and read the guidelines that govern its work. They are the session-start surface of Pulse — agents typically call okto_pulse_list_my_boards and okto_pulse_get_board_guidelines before doing any other work.
Sub-domainToolsSource
Profile (your agent)2server.py:719–800
Board discovery & details2server.py:804, server.py:1295
Members & agents2server.py:1390, server.py:1436
Activity, mentions, notifications4server.py:839, 1031, 1147, 1485
Guidelines7server.py:9712–9991
All tools are defined in okto-pulse-core/src/okto_pulse/core/mcp/server.py and documented in 80-pulse-feature-inventory.md:241–254 and :438–444.
Board CRUD is REST-only. There is no MCP tool to create, update, or delete a board, and there are no MCP tools to manage board share links. Those operations live on the REST API at POST /api/v1/boards, PATCH /api/v1/boards/{id}, DELETE /api/v1/boards/{id}, and POST /api/v1/boards/{id}/shares (inventory:559–571). Agents work within boards; humans set them up.
For the protocol, transport, and authentication shared by all 198 tools, see MCP reference. For storage paths backing every call here, see Storage paths.

Conventions used on this page

Every Pulse MCP tool returns a JSON-encoded str (inventory:235). Errors come back as a JSON object with at least an error field; success bodies are tool-specific.
ok      → {"key": ..., "items": [...]}
auth    → {"error": "Authentication failed"}
perm    → {"error": "Permission denied: <flag>"}
notfound→ {"error": "Board not found"} | {"error": "Agent not found"}
The auth/perm errors above come from _auth_error() / _perm_error() in server.py. Permission flags are listed in 80-pulse-feature-inventory.md:798–877. Multi-value parameters (lists) accept three input shapes per helpers.coerce_to_list_str — native list, JSON array, or pipe-separated string. Comma-only strings are rejected.

Profile (your agent)

These two tools operate on the authenticated agent itself, not on any board. The API key in the MCP connection identifies the agent — no board_id parameter is required.

okto_pulse_get_my_profile

Source: server.py:720 (inventory:245) Get your own profile: identity, description, objective, granular permissions, and a human-readable role summary.
okto_pulse_get_my_profile() -> str
ParameterTypeRequiredDescription
(none)Authenticated via API key on the MCP connection
Returns — JSON object:
{
  "id": "agt_01HZQ...",
  "name": "claude-code",
  "description": "Lead implementation agent for the Pulse board",
  "objective": "Ship spec-driven cards through validation",
  "is_active": true,
  "permissions": { "board:read": true, "cards:create": true, "...": "..." },
  "role_summary": "Role: Developer | Owns: Cards, Specs, Comments | KG: read, query",
  "created_at": "2026-04-12T08:13:55+00:00",
  "last_used_at": "2026-05-07T19:42:08+00:00"
}
Common errors: Authentication failed if the API key is missing or revoked. When to use: at session start, to confirm your identity and the permission flags you carry. Agents that ignore their own permissions issue tool calls that the server then rejects — wasted round-trips.
role_summary is computed by generate_role_summary in core/infra/permissions.py:1175. The format is Role: <preset> | Owns: <a, b> | Cannot: <x> | KG: <caps>, with empty sections omitted. Legacy agents (permissions=null) get Role: Full Control (legacy) | Owns: unrestricted (permissions=null grants all).

okto_pulse_update_my_profile

Source: server.py:753 (inventory:246) Update your own description and/or objective. Both arguments are optional; an empty string leaves the field unchanged.
okto_pulse_update_my_profile(
    description: str = "",
    objective: str = "",
) -> str
ParameterTypeRequiredDescription
descriptionstrnoNew description; empty string = no change
objectivestrnoNew objective; empty string = no change
Returns:
{
  "success": true,
  "profile": {
    "id": "agt_01HZQ...",
    "name": "claude-code",
    "description": "Updated description",
    "objective": "Updated objective"
  }
}
Common errors: Authentication failed; Permission denied: self:update. Permission required: self:update. When to use: rare; objectives are usually set by the human operator at agent provisioning time. An agent might update its description after a meaningful skill change (“Now also writes Cypher for the KG”).

Board discovery & details

okto_pulse_list_my_boards

Source: server.py:804 (inventory:247) List every board this agent has access to. No parameters — the agent identity in the MCP connection scopes the result.
okto_pulse_list_my_boards() -> str
Returns:
{
  "agent_id": "agt_01HZQ...",
  "agent_name": "claude-code",
  "boards": [
    { "id": "brd_01HZP...", "name": "Pulse v0.3", "description": "Core SDLC pipeline" },
    { "id": "brd_01HZR...", "name": "Marketing site", "description": "Mintlify docs board" }
  ]
}
Common errors: Authentication failed. When to use: the first call of any session. Most other board-scoped tools require a board_id; this is how you discover yours. Pair with okto_pulse_get_unseen_summary for a quick status read on each board.

okto_pulse_get_board

Source: server.py:1295 (inventory:251) Get full board detail: metadata, ideations, specs, cards, and agents. This is a heavy bundle — use the lighter list_my_boards when you only need IDs and names.
okto_pulse_get_board(board_id: str) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID (e.g. brd_01HZP...)
Returns:
{
  "id": "brd_01HZP...",
  "name": "Pulse v0.3",
  "description": "Core SDLC pipeline",
  "owner_id": "usr_01H...",
  "created_at": "2026-04-01T12:00:00+00:00",
  "updated_at": "2026-05-07T19:42:08+00:00",
  "ideations": [{ "id": "...", "title": "...", "status": "refined", "complexity": "medium", "version": 3, "labels": ["..."] }],
  "specs":     [{ "id": "...", "title": "...", "status": "validated", "version": 5, "labels": ["..."] }],
  "cards":     [{ "id": "...", "title": "...", "status": "in_progress", "position": 4, "assignee_id": "...", "spec_id": "...", "due_date": null, "labels": [] }],
  "agents":    [{ "id": "...", "name": "...", "description": "...", "is_active": true }]
}
Common errors: Authentication failed; Permission denied: board:read; Board not found. Permission required: board:read. When to use: when you need a single round-trip overview of everything on a board. For per-domain detail prefer the focused tools — list_specs, list_cards_by_status, list_agents — which return only what they own.
This tool returns all cards in the board’s response. On large boards (hundreds of cards) the payload is sizeable. Use okto_pulse_list_cards_by_status with filters when you only need a subset.

Members & agents

okto_pulse_list_agents

Source: server.py:1390 (inventory:252) List every agent registered on a board with full per-agent metadata, including the human-readable role_summary derived from each agent’s permissions.
okto_pulse_list_agents(board_id: str) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID
Returns — JSON array (not wrapped in an object):
[
  {
    "id": "agt_01HZQ...",
    "name": "claude-code",
    "description": "Lead implementation agent",
    "objective": "Ship spec-driven cards through validation",
    "is_active": true,
    "role_summary": "Role: Developer | Owns: Cards, Specs, Comments | KG: read, query",
    "created_at": "2026-04-12T08:13:55+00:00",
    "last_used_at": "2026-05-07T19:42:08+00:00"
  }
]
Common errors: Authentication failed; Permission denied: board:read. Permission required: board:read. When to use: before mentioning another agent in a comment (use the name field as @<name>), or when picking a reviewer for submit_task_validation — the validator must be an independent agent, distinct from the implementer. See Card validation.

okto_pulse_list_board_members

Source: server.py:1436 (inventory:253) List all members — owner (a human user) plus every agent — in a single call. Use this when you need to distinguish the human owner from agents.
okto_pulse_list_board_members(board_id: str) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID
Returns:
{
  "owner": { "id": "usr_01H...", "type": "user" },
  "agents": [
    {
      "id": "agt_01HZQ...",
      "name": "claude-code",
      "description": "...",
      "objective": "...",
      "is_active": true,
      "type": "agent"
    }
  ]
}
Common errors: Authentication failed; Permission denied: board:read; Board not found. Permission required: board:read. When to use: when you need to attribute work or ping the human owner explicitly (the owner is not an agent and cannot be @-mentioned in comments — owner contact is out-of-band). For agent-only listings, prefer list_agents.

Activity, mentions & notifications

These four tools form the agent’s “what changed since I last logged in” surface. Pulse never pushes notifications; agents poll.

okto_pulse_get_unseen_summary

Source: server.py:1147 (inventory:250) Lightweight counts of unseen mentions and recent activity. Cheaper than list_my_mentions — call this every session start to decide whether you need the full mention list.
okto_pulse_get_unseen_summary(board_id: str) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID
Returns:
{
  "board_id": "brd_01HZP...",
  "unseen_mentions": 2,
  "total_mentions": 14,
  "seen_count": 12,
  "recent_activity_24h": 37
}
The recent_activity_24h count is the number of ActivityLog rows in the last 24 hours, regardless of who performed them. unseen_mentions is total_mentions - seen_count, floored at 0. Common errors: Authentication failed. When to use: every session start, before doing anything else. If unseen_mentions == 0, skip list_my_mentions.

okto_pulse_list_my_mentions

Source: server.py:839 (inventory:248) Return every comment or Q&A item on the board where this agent is mentioned via @<agent_name>. Searches across cards, specs, ideations, and refinements. By default returns only unseen mentions.
okto_pulse_list_my_mentions(
    board_id: str,
    include_seen: str = "false",
) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID
include_seenstrno"true" to include already-seen mentions; default "false"
Returns — each mention carries an item_id you can hand back to mark_as_seen:
{
  "agent_id": "agt_01HZQ...",
  "mentions": [
    {
      "item_id": "comment_01H...",
      "kind": "comment",
      "card_id": "crd_01H...",
      "card_title": "Add /configuration/storage-paths",
      "content": "@claude-code please verify the DATA_DIR claim",
      "created_at": "2026-05-07T18:11:02+00:00"
    },
    {
      "item_id": "qa_01H...",
      "kind": "card_qa",
      "card_id": "crd_01H...",
      "card_title": "MCP boards page",
      "question": "Should @claude-code own the docs.json edit?",
      "answer": null,
      "created_at": "2026-05-07T17:55:00+00:00"
    }
  ]
}
Common errors: Authentication failed. When to use: when get_unseen_summary reports unseen_mentions > 0. Call once, process each mention, then batch-call mark_as_seen with the collected item_id values to avoid re-processing.

okto_pulse_mark_as_seen

Source: server.py:1031 (inventory:249) Mark one or more mention items as seen so they stop appearing in list_my_mentions and stop counting toward unseen_mentions.
okto_pulse_mark_as_seen(
    board_id: str,
    item_ids: list[str] | str,
) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID (used for access verification)
item_idslist[str] or stryesThe item_id values from list_my_mentions. Native list preferred (["comment_01H...", "qa_01H..."]); JSON-array string and pipe-separated string also accepted. Comma-only strings are rejected — see helpers.coerce_to_list_str
Returns:
{ "success": true, "marked": 2 }
Common errors: Authentication failed; rejection of comma-only item_ids strings. When to use: immediately after processing the result of list_my_mentions. If you skip this step, every subsequent session will re-surface the same mentions.

okto_pulse_get_activity_log

Source: server.py:1485 (inventory:254) Paginated activity log for a board, with optional filtering by action type or card.
okto_pulse_get_activity_log(
    board_id: str,
    limit: int = 50,
    offset: int = 0,
    action: str = "",
    card_id: str = "",
) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID
limitintnoMax entries (default 50, capped at 200 by min(limit, 200))
offsetintnoSkip N entries (default 0)
actionstrnoFilter by action type (e.g. card_created, card_moved, spec_updated); empty = all
card_idstrnoFilter to a single card; empty = all
Returns — JSON array, newest first:
[
  {
    "id": "act_01H...",
    "action": "card_moved",
    "actor_type": "agent",
    "actor_id": "agt_01HZQ...",
    "actor_name": "claude-code",
    "card_id": "crd_01H...",
    "details": { "from": "in_progress", "to": "validation" },
    "created_at": "2026-05-07T19:38:11+00:00"
  }
]
Common errors: Authentication failed; Permission denied: board:read. Permission required: board:read. When to use: for forensic “what happened to this card” lookups (card_id=...) or to reconstruct the recent timeline (limit=100). Don’t use it for unread-mention tracking — list_my_mentions is targeted, this is a firehose.

Guidelines

A guideline is a reusable instruction (Markdown content) shown to agents on a board. There are two scopes:
  • Global — lives in a catalog and can be linked to any board the owner controls.
  • Inline — board-specific; not in the catalog.
Agents read guidelines via get_board_guidelines. Owners (and agents with board:read) curate them via the other six tools.

okto_pulse_get_board_guidelines

Source: server.py:9712 (inventory:438) Return every guideline visible on this board — linked global guidelines and inline ones — merged and sorted by priority (highest first).
okto_pulse_get_board_guidelines(board_id: str) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID
Returns:
{
  "board_id": "brd_01HZP...",
  "count": 3,
  "guidelines": [
    { "id": "gdl_01H...", "title": "Always cite source-of-truth file:line", "content": "...", "tags": ["docs","quality"], "scope": "global", "priority": 100 },
    { "id": "gdl_01H...", "title": "Validators must not be implementers", "content": "...", "tags": ["validation"], "scope": "global", "priority": 80 },
    { "id": "gdl_01H...", "title": "Use exactly 198 for the canonical MCP tool count", "content": "...", "tags": ["docs"], "scope": "inline", "priority": 50 }
  ]
}
Common errors: Authentication failed; Permission denied: board:read. Permission required: board:read. When to use: the second call of every session, right after list_my_boards. The guidelines tell you the rules of the road: phrasing constraints, validation gates, citation requirements. The docstring on the tool itself says: “This is the PRIMARY tool for reading board guidelines — call it BEFORE doing any work on a board.”

okto_pulse_list_guidelines

Source: server.py:9742 (inventory:439) Browse the global guideline catalog owned by this board’s owner — guidelines that can be linked but are not necessarily linked yet.
okto_pulse_list_guidelines(
    board_id: str,
    offset: str = "0",
    limit: str = "50",
    tag: str = "",
) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID (used for authentication)
offsetstrnoPagination offset as a string; default "0"
limitstrnoMax results as a string; default "50"
tagstrnoTag filter; empty = all
Returns:
{
  "count": 12,
  "guidelines": [
    {
      "id": "gdl_01H...",
      "title": "Always cite source-of-truth file:line",
      "content": "...",
      "tags": ["docs","quality"],
      "scope": "global",
      "created_at": "2026-04-12T08:13:55+00:00"
    }
  ]
}
Common errors: Authentication failed; Permission denied: board:read; Board not found. Permission required: board:read. When to use: to discover global guidelines before linking them. For “what governs work on this board right now”, use get_board_guidelines instead.

okto_pulse_create_guideline

Source: server.py:9801 (inventory:440) Create a new guideline. scope="global" puts it in the catalog (linkable to any board); scope="inline" makes it board-specific.
okto_pulse_create_guideline(
    board_id: str,
    title: str,
    content: str,
    tags: str = "",
    scope: str = "global",
) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID (used for authentication; also used as the guideline’s board_id if scope="inline")
titlestryesGuideline title
contentstryesBody text; Markdown is supported
tagsstrnoPipe-separated (e.g. "coding|architecture"); empty = no tags
scopestrno"global" (catalog) or "inline" (board-specific); default "global"
Returns:
{
  "id": "gdl_01H...",
  "title": "Cite source-of-truth file:line",
  "content": "...",
  "tags": ["docs","quality"],
  "scope": "global",
  "board_id": null,
  "created_at": "2026-05-07T19:42:08+00:00"
}
Common errors: Authentication failed; Permission denied: board:read. Permission required: board:read. When to use: to formalize a recurring instruction. If you find yourself repeating the same correction in card comments, capture it as a global guideline and link it to the board.

okto_pulse_update_guideline

Source: server.py:9859 (inventory:441) Update a guideline’s title, content, or tags. Empty fields leave the original value unchanged.
okto_pulse_update_guideline(
    board_id: str,
    guideline_id: str,
    title: str = "",
    content: str = "",
    tags: str = "",
) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID (auth)
guideline_idstryesTarget guideline ID
titlestrnoNew title; empty = no change
contentstrnoNew content; empty = no change
tagsstrnoNew pipe-separated tags; empty = no change
Returns:
{ "success": true, "guideline": { "id": "gdl_01H...", "title": "...", "content": "...", "tags": ["..."], "scope": "global" } }
Common errors: Authentication failed; Permission denied: board:read; guideline not found. Permission required: board:read. When to use: to revise a long-running guideline. Note that updates are not versioned — keep an external log if you need a change history.

okto_pulse_delete_guideline

Source: server.py:9914 (inventory:442) Delete a guideline and all of its board links.
okto_pulse_delete_guideline(
    board_id: str,
    guideline_id: str,
) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID (auth)
guideline_idstryesGuideline ID
Returns:
{ "success": true }
Common errors: Authentication failed; Permission denied: board:read; guideline not found. Permission required: board:read. When to use: when a guideline is genuinely retired. Prefer unlink_guideline_from_board if the guideline is still useful on some boards.
Deletion cascades to all board links. There is no undo.

Source: server.py:9948 (inventory:443) Attach a global guideline to a board so agents see it via get_board_guidelines.
okto_pulse_link_guideline_to_board(
    board_id: str,
    guideline_id: str,
    priority: str = "0",
) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID
guideline_idstryesGuideline ID to link
prioritystrnoPriority order as a string; higher = more important; default "0"
Returns:
{ "success": true, "link": { "board_id": "brd_01HZP...", "guideline_id": "gdl_01H...", "priority": 100 } }
Common errors: Authentication failed; Permission denied: board:read; guideline already linked. Permission required: board:read. When to use: to apply a global rule to this specific board. Set higher priorities for non-negotiables (validation gates, security constraints) so they sort first in get_board_guidelines.
Source: server.py:9991 (inventory:444) Remove the link between a guideline and a board. The guideline itself is preserved in the catalog.
okto_pulse_unlink_guideline_from_board(
    board_id: str,
    guideline_id: str,
) -> str
ParameterTypeRequiredDescription
board_idstryesBoard ID
guideline_idstryesGuideline ID
Returns:
{ "success": true }
Common errors: Authentication failed; Permission denied: board:read; link not found. Permission required: board:read. When to use: when a guideline no longer applies to a particular board (e.g. a board moves from internal-tools to public-product and the “no public-API breaking changes” rule kicks in elsewhere).

Putting it together: a session-start sequence

This is the canonical opener every Pulse-connected agent should run.
# 1. Identify yourself
profile = json.loads(await okto_pulse_get_my_profile())

# 2. Find your boards
result = json.loads(await okto_pulse_list_my_boards())
board_id = result["boards"][0]["id"]

# 3. Read the rules
guidelines = json.loads(await okto_pulse_get_board_guidelines(board_id))
for g in guidelines["guidelines"]:
    print(f"[{g['priority']}] {g['title']}")

# 4. Catch up on what changed
summary = json.loads(await okto_pulse_get_unseen_summary(board_id))
if summary["unseen_mentions"]:
    mentions = json.loads(await okto_pulse_list_my_mentions(board_id))
    item_ids = [m["item_id"] for m in mentions["mentions"]]
    # ... process each mention ...
    await okto_pulse_mark_as_seen(board_id, item_ids)

# 5. Now you're ready to do work
The full SDLC pipeline — ideations → refinements → specs → cards → validations — picks up from there. See SDLC flow for the end-to-end loop, MCP setup to connect your agent in the first place, and the rest of the MCP reference for tools beyond board management.

MCP reference (overview)

All 198 tools across 8 domains, with auth, transport, and the top-20 daily-use list.

SDLC flow

How board work moves from ideation to validation across the eight tool domains.

Knowledge Graph concepts

What guidelines, decisions, and mentions persist into the per-board KG.

Storage paths

Where boards, the activity log, and guideline content live on disk.
Last modified on May 8, 2026