Documentation menu

    Connect your AI assistant

    Add Aztra to Claude, ChatGPT, Cursor, VS Code or any MCP client, and let it work in your workspace as you.

    Aztra runs an MCP server — the open Model Context Protocol that AI assistants use to work with external tools. Connect it once and your assistant can read and update issues, sprints, goals, wiki pages and time logs directly, acting as you and limited to what you can already see and do.

    The server address is the same for every client:

    https://aztra.my/api/mcp/mcp
    

    It is also listed on the Official MCP Registry as my.aztra/aztra, so clients that browse the registry will find it there.

    Two ways to connect

    Sign inAgent key
    Best forClaude.ai, Claude Desktop, ChatGPTClaude Code, Cursor, VS Code, scripts and CI
    HowAdd the URL; the client sends you through Aztra's sign-in and a consent screenMint a key under Settings → Profile → MCP keys, paste it as a header
    Acts asYouYou, or a member an admin minted it for
    Access levelWhat you approve on the consent screenYou choose when minting: read-only or read-write
    RevokeSettings → Profile → Connected assistantsSettings → Profile → MCP keys

    Sign in is the better default: nothing to copy, nothing that can leak, and revoking is one click. Use an agent key where a client cannot run an OAuth flow, or where a read-only key is the point.

    Claude.ai and Claude Desktop

    Add a custom connector

    Open Settings → Connectors, choose Add custom connector, and enter the server address above.

    Sign in and approve

    Claude opens Aztra's sign-in page, then a consent screen listing what it will be able to do. Approve, and you are back in Claude with Aztra attached.

    Ask

    "What is at risk in MyInfra this sprint?", "Log two hours on INFRA-2947", "Draft a wiki page summarising this week's threads." Claude asks before running anything that changes data.

    ChatGPT

    Add Aztra as a custom connector using the server address, and sign in when prompted. Custom connectors currently require ChatGPT's developer mode to be enabled for your account or workspace.

    Claude Code

    Mint a key under Settings → Profile → MCP keys, then run one command:

    claude mcp add --transport http aztra "https://aztra.my/api/mcp/mcp" \
      --header "Authorization: Bearer <your key>" \
      --header "Accept: application/json, text/event-stream"
    

    The dialog that shows your new key gives you this command already filled in.

    Cursor

    Add to .cursor/mcp.json in your project, or the global one in ~/.cursor/:

    {
      "mcpServers": {
        "aztra": {
          "url": "https://aztra.my/api/mcp/mcp",
          "headers": { "Authorization": "Bearer <your key>" }
        }
      }
    }
    

    VS Code

    Add to .vscode/mcp.json:

    {
      "servers": {
        "aztra": {
          "type": "http",
          "url": "https://aztra.my/api/mcp/mcp",
          "headers": { "Authorization": "Bearer <your key>" }
        }
      }
    }
    

    Any other client

    Any client that speaks remote MCP over HTTP takes the same shape — a url and an Authorization header:

    {
      "mcpServers": {
        "aztra": {
          "type": "http",
          "url": "https://aztra.my/api/mcp/mcp",
          "headers": {
            "Authorization": "Bearer <your key>",
            "Accept": "application/json, text/event-stream"
          }
        }
      }
    }
    

    For clients that only run local (stdio) servers, bridge with mcp-remote:

    {
      "mcpServers": {
        "aztra": {
          "command": "npx",
          "args": ["-y", "mcp-remote", "https://aztra.my/api/mcp/mcp", "--header", "Authorization:Bearer <your key>"]
        }
      }
    }
    

    A key is a password. Keep it out of shared configs, screenshots and chat — if one gets out, revoke it under Settings → Profile → MCP keys and mint another.

    Read-only and read-write keys

    When you mint a key you choose its level, and that decides what your assistant is offered:

    • Read-only — the assistant sees the read tools only. Write tools are not listed, so it cannot attempt one; there is nothing to refuse.
    • Read-write — the assistant sees every tool. Clients that support MCP annotations use them to decide when to ask you first: read tools run without a prompt, and tools marked as changing data ask for confirmation.

    A key is bound to one person and inherits their project access. It can never do more than that person can in the app.

    What your assistant can do

    Every tool the server offers, generated from the same definition the server runs. Names are what the assistant calls; titles are what you will see in its permission prompts.

    Read tools (29)

    Available to every key. They look things up and never change anything.

    Read-only tools
    ToolWhat it does
    Feedback summary
    get_feedback_summary
    Summarise a project's feedback (read-only): form + response counts, average rating, status breakdown, converted count, and the 5 most recent responses. Use when the user asks how a project's feedback or sentiment looks.
    Get attachment download link
    get_attachment
    Get one attachment by id, with a time-limited signed download URL. Only attachments on issues and tickets in your workspace are reachable. The URL is unauthenticated for its lifetime, so treat it as a secret and do not persist it.
    Get goal
    get_goal
    Get one goal in full: its values and progress_percent, its category, its parent (if it is a sub-goal), every sub-goal beneath it, and the most recent entries from its value history. The history is the only audit trail a goal has, since goals carry no version records.
    Get issue
    get_issue
    Get full details of a single issue by UUID or code (e.g. "ASTRA-42"). Includes time_summary.total_logged_minutes and time_summary.meets_time_gate — check meets_time_gate before trying to set status to in_review or completed.
    Get issue template
    get_issue_template
    Get a full issue template, including its tree under `root` and any project scope. Use before instantiate_issue_template to preview what will be created.
    Get project template
    get_project_template
    Get a full project template, including `config` (labels/statuses), `issues` (starter trees), and `ticket_type_ids`. Use before seed_project_template to preview.
    Get support ticket
    get_ticket
    Get full details of a single support/client ticket by UUID or code, including comments (each flagged is_internal) and SLA fields. Read-only — tickets are customer-facing and cannot be created or modified via MCP.
    Get thread
    get_thread
    Get a thread with its replies and linked entity (read-only). Project-scoped threads require that the token is allowed for that project. Returns the thread plus up to reply_limit replies (default 100), plus truncated_replies=true when more remain.
    Get wiki page
    get_wiki_page
    Get a full wiki page by UUID or slug. Project-scoped pages require membership of that project; workspace owners and admins are exempt. Returns scope, project_code, current_version, and a sharing object (public link, visibility, teamspaces, per-user/role permissions). Content is served as HTML — pages accept markdown on write but are stored and returned as HTML, so markdown does not round-trip. An ambiguous slug returns an error listing the candidate UUIDs and their scopes.
    List attachments
    list_attachments
    List files attached to one issue or ticket: id, file_name, mime_type, file_size, description, uploader and upload time. Metadata only — call get_attachment with an id to get a downloadable URL. Pass exactly one of issue or ticket.
    List feedback responses
    list_feedback_responses
    List a project's feedback responses, newest first (read-only). Optionally filter by form or status. Returns answers, rating, submitter, and timestamps.
    List goals
    list_goals
    List goals in the workspace. A SUB-GOAL IS JUST A GOAL WITH A PARENT — parent_goal_id links them, and is_sub_goal/sub_goal_count are returned so you can build the tree. Use top_level_only=true for roots, or parent=<goal id> for one goal's children. Reads span the whole workspace (mine_only=true narrows to the key's own goals); writes are restricted to your own goals. Returns progress_percent alongside start/current/target values.
    List issue templates
    list_issue_templates
    List reusable issue-tree templates in this workspace (read-only). Without `project`, returns workspace-wide templates only (project_id null). Pass `project` to also include that project's templates. Returns trimmed rows (no `root` tree blob) — call get_issue_template for the full tree.
    List issues
    list_issues
    List, count or group the issues in one project. Rows omit description and carry assignee_name, status_name and status_category, wrapped as { total, count, offset, limit, has_more, issues }. open_only=true excludes terminal statuses and matches get_workload.open + unassigned_open. count_only=true returns just { total }; group_by returns { groups: [{ key, label, count }] }; fields=[...] trims rows. updated_since is the primitive for incremental sync.
    List project templates
    list_project_templates
    List reusable project templates in this workspace (read-only). Returns trimmed rows (no `issues`/`config` blobs) — call get_project_template for the full snapshot.
    List projects
    list_projects
    List projects you have access to in this workspace. Archived projects are left out unless include_archived is set — pass it when you need to find one to restore_project. Rows carry archived_at (null when active) so you can tell them apart.
    List sprints
    list_sprints
    A project's sprints with dates, status and progress (read-only). Each row carries issue_count, completed_issues and story-point totals; an unfilled sprint reads issue_count 0. Sprint membership is a separate join table — it does not follow from an issue's status, dates or priority, and closing an issue does not remove it from a sprint.
    List support tickets
    list_tickets
    List support/client tickets in a project (read-only). Tickets are the customer-facing support system, separate from issues. Returns trimmed fields (no description).
    List threads
    list_threads
    List threads in this workspace (read-only). Threads are either workspace-wide (project_id null) or project-scoped. Without `project`, returns everything the caller can see given the token's project scope. Pass project="workspace" for workspace-only, or project="<code>"/numeric id for one project. Pass entity_type + entity_ref to find the thread linked to a specific issue/ticket/task. Each row carries scope, project_code, and entity ref.
    List time entries
    list_time_logs
    The individual time entries on an issue (read-only), newest first. get_issue's time_summary gives the rolled-up total; this gives the entry ids delete_time_log needs, plus who logged each one and when. deletable_by_you counts the entries belonging to this key.
    List wiki page versions
    list_wiki_versions
    List the version history of a wiki page (read-only). Every title/content edit is snapshotted, so this is the recovery path after a bad overwrite. Returns version_number, change_type, change_summary and author, newest first, plus the page's current_version. Bodies are omitted; use restore_wiki_version to put one back.
    List wiki pages
    list_wiki_pages
    List wiki pages in this workspace (read-only). Pages are either workspace-scoped (project_id null) or project-scoped. Without `project`, returns everything the caller can see (workspace pages + every project they're a member of, or every project for workspace owners/admins). Pass project="workspace" for workspace-only, or project="<code>"/numeric id to scope to one project. Each row carries scope ("workspace"|"project") and project_code.
    List wiki templates
    list_wiki_templates
    List wiki templates available in this workspace (read-only). Pass a returned id as create_wiki_page template_id to start a page from it. Template bodies are omitted here.
    List workspace members
    list_members
    Workspace members: profile_id, nickname, display_name, workspace_role, avatar_url and is_you. Maps a name to the profile UUID that assignee filters and assignee_id writes take. Emails are excluded. Narrow with query (name substring) or role.
    My work pulse
    get_pulse
    Snapshot of the calling user's assigned work for a time range. Returns per-project stats (open, in-progress, blocked, overdue, stale, completed in window) plus surfaced issues. Ranges: daily=24h, weekly=7d, monthly=30d, last_month=previous calendar month, quarterly=90d; 3 months is the maximum lookback. Per-project stats are project-wide — only the surfaced issue lists are scoped to the caller.
    Project org chart
    get_project_org_chart
    Get a project's org chart — the reporting hierarchy of its members. Returns flat nodes, each with profile_id, nickname, title, label, parent_id (who they report to; null = top), and sort_order. Build the tree from parent_id. Requires project membership or a workspace owner/admin/manager role.
    Search issues
    search_issues
    Search issues by text (title/description) or exact issue code, across every project you can access or one project. Same row shape as list_issues (assignee_name, status_name, status_category joined in), wrapped as { total, count, offset, limit, has_more, issues }, most recently updated first. limit defaults to 25 and is capped at 100 — page with offset. For structured questions (counts, date ranges, one project) prefer list_issues.
    Sprint progress
    get_sprint_progress
    Progress snapshot for a single sprint (read-only): the project's active sprint, else the most recent non-planned one, with story points done vs total and completion_pct. Returns null when the project has no sprints. Use list_sprints to see every sprint.
    Team workload
    get_workload
    Per-person workload across the workspace, or one project when project is passed. Covers the whole team, where get_pulse covers only the calling user. Each member returns open (assigned, not completed, point-in-time), overdue, created_total/completed_total over the window, and a weeks array bucketed by ISO week start, heaviest first. unassigned_open counts open issues with no assignee. Roles below manager receive only their own row, flagged restricted_to_self=true.

    Write tools (31)

    Offered only to a read-write key. A read-only key never sees them, so an assistant on a read-only key cannot attempt one by mistake.

    Write tools
    ToolWhat it does
    Archive goal
    delete_goal
    changes or removes existing data
    Archive one of this key's own goals (requires a read-write key). Sets status=“archived”, removing it from active views; reversible with update_goal(status=“active”). There is no hard delete: the parent link cascades, so removing a goal would take every sub-goal and its history with it. Live sub-goals are reported rather than archived alongside the parent.
    Archive project
    archive_project
    changes or removes existing data
    Archive a project (requires a read-write key). The caller must be an owner or admin of that project; a workspace admin who is not a project member is refused. Archiving hides the project from active lists and marks it inactive. Its issues are not closed, deleted or moved. Reversible by a project owner via restore_project. update_project(status=“completed”) marks work finished while leaving the project visible.
    Create goal
    create_goal
    Create a goal, or a sub-goal by passing parent (requires a read-write key). The goal is owned by this key's profile — you cannot create goals for other people. Sub-goals inherit their parent's project scope. target_value is required and must be >= start_value; current_value starts at start_value and is moved with update_goal_progress, not set here.
    Create issue
    create_issue
    Create a new issue in a project (requires a read-write key). Supports start_date (for epic/timeline scheduling), labels (by name), and parenting (same project only). difficulty also sets the sub-issue cap for THIS new issue when it later becomes a parent (low=no sub-issues, medium=10, hard=unlimited — advisory; raise to hard to lift the cap).
    Create issue template
    create_issue_template
    Create a reusable issue template (requires a read-write key). from_issue takes an existing issue UUID or code and captures its full sub-tree. scope makes the template workspace-wide (default) or pins it to the source issue's project. Raw root authors a tree from scratch and is capped at 50KB, depth 10, 500 nodes.
    Create issues from template
    instantiate_issue_template
    Create real issues from a template tree (requires a read-write key). Bulk-write and irreversible — preview with get_issue_template first. Caller must be a member of the target project. `parent_issue` grafts the template root under an existing issue in the same project; omit to create a new top-level issue. Returns the root issue (id + code).
    Create project
    create_project
    Create a project in this workspace (requires a read-write key). The caller must be a workspace owner, admin or manager; a project-scoped key is refused. The project comes with the standard issue statuses, default ticket types, and the caller as owner. Returns the project, its URL, and a seeded count; a failed optional step surfaces in warnings rather than failing the call.
    Create project template
    create_project_template
    Create a reusable project template (requires a read-write key). Prefer `from_project` — pass an existing project ref (numeric id or identifier) and labels + custom statuses + ticket types + starter issue trees are captured. Manual mode accepts `ticket_type_ids` / `config` / `issues` directly (payloads capped).
    Create thread
    create_thread
    Post a new thread to the workspace activity feed (requires a read-write key). Omitting project and entity_* posts workspace-wide; project=“<code>” scopes it to one project; entity_type+entity_ref links it to an issue, ticket or task and inherits that entity's project. Entity-linked threads are unique per entity: when one already exists the response is { thread_id, already_exists: true } and no thread is created. reply_thread adds to an existing thread.
    Create wiki page
    create_wiki_page
    Create a new wiki page (requires a read-write key). Slug is auto-generated. Status defaults to "draft" — pass "published" to publish on create. Scope: pass `project` to create a project-scoped page, omit for workspace-global. Children inherit their parent's scope — if `parent_page_id` is set, leave `project` unset or match the parent (mismatch returns an error).
    Delete time entries
    delete_time_log
    changes or removes existing data
    Delete time entries by id (requires a read-write key) — the undo for log_time, and the only way to take back a mis-logged sweep. Get the ids from list_time_logs. Only entries logged by this key's owner are deleted; anyone else's come back under not_yours untouched, the same rule the web app enforces. Removing entries can drop an issue back below the logged-time gate that in_review and completed require.
    Delete wiki page (recoverable)
    delete_wiki_page
    changes or removes existing data
    Soft-delete a wiki page (requires a read-write key and manage permission). Sets deleted_at, so the page leaves every listing while staying recoverable with its version history intact. There is no permanent delete over MCP. Archiving via update_wiki_page(status=“archived”) only marks a page and leaves it listed. Live sub-pages are reported in the response rather than deleted.
    Edit comment
    update_comment
    changes or removes existing data
    Edit a comment you previously wrote — pass the reply id from reply_thread, or the thread id when correcting your first comment on an issue (the first one becomes the thread body). Only comments authored by this agent key can be edited; others are rejected. Prefer posting a follow-up: an edit silently rewrites text someone may have already read. Use this to fix an error in your own note, not to keep a running status log up to date.
    Link issues
    link_issue
    Create a typed dependency between two issues in the same project (requires a read-write key). direction "from" (default) makes `issue` the subject — e.g. type "blocks", direction "from" means issue blocks linked_issue; direction "to" means issue is blocked by linked_issue.
    Log time
    log_time
    Log time on an issue (requires a read-write key). Independent of status: logging time and changing status are separate operations. Takes minutes or hours, or both, which are summed, and records the duration exactly as given with no rounding. Entries are attributed to the key owner's profile_id. apply_to_descendants=true logs the same duration across the subtree in one call. Already-closed descendants are skipped and counted in skipped_completed unless include_completed=true.
    Move issues between sprints
    assign_issue_sprint
    changes or removes existing data
    Put issues into a sprint, or take them out (requires a read-write key). The only way to fill a sprint: no status, due_date or priority change moves an issue into one. An issue belongs to at most one sprint, so assigning replaces whatever it was in. Every issue in a call must be in the sprint's project. action “remove” without a sprint takes each issue out of whichever sprint it is in. Up to 50 per call, reporting ok/changed per issue.
    Record goal progress
    update_goal_progress
    Record progress on one of your own goals (requires a read-write key). Pass exactly one of value (set the current value to this) or increment_by (add this to it). The change is written to the goal's history with optional notes, and the goal auto-completes when it reaches target_value. This is the only way to move current_value, so the history stays complete.
    Reply to thread
    reply_thread
    Reply to an existing thread (requires a read-write key). Use this for follow-ups, status updates on an existing announcement, or when create_thread reports already_exists for an entity-linked thread. The author is the agent key's owner.
    Restore archived project
    restore_project
    Bring an archived project back (requires a read-write key; the caller must be an OWNER of that project — admins can archive but not restore). Clears the archive and sets the project active again. Returns restored=false when the project was not archived to begin with.
    Restore wiki page version
    restore_wiki_version
    changes or removes existing data
    Restore a wiki page to an earlier version (requires a read-write key and edit permission). The current state is snapshotted first, so the restore is itself undoable, and it lands as a new version rather than rewinding history. list_wiki_versions supplies version_number.
    Seed project from template
    seed_project_template
    Apply a project template to an EXISTING project (requires a read-write key). Adds labels and custom statuses (idempotent: skips by name) and creates the starter issue trees. Caller must be a member of the target project. Use this to apply a template to a project that already exists; when creating a new one, pass template to create_project instead and it is seeded in the same call.
    Set issue consulted (RACI)
    set_issue_consulted
    changes or removes existing data
    Add or remove a person as "Consulted" (the C in RACI) on an issue (requires a read-write key). Identify the person by profile_id (UUID) or email. action defaults to "add"; use "remove" to un-consult. Only the issue assignee, the project lead, or a workspace owner/admin/manager may set consulted.
    Set wiki page permission
    set_wiki_page_permission
    changes or removes existing data
    Grant, change, or revoke a per-page access rule for one user or one workspace role (requires a read-write key and manage permission). Target exactly one of profile_id or role. permission is view, edit, manage, or none (none = explicit deny). Pass remove=true to delete the rule. inherit_to_children (default true) cascades the rule to descendant pages.
    Set wiki page visibility
    set_wiki_page_visibility
    changes or removes existing data
    Set who inside the workspace can see a wiki page (requires a read-write key and manage permission). visibility="global" = everyone in the workspace (project pages still require project membership); visibility="teamspace" = only members of the given teamspaces. Replaces the page's teamspace list. visibility_override=true makes descendant pages inherit THIS page's visibility.
    Share wiki page publicly
    share_wiki_page
    changes or removes existing data
    Create or revoke a public share link for a wiki page (requires a read-write key and manage permission). public=true mints a public URL anyone with the link can read (optionally expiring); public=false revokes it. Returns public_url when enabled.
    Unlink issues
    unlink_issue
    changes or removes existing data
    Remove a typed dependency between two issues, in either direction (requires a read-write key).
    Update goal
    update_goal
    changes or removes existing data
    Update a goal's fields (requires a read-write key). Limited to goals owned by this key; editing someone else's is refused. current_value is not settable here — progress is an event with a history and goes through update_goal_progress. A goal that already has a description rejects the call unless description_mode is set, since goals carry no version history.
    Update issue
    update_issue
    changes or removes existing data
    Update an existing issue (requires a read-write key). On an issue that already has a description, passing description posts the text as a comment on its thread rather than overwriting, and reports description_action=“commented” — issues carry no version history. description_mode edits the description itself. Moving status to in_review or completed requires logged time and is rejected otherwise; get_issue reports time_summary.meets_time_gate. Re-sending an unchanged status re-points status_id at the matching column, repairing a diverged row, and leaves completed_at as it was.
    Update many issues
    bulk_update_issues
    changes or removes existing data
    Apply one set of changes to up to 50 issues in a single call (requires a read-write key). Each issue runs the full update_issue path, so the time gate, parent checks and label resolution all still apply, and the response reports ok/error per issue — one failure does not stop the rest. Accepts every update_issue field except title and description.
    Update project
    update_project
    changes or removes existing data
    Update a project's lifecycle status or basic fields (requires a read-write key; caller must be a project or workspace owner, admin or manager). status is the project-level lifecycle, separate from issue status and from is_active — completing or cancelling neither archives the project nor closes its issues. The identifier cannot be changed here, since existing issues keep the code they were created with. A project that already has a description rejects the call unless description_mode is set.
    Update wiki page
    update_wiki_page
    changes or removes existing data
    Update a wiki page (requires a read-write key). Any field omitted is left unchanged. Setting status to "published" stamps published_at. Re-parenting cannot reference the page itself and must stay within the same scope (workspace pages stay under workspace pages, project pages under the same project's pages). project_id is immutable after creation. Editing content/title auto-creates a version snapshot via DB trigger.

    Limits

    • 100 requests a minute per key. Past that the server answers 429 with a Retry-After header, and well-behaved clients wait it out. Normal use is nowhere near this.
    • Large results are trimmed. Images embedded in an issue are replaced with a note of their size rather than sent as raw data, and a result too large for the assistant to hold comes back as a short notice with a hint to narrow the request.
    • Two writes are gated. Moving an issue to In review or Completed requires time logged on it — the same rule the app enforces.

    Revoking access

    • Signed-in assistantsSettings → Profile → Connected assistants lists every assistant you have signed in from, with its access level and the workspace it was granted. Disconnect cuts it off immediately: its tokens stop working on the next request, and it has to sign in again to reconnect. Disconnecting inside the client also works, but only Aztra's side is instant.
    • KeysSettings → Profile → MCP keys lists every key with when it was last used and from where. Revoke is instant and permanent; mint a new key if you need one again.

    Everything an assistant does through MCP is attributed to the person whose account or key it used, and shows in the activity feed like any other change.