Claude connector
Connect Claude to your Elixion workspace so it can find work, understand it, and file new work, acting as you.
Connect Claude to Elixion, the platform for Engineering Intelligence™, and it can find your work, understand it, and file new work, acting as you, with exactly the permissions your Elixion account already has.
- Connector URL:
https://api.elixion.ai/mcp - Authentication: OAuth 2.1 with PKCE. Claude sends you to Elixion to sign in and approve.
Connect it
Inside Elixion, Connect Claude in the sidebar opens a setup page that walks through both routes and notices the moment you finish.
Claude Code: one command
claude plugin marketplace add Elixion-ai/elixion-plugin
claude plugin install elixion@elixion-plugins
Then run /mcp, choose elixion, and approve. There is nothing to paste: the plugin carries the connection details. It also installs two skills, one that keeps your board in sync as you work and one that answers "what did I do this week" from the board.
claude.ai: custom connector
- In Claude, open Settings > Connectors > Add custom connector.
- Paste the URL:
https://api.elixion.ai/mcp - Click Connect. Claude sends you to Elixion.
- Sign in if you are not already, approve, and Claude shows the connector as Connected.
Permissions
A connection carries two scopes, and it normally carries both:
| Scope | What it allows |
|---|---|
| elixion:read | Read projects, issues, boards and sprints you can already see |
| elixion:write | Create and update issues, comment, assign, and manage sprints |
The Elixion consent screen asks for a default workspace and then for Allow or Cancel. It carries no scope control, and a client that asks for no particular scope, which is Claude's usual flow, is granted both. A connection that carries read access only, because the client asked for elixion:read alone, cannot write. The write tools refuse the call and tell you to reconnect and approve write access.
Which workspaces it can see
The consent screen has a Default workspace selector, and it opens on All my workspaces. Leave it there unless you have a reason not to: every project in Elixion lives in its own workspace, so choosing a single one shows Claude exactly one project.
Pick a single workspace and the connection is genuinely narrowed. Projects, issues, epics, sprints, search and notifications are all filtered to that workspace's projects, and create_project is refused outright, because a new project would create a workspace outside the one you consented to.
Reconnecting is how you change it. If you are replacing an existing narrowed connection, the consent screen carries the old workspace forward and warns you in red before a new approval widens or swaps it.
Disconnecting
Open Settings then Connections in Elixion. Every Claude client holding a live grant is listed with the workspace it reaches, what it may do, when it was connected and when it was last used, and each one has a Revoke control. Revoking takes effect immediately, and reconnecting is done from Claude.
You can also remove the connector in Claude. The next call fails and Claude asks you to reconnect.
The same two operations are available over the API, if you prefer: GET /api/v1/mcp/connections lists your live connections and DELETE /api/v1/mcp/connections/{id} revokes one. Both only ever act on your own grants.
A connection also ends on its own: the access token lasts an hour and the refresh token thirty days, and deactivating the Elixion account behind it stops every call immediately.
What Claude can do
Claude acts as you. It cannot see a project you cannot see, and it cannot do anything in Elixion you could not do yourself. The tools call the same code the rest of the product calls, so your project and workspace permissions apply unchanged.
Reading
| Tool | What it is for |
|---|---|
| ping | A connectivity check that reads nothing |
| whoami | Who Claude is connected as, which is what makes "assign this to me" work |
| list_projects, get_project | Find a project and see how it is set up |
| list_project_members | Who is on the team, which is what makes "assign this to Sarah" work |
| list_issues | "What's on my plate", "what's open in PAY" |
| get_issue | One issue: description, subtasks, comments. full=true for long text |
| list_issue_comments | A whole comment thread, a page at a time, uncut |
| search_issues | Anything the simple filters cannot express, using EQL |
| get_eql_help | The exact EQL grammar the search understands |
| get_board | The board as it appears on screen |
| list_sprints, get_sprint | Sprint dates, goal, status, capacity |
| get_issue_relationships | What blocks an issue, what it blocks, duplicates |
| list_issue_history | What changed on a ticket, and who changed it |
| list_issue_worklogs | Time logged against an issue |
| list_epics | Epics with progress: how many issues and points are done |
| get_sprint_analytics | How a sprint is tracking, including mid-sprint scope change |
| get_project_velocity | Points delivered per completed sprint, and the average |
| get_project_activity_feed | What happened on a project, the standup rundown |
| list_notifications | What needs your attention in the connected workspace |
| list_milestones, get_milestone | Upcoming releases and checkpoints, with progress |
| list_milestone_issues | What is in a milestone, and what is blocking it |
| list_documents, get_document | Find and read project docs: PRDs, specs, notes |
| get_time_report | Time logged across a project or period, broken down by person |
| get_timesheet | A timesheet, your own or a teammate's where you share a project |
| get_capacity_planning | Who has bandwidth for the sprint, and who is overloaded |
| list_agents | The AI agents working on your projects |
| list_agent_runs | What the agents have been doing, and whether runs finished |
| get_issue_agent_output | An agent's progress and output on one issue |
| list_issue_evidence | The pull requests, commits, test runs, artifacts and links on an issue |
| list_issue_runs | The run records on an issue, and who recorded each one |
| list_issue_templates, get_issue_template | Your team's issue patterns, ready to apply when filing |
| list_recurring_tasks | Scheduled recurring tasks and when they run next |
Writing
These change your workspace, and other people see the result. Claude asks you before using them.
| Tool | What it is for |
|---|---|
| create_project | Start a project from scratch, with its own key and workspace |
| update_project | Rename a project, or change its status, type or methodology |
| create_issue | File a new issue |
| update_issue | Change title, priority, points, labels or description |
| append_to_issue_description | Add to the end of a description without rewriting it |
| transition_issue_status | Move an issue between statuses |
| assign_issue | Put an issue on someone's plate |
| claim_issue | Take an unassigned issue for yourself, atomically, so no other session can take it at the same moment |
| add_issue_comment | Comment, attributed to you |
| manage_sprint | Create, start, complete or cancel a sprint |
| manage_sprint_issues | Add issues to a sprint, or take them out |
| manage_issue_link | Link issues ("PAY-42 is blocked by PAY-41") or unlink them |
| add_work_log | Log time spent on an issue |
| mark_notifications_read | Clear notifications in the connected workspace |
| create_milestone | Add a release or checkpoint with a target date |
| manage_milestone | Update, complete or reopen a milestone |
| manage_milestone_issues | Put issues into a milestone, or take them out |
| create_document | File a document: a PRD Claude drafted, meeting notes |
| manage_issue_archive | Archive finished issues, or bring them back |
| manage_bulk_issues | Transition, assign, label or update up to 50 issues in one call |
| add_issue_evidence | Record a pull request, commit, test run, artifact, preview or link on an issue |
| record_agent_run | Let an agent record its own run against an issue |
Five of the write tools are marked destructive, which is Claude's signal to confirm harder before calling: update_issue, update_project, manage_milestone, manage_issue_link and manage_sprint. The marker means the call can lose something you had, by overwriting prose or driving a sprint to a terminal state, rather than only adding or moving work. Everything else that writes is marked non-destructive.
Delivery evidence and agent runs
An agent working on an issue can record what it actually did, so the issue carries its own proof of delivery.
add_issue_evidence records one artifact: a pull request, a commit, a test run, a build artifact, a preview or a link. It is idempotent per artifact, so recording the same pull request again as MERGED updates the row rather than adding a second one. A preview is idempotent per environment instead of per url, so a rebuild updates the environment's row rather than adding another. list_issue_evidence reads them back, along with has_merged_pr, which is the same fact the hasMergedPR field filters on in EQL.
Custom statuses and status groups
A project can define its own statuses on top of the 7 built-ins (BACKLOG, TODO, IN_PROGRESS, IN_REVIEW, TESTING, DONE, DEFERRED), each in one of four groups: To do, In progress, Done or Deferred. update_issue and transition_issue_status accept a project's own status name, exactly as it was created (status = "Shipped", not "SHIPPED"). create_issue does not yet: a new issue starts in one of the built-in statuses and can be moved to the project's own afterwards.
EQL matches a status by name case-insensitively, built-in or custom: status = "shipped" matches a project's own "Shipped" status. To match every status in a GROUP instead of one literal status (including a project's own status in that group), use statusGroup (status_group also works): statusGroup = "In progress" or statusGroup = "Done". Both the group's display label and its raw value (IN_PROGRESS, DONE, TODO, DEFERRED) are accepted.
record_agent_run lets an agent open a run, then close or amend it later with an outcome of SUCCESS, FAILED, CANCELLED or TIMEOUT. A run reported after the fact opens and closes in one call. The name the agent gives is what appears in the issue's runs and in the agent log, and the record is marked as agent-written, so it stays distinguishable from a run Elixion dispatched itself. list_issue_runs shows every run on an issue with its source: PLATFORM for one Elixion performed, AGENT for one an agent reported about itself, HUMAN for one a person recorded.
Names, not identifiers
You rarely have to hand Claude a UUID.
- Projects resolve from a key, a UUID, or an exact project name. An archived project never shadows a live one of the same name, and several live matches raise an error listing the keys rather than picking one.
- Sprints and milestones resolve from the exact name the list tools show, such as "Sprint 18". An ambiguous name raises an error listing the candidates.
- Epics resolve from an issue key such as
PAY-42, which is the only epic handle the connector ever hands out. A key that is not an epic is rejected by name.
Blocked work in one call
Rows from list_issues carry blocked_by, the keys of the issues blocking them, loaded in the same query. Mapping a dependency chain is one call rather than one call per issue.
A blocked issue does not always have a blocker to name. The flag is also set by operational failures, and those rows come back with an empty blocked_by and a blocked_reason instead.
Several agents, one board
Two Claude sessions reading the same board would both see the same unassigned issue and both start it. Nothing in list_issues stops that, because reading is not taking. claim_issue is how a session takes an issue so that no other session can take it too.
It is a single conditional write in the database, so the database decides who wins rather than the sessions agreeing to behave. Of any number of callers racing the same issue, exactly one wins. Every call returns one of three results:
| Result | What it means | What to do |
|---|---|---|
| won | You have it. The issue is now IN_PROGRESS and assigned to you | Start the work |
| already_held | You already had it. Nothing was written again | Carry on; safe after a retry or a restart |
| lost | Someone else holds it | Pick a different issue |
Every result also carries held_by, held_by_id, held_by_kind and held_since for whoever holds the issue, including on a loss, so a session that loses learns who has it without a second call. held_by is the holder's display name, and several accounts can share one, so it is for reading, not for deciding. held_by_id is the holder's id: compare it with the user_id from whoami to know whether the holder is you. held_by_kind is user for a person's account and agent for an Elixion agent. All three are null when nobody holds the issue.
An issue can be won only while all four of these hold at the moment of the write: its status is BACKLOG or TODO, it has no human assignee, it has no agent assignee, and it is not archived. Anything else returns a result other than won and changes nothing. A losing call writes no history, no audit entry and no activity.
Calling it again for an issue you hold returns already_held with the original held_since, so a retry never resets how long you have held something.
A claim is an assignment, not a lock with a timer. It does not expire. If a session claims an issue and then stops, the issue stays with it until someone reassigns it or moves it back. Release an issue the ordinary way, with assign_issue or transition_issue_status; there is no separate unclaim.
Seeing what is in flight. Rows from list_issues and cards from get_board carry held_since: a timestamp when someone holds the issue now, and null when nobody does. They also carry the same held_by_id and held_by_kind as claim_issue, so a row says which account holds the issue, not only its name. An issue that was taken and later released reads null, not the time it was released. get_issue does not carry it; use list_issues or get_board to see what is in flight.
A pattern that uses it:
list_issues(project="PAY", status="TODO") pick a candidate
claim_issue(id="PAY-42")
won start working
lost read held_by_id, choose another issue
already_held carry on, you had it before
Limits, and how to get past each one
Tool results are bounded, because a result that overflows takes the answer down with it. Truncation is never silent. Any clipped field comes back with truncated: true and a visible … [truncated] marker. If you do not see that flag, you have everything.
| What | Limit | How to get the whole thing |
|---|---|---|
| Description, acceptance criteria | 4,000 characters | get_issue(full=true) raises the ceiling to 100,000 |
| A comment inside get_issue | 500 characters | list_issue_comments returns bodies uncut |
| Comments inside get_issue | the latest 5 | list_issue_comments pages the whole thread |
| list_issue_comments | 20 per page, at most 50 | page with page; has_more and total say when you are done |
| list_issues, list_epics, list_documents, list_notifications | 25 per page, at most 50 | page with page; total is always the true count |
| search_issues | 25 results, at most 50 | narrow the EQL query; there is no cursor |
| get_board | 60 cards per column | each column reports its true total; use list_issues for the rest |
| list_issue_evidence, list_issue_runs | 100 rows, no paging | total reports the real count; open the issue in Elixion for more |
| get_document body | about 20,000 characters | open the document in Elixion |
| manage_bulk_issues | 50 issues per call | split into batches |
| /mcp requests | 120 per 60 seconds, per connection | wait for the window named in the error and retry |
Amending a long description. Do not read a description and write it back to add a paragraph. If the read was truncated, the rewrite destroys the tail you never saw. Use append_to_issue_description, which adds to the end without reading it at all. Reach for update_issue only when you genuinely mean to replace the text, and read it with full=true first when you do.
Things the connector deliberately will not do
These are refusals by design, not gaps.
It cannot mark an issue Done. Acceptance belongs to the issue's reporter, so IN_REVIEW is the ceiling. That covers any status in the Done group: the built-in DONE, or a project's own Done-group status such as a custom "Shipped". TESTING is out of reach too, for the same reason. transition_issue_status accepts BACKLOG, TODO, IN_PROGRESS, IN_REVIEW, DEFERRED, and any status the issue's own project has defined outside the Done group, and rejects the rest out loud rather than quietly doing nothing, so Claude can never report a ticket closed that it never moved.
It will not silently overwrite a rich description. If a description contains formatting, images or @-mentions, update_issue refuses to replace it with plain text until you have seen what would be lost and confirmed.
It cannot delete anything. There is no tool to delete an issue, a sprint, a project, a milestone, a document, a comment or a work log. The only removals are unlinking two issues and taking an issue out of a sprint or a milestone. Archiving an issue is reversible. manage_sprint offers cancel but no delete, so a sprint's history survives, and manage_milestone does not delete either.
Archiving has preconditions. Only Done or Deferred issues archive, and the reason has to fit: a Done issue takes COMPLETED, WONT_DO or DUPLICATE, a Deferred issue takes WONT_DO or DUPLICATE. Epics are exempt and archive at any status without a reason. A combination that does not fit is refused before anything changes.
Bulk edits do not notify anyone. manage_bulk_issues changes up to 50 issues in one transaction and sends no notifications to watchers or assignees, unlike the single-issue tools. Issues you cannot reach are skipped and counted, never named.
It cannot reach outside the workspaces you consented to. If you narrowed the connection to one workspace, everything else is invisible to it, and mark_notifications_read reports anything outside that workspace back as out of scope rather than touching it.
Try it
- "What's assigned to me in Elixion right now?"
- "Show me the PAY board. What's blocked?"
- "Find issues that aren't done and are due this week."
- "Read PAY-42 and summarise what's left."
- "File a bug in PAY: the export button 404s on Safari."
Troubleshooting
Claude says it needs me to reconnect. The connection expired or was revoked. Reconnect from Claude.
Claude cannot see a project I expect. The connector inherits your Elixion permissions exactly. If you cannot open the project in Elixion, Claude cannot either. Ask a workspace admin to add you. If you narrowed the connection to a single workspace at consent, reconnect and choose All my workspaces.
Claude says it cannot write. The connection was approved with read access only. Reconnect and approve write access.
Claude says it cannot create a project. The connection is scoped to one workspace, and a new project would create its own workspace outside it. Reconnect with workspace-wide access.
A call failed with a rate-limit error. The connector allows 120 requests a minute per connection. Wait for the window given in the error and retry. If it keeps happening in normal use, contact us; the limit is meant to be invisible.
A name came back ambiguous. Two sprints, milestones or projects share that name. The error lists the candidates. Pass the id, or the project key, instead.
Privacy
Claude reads only what you ask it to, using your own Elixion permissions, and Elixion never receives your Claude conversation. Access tokens are stored hashed; tokens, authorization codes and Authorization headers are never logged.
Full detail: Privacy Policy.