MCP server
Hyrax runs a Model Context Protocol (MCP) server so the AI coding agents you already use — Claude Code, Cursor, Copilot — can query your repositories' live discovery context, findings and rules over HTTP, and work with your issues and missions. It is how your agents read what Discovery learned about a repo — its architecture, conventions, and how-to guides — and it answers the questions that change often: What findings are open on this file? What rules apply before I edit this file? Which issues are assigned to me?
Connecting
The server is mounted at /mcp over streamable HTTP — point your client at /mcp/ with the trailing slash. On the API host a bare POST /mcp 307-redirects to it, preserving method and body, but a client that doesn't follow 307s will fail — and on the app host the bare path doesn't route at all, so always include the slash. Use the same hk_live_ API key as the REST API, passed as a bearer token:
POST /mcp/ HTTP/1.1
Authorization: Bearer hk_live_...
Content-Type: application/json
The endpoint is rate-limited per API key — about 60 requests per minute, or the key's own per-minute limit if that is lower. Exceed it and you get a 429 with a Retry-After header. Spend ceilings apply too: once your workspace reaches its hourly spend ceiling, or the key reaches its own dollars_per_hour ceiling if it has one, you get a 429 with code: "rate_limit_budget" and a Retry-After header. On MCP that refusal covers every call, reads included — the server is a single JSON-RPC endpoint, so it can't price per tool the way the REST routes do.
A key's restrictions travel with it across transports: if the key was minted with an IP allowlist (allowed_cidrs), the MCP server enforces it exactly as the REST API does — a request from outside every listed range (or whose client IP can't be reliably established) is refused with a 401, fail-closed.
The MCP server authenticates with the same API keys as the REST API, included on both plans, Free and Paid. See the API overview and Plans & pricing.
What you can do
Every per-repository tool addresses your repo by the owner/repo/branch triple. An agent typically lists your repos first, then passes the triple into the rest.
Read tools query your repo's live state and never change anything:
| Tool | What it answers |
|---|---|
| List repositories | Which repos does this workspace have? |
| Repository overview | The stack profile, domain summary, and engineering principles for one repo. |
| Read knowledge bundle | The full discovery bundle — profile, principles, conventions, and open directives. |
| List / search observations | The findings list (with advisories, and suggestions where your workspace has them), filtered by kind, status, priority, and repo; or a substring search (with an optional kind filter). The search tool is named search_issues, but it searches findings, not issues. |
| Applicable rules | The conventions and skills that apply to a specific file path. |
| Canonical pattern | The repo's canonical patterns prose (optionally filtered by an area keyword), served live from the latest Discovery run. Requires the view_repositories scope. |
Recent findings (recent_issues) | Open findings touching a given file path. Despite its name, it returns findings (HYRAX-N), not issues (ISS-N). |
| Explain an observation | The full body of one observation by its HYRAX-N ref. |
| Pending migrations | The open architectural suggestions feed. Empty unless Hyrax support has turned audit suggestions on for your workspace. |
| How-to guides | The list of how-to guides Discovery produced, and the body of any one. |
| Cost forecast | The likely cost and duration band (low / mid / high, with sample size and confidence) for a workflow on a repo — readable by any key, so a submit-only key can quote the price before it runs. |
| Job status | The state, workflow, repo, timestamps, error, failure classification, and fix PR URL for a job you submitted. Requires the view_jobs scope. |
| List jobs | A repo's jobs, newest first, with an optional status filter — the same slim per-job shape as Job status, for when you don't hold a job id. Requires the view_jobs scope. |
| List fix PRs | The per-repo lane of findings Hyrax opened a fix PR for — ref, title, PR link, and a derived status (merged answers "did my fix land?"; in_review / revising mean the PR is still open). Findings with an open fix PR leave the active observations list and surface here. Requires the view_repositories scope. |
| Observation detail | One observation (HYRAX-N) in full: every location, the fix-attempt history, and whether a fix can run on its repo. Requires the view_observations scope. |
| Repository detail | One repo's full record: detected languages and size, open observation counts, last audit and discovery times, and its settings. Requires the view_repositories scope. |
| Repository / workspace guidance | The guidance you set: every slot for a repo, resolved to the value that applies and where it came from, or the workspace-level answers. Requires the view_repositories scope. |
| Workspace settings | The workspace settings: whether audits suggest code improvements (which takes effect only where Hyrax support has turned audit suggestions on), the organization context in use, and the default fix failure modes. Requires the view_repositories scope. |
| Workspace overview | The dashboard: one row per repo with its open findings by priority and by domain. Requires the view_repositories scope. |
| Active jobs | The pending and running jobs across every repo the key can see, newest first. Requires the view_jobs scope. |
| Audit freshness | How far a repo's branch has moved since its last completed audit, to decide whether to run another. Needs the Hyrax GitHub App installed on the repo's organization. Requires the view_repositories scope. |
| Repository preview | A GitHub repo's metadata and language support before you register it, at no cost. Needs the Hyrax GitHub App installed on the repo's organization. Requires the view_repositories scope. |
| PR reviews | A repo's pull request review history, and one pull request's latest review with its findings. Requires the view_repositories scope. |
| Review instructions | The repository instruction files (such as AGENTS.md or CLAUDE.md) the latest pull request review followed. Requires the view_repositories scope. |
| To-do list | The to-dos Hyrax derives for your repos and workspace, most urgent first. Requires the view_repositories scope. |
Write tools run without round-tripping through the web app. Almost every tool — read and write — is gated by the key's scopes, including for account owners (the one exception, Cost forecast, is noted in the table above): a key's scopes are a hard ceiling for that key on every surface (REST and MCP alike), so a call is refused unless the key carries the matching scope even when its owner is the account owner. If a key lacks the scope it needs, mint a new key with the fuller set, since keys only narrow after mint.
Cost-bearing writes submit or drive a job and draw on your spend controls exactly as the REST routes do:
| Tool | What it does | Required scope |
|---|---|---|
| Submit a job | Start a workflow run (audit, and so on) for a repo. It takes no per-workflow options, so a fix or a pull request review starts from its own tool below. | submit_audit_jobs |
| Submit a fix | Spawn a fix job for one finding (HYRAX-N ref) — mints the job and registers the fix attempt in one call. Only an open finding can be fixed, and advisory findings cannot. | submit_fix_jobs |
| Request a fix | Confirm or re-bind the fix attempt for an already-minted fix job (takes the ref plus that job's id — it does not spawn the job). | submit_fix_jobs |
| Retry a job | Re-submit a failed or cancelled job, preserving its workflow. A job can be retried a limited number of times. | submit_audit_jobs, plus submit_fix_jobs when retrying a fix job (both on the key) |
| Register a repository | Add a repository to the workspace. A public repository without the Hyrax GitHub App is added by URL in the web app instead. | register_repo (a manage_repos key also works — it implies register_repo) |
| Request a PR review | Run a Hyrax review on one pull request (repository plus PR number). Hyrax does not review a pull request it opened itself. | submit_audit_jobs |
| Revise a fix PR | Revise the open Hyrax fix pull request for one finding (HYRAX-N) from the review feedback left on it. Each pull request allows a limited number of revisions. | submit_fix_jobs |
Triage writes take routine, reversible actions on findings and settings:
| Tool | What it does | Required scope |
|---|---|---|
| Dismiss an observation | Close an observation with a reason (false positive, won't fix). | triage_observations |
| Acknowledge an observation | Stamp an observation as seen (acknowledged_at) — it stays open on the worklist. | triage_observations |
| Complete an observation | Mark an observation addressed when it was resolved outside a Hyrax PR (optional proof link + note). Reversible via reopen. | triage_observations |
| Reopen an observation | Move a closed observation back to new. | triage_observations |
| Create a ticket | File a Linear ticket for an observation (when the repo has ticket integration configured). | triage_observations |
| Update repository metadata | Flip safe repo settings, such as enabling PR review. | manage_repos |
| Set guidance / context | Upsert or clear a guidance slot, or set the workspace's organization context: the text Hyrax adds to every agent prompt in the workspace, at most 8,192 characters. | manage_tenant_settings |
| Set / clear a workspace setting | Set or clear a typed workspace configuration knob (e.g. audit_timeout_s); clearing reverts the knob to its default. | manage_tenant_settings |
REST-only. Destructive actions stay out of MCP — reach for the REST API for:
- Cancelling a job
- Deleting or resetting a repository
- Webhook subscription management
Team context tools
Team context entries are the decisions, conventions, runbooks and warnings your team and your agents write down for later agents. These tools read and write them. They are not issues. One workspace entry is set elsewhere: the workspace's organization context is kept as the workspace entry with the key organization-context. These tools read it like any other entry but refuse to create, change, disable or restore that key, at any level, with key_reserved; change it with Set guidance / context, which replaces the whole text. Workspace settings returns the text in use, whether or not the entry exists yet.
Every tool except the repository context digest takes an optional project (the slug of a project, Space or Area); omit it to address the workspace. The repository context digest takes the repository instead, as github_org, github_repo and github_base_branch, plus an optional limit. Reads return the effective entries at that level, including entries inherited from the workspace and from the levels above it. Writes act only on the entries that live at the level you address.
| Tool | What it does | Required scope |
|---|---|---|
Context digest (get_context_digest) | The entries that apply at a project or the workspace, summaries only, in reading order: the workspace's organization context first when the digest includes it, then live entries, then corroborated proposals, then other proposals, with warnings first in each group. limit is 40 by default, at most 100. Read it before working in a project. | view_context |
Repository context digest (get_repo_context_digest) | The digest for a repository (github_org, github_repo, github_base_branch; it takes no project): the digest of the most specific project, Space or Area that contains it, or the workspace's when none does. A Space's Inbox, and a Space that holds every repository, count only when nothing else contains the repository. limit is 40 by default, at most 100. Read it before working in a repo. | view_context |
List context entries (list_context_entries) | The effective entries, summaries only, paginated. Filters: kind, status, tag, q (full-text search over title, summary and body) and include_disabled. | view_context |
Read a context entry (get_context_entry) | One entry in full, body_md and data included, by key. It may be inherited; level and source_project_slug say where it lives. | view_context |
Context entry history (get_context_entry_history) | The entry's change history, newest first and paginated. Each event names who acted and carries the values the entry held before that change. | view_context |
Create a context entry (create_context_entry) | Create an entry from key, kind, title and summary, plus optional body_md, data, tags, scope and agent_label. A key held by a live entry at the same level is refused (key_taken). | manage_context |
Create or replace a context entry (upsert_context_entry) | Omit expected_etag to create only. Pass the entry's ETag as expected_etag to replace it: title, summary, kind and body_md are replaced, data is replaced when sent, and tags and scope are kept when omitted. | manage_context |
Update a context entry (update_context_entry) | Change some fields under expected_etag. Omitted fields are kept, and data is a JSON merge patch. An inherited entry can't be updated from here. | manage_context |
Disable a context entry (disable_context_entry) | Disable the entry under expected_etag, with a required reason. It stops applying at once, stays in its history, and frees its key. There is no hard delete. | manage_context |
Restore a context entry (restore_context_entry) | Restore the most recently disabled entry for key. Refused (key_taken) if a live entry has taken the key since. | manage_context |
Corroborate a context entry (corroborate_context_entry) | Record that your key checked the version of a proposed entry named by expected_etag. The key that created or last changed the entry can't corroborate it. The entry stays proposed. | corroborate_context and view_context |
Everything an agent writes over MCP lands as proposed until a person confirms it in the web app; no tool confirms. agent_label names who is writing (up to 200 characters, shown on the entry and not verified); omit it and the entry is labelled with your key's name and prefix. expected_etag is the etag from your latest read or write. A stale one is refused with version_conflict, and the error carries the current ETag so you can re-read, re-apply and retry.
A key needs view_context to read entries: manage_context alone can write but not read, so an agent that does both needs both scopes. A write by a key without view_context returns only the entry's id, key, version, etag and status. Writes also need access to the level you write at: see Who can do what. Size limits, secret scanning and the other refusals are listed under Limits and refusals.
Projects and issues
These tools work with your workspace's Areas, Spaces and projects and the issues in them. Issues are named by their ISS-N ref. They are not findings: a finding (HYRAX-N) becomes an issue only when someone files it as one. Areas, Spaces and projects all go through the project tools, addressed by slug.
| Tool | What it does | Required scope |
|---|---|---|
List / get projects (list_projects, get_project) | The Areas, Spaces and projects you can see, or one of them with its repositories. | view_issues |
List / get issues (list_issues, get_issue) | Issues filtered by status, project, repo, assignee (me, none or a member's email) and labels; or one issue with its links, relations and pull requests. | view_issues |
Issue history (list_issue_events) | The issue's event history. | view_issues |
File an issue (file_issue) | File an issue in a project. | manage_issues |
File findings as issues (file_issues_from_findings) | Turn findings (HYRAX-N) into issues in a project. | manage_issues |
Update an issue (update_issue_fields, update_issue_status) | Change an issue's title, priority, assignee, labels, project or parent issue, or move it to another status. | manage_issues |
Close / reopen (close_issue, reopen_issue) | Close an issue, or reopen it under the same ISS-N. | manage_issues |
Claim an issue (claim_issue, renew_claim, release_issue) | Mark an issue as being worked on by your agent, keep the claim alive, or let it go. | manage_issues |
Notes, links and pull requests (note_issue, relate_issues, unrelate_issues, attach_pr) | Add a note, relate two issues, or attach a pull request. | manage_issues |
Acceptance criteria (add_acceptance_criterion, set_acceptance_criterion_met) | Add a criterion to an issue, or mark one met. | manage_issues |
Manage projects (create_project, update_project, add_repo_to_project, remove_repo_from_project) | Create or change an Area, Space or project, or change which repositories it covers. | manage_projects |
Writes also need a role on the project you write to, or on a level above it — see Organizing work.
Missions
Missions are in beta: Hyrax support turns them on per workspace, on the Paid plan. Without them, these tools are still listed but refuse the call. Missions are named by their MSN-N ref.
| Tool | What it does | Required scope |
|---|---|---|
Start a mission (create_mission) | Start a mission on a repo from a written directive, with a budget. | submit_program_jobs |
Resubmit a mission (resubmit_mission) | Start a new mission from a failed or cancelled one. The old one is left unchanged. | submit_program_jobs |
List / get missions (list_missions, get_mission, resolve_mission) | A repo's missions, one in full with its steps and status, or the repo a bare MSN-N ref runs on. | view_jobs |
Missions waiting on you (list_missions_waiting_on_me) | Missions that need a decision. | view_jobs |
Mission pull request (get_mission_pull_request) | The mission's pull request and its state. | view_jobs |
Mission settings (get_mission_settings) | The repo settings a mission uses, such as which CI checks it waits on. | view_jobs |
Pause a mission (pause_mission) | Pause a mission: the running step finishes, then it stops. | cancel_running_jobs |
Approving a plan, raising a budget, skipping a step and cancelling a mission aren't MCP tools — do those on the mission's page in the web app (see Missions).
Change Reviews
Change Reviews are in beta: Hyrax support turns them on per workspace. Without them, these tools are still listed but refuse the call. A change review reads every pull request linked to one Linear ticket, or a set of pushed branches, and says whether the change does what the ticket asks. It is named by the ticket's key (such as ENG-123) or, when it was started in Hyrax, by hx-<n>. A review that touches a repository you can't see is not shown to you.
| Tool | What it does | Required scope |
|---|---|---|
List / get change reviews (list_change_reviews, get_change_review) | The workspace's change reviews, most urgent first, or one in full. mine keeps only reviews with a pull request you opened, matched on the GitHub login whoami reports; repo keeps one repository's. | view_jobs |
Find a change review (find_change_review) | Where one branch or pull request stands (repo as org/repo, plus branch or pr_number): the change review that covers it, or the first step that stopped one and what to do about it, or that Hyrax has not seen it. "Hyrax couldn't check" means Hyrax could not tell, not that a step was missed; a step that needs a workspace setting names it and asks you to contact a Hyrax admin. | view_jobs |
Team readiness (list_change_review_readiness) | Per repository, how many branches have a change review, are blocked on a step the developer owns, need a workspace setting an admin changes, hit a check Hyrax couldn't make, or are waiting. Workspace admins also see each branch and who opened its pull request; everyone else sees their own branches. | view_jobs |
Set acceptance criteria (set_change_review_criteria) | Save the criteria a change review judges against. The next review run reads them. | submit_audit_jobs |
Start from branches (start_change_review_from_branches) | Start a change review over 1 to 10 pushed branches, with a Linear ticket or a written description of the change. It spends credit, starts at once, and posts nothing to GitHub or Linear. Hyrax reads the branches on GitHub, so work you have not committed and pushed is not reviewed. This is not review_branch, which reviews one branch's code. | submit_audit_jobs |
Starting a change review from pull requests, and re-running one, are done in the web app. Three prompts walk these tools for you: my_change_reviews, change_review_for_branch and start_change_review.
Tool arguments
Send only the arguments a tool declares. Each tool's tools/list entry carries the full input schema, and that schema is closed — it sets "additionalProperties": false.
An argument a tool does not declare is now refused. Previously it was ignored and the call was answered anyway, which is the worse outcome for an agent: an argument meant as a filter was dropped while the call still returned a successful tool result, so the agent received a wider result set than it asked for, with nothing in the response to tell it apart from a correctly filtered one.
A call carrying an undeclared argument now comes back as a tool error naming the offending key. A misspelled filter is the common case — the observations list takes priority, so prioritiy used to be dropped while the call returned every priority:
Error executing tool list_observations:
[invalid_payload] prioritiy: Extra inputs are not permitted
Wrapped to fit this column: the real message is one line. An argument of the wrong type or outside its limits (a job_id that is not a UUID, a limit of 0) is refused the same way: [invalid_payload], then the argument's name and what is wrong with it. That [invalid_payload] wording is newer than this caution: at first, these refusals carried a longer validation report that named the key in the same way.
If your client sends a stray argument today, it will start failing. Drop the key, or check the tool's schema for the argument you actually want. Optional arguments are unaffected — a closed schema is not the same as a required one, and every optional argument stays optional.
Prompts
The server also ships MCP prompts — ready-made instructions your client's model can load. In Claude Code they surface as slash-commands (/mcp__hyrax__<prompt>); other MCP clients list them under prompts.
| Prompt | Arguments | What it loads |
|---|---|---|
hyrax_agent_loop | — | The operating guide for an agent driving Hyrax autonomously: the forecast → submit → poll → read → fix loop, cost safety, scopes, and pagination. |
triage_new_findings | org, repo, branch | Triage a repo's new findings: group by priority and kind, propose fix / dismiss / acknowledge per finding, and ask before any cost-bearing call. |
investigate_finding | org, repo, branch, ref | Deep-dive one observation by its HYRAX-N ref: pull its full body, gather context, and summarize root cause + proposed remedy. |
branch_review | org, repo, base_branch, branch | Review a pushed branch before you open a pull request: run the review, check each finding against your code, and send a verdict for every finding. |
my_change_reviews | — | The change reviews that cover your own pull requests, the ones that need you first. Reads only. |
change_review_for_branch | — | The change review for the branch you have checked out — your client reads the repository and branch from your local checkout — or the step that is stopping one and how to fix it, including when only a Hyrax admin can change it. Reads only. |
start_change_review | — | Start a change review over pushed branches. Your client asks you which branches, and for a Linear ticket key or a description of the change, then confirms before it starts: it spends credit and posts nothing to GitHub or Linear. It first checks that your work is committed, pushed, and on its own branch rather than the default branch. This is not branch_review, which reviews your code. |
The three change review prompts are listed only in workspaces where Change Reviews are turned on.
For example, /mcp__hyrax__triage_new_findings with org=myorg repo=myrepo branch=main starts a guided triage session against that repo's open findings.
Setting up a client
Any MCP client that speaks streamable HTTP with a bearer header can connect. In Claude Code, add an HTTP MCP server entry (Cursor and others use the same fields):
{
"mcpServers": {
"hyrax": {
"type": "http",
"url": "https://api.hyrax.dev/mcp/",
"headers": { "Authorization": "Bearer hk_live_REPLACE_ME" }
}
}
}
The canonical endpoint is on the API host (api.<domain>). The app host also forwards /mcp/ to the same origin, so an existing https://app.hyrax.dev/mcp/ URL keeps working — but point new clients at the API host.
Verify the key before wiring an agent up by listing the tools directly:
curl -sS https://api.hyrax.dev/mcp/ \
-H "Authorization: Bearer hk_live_REPLACE_ME" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
The response enumerates every tool with its input schema.
The one place your agents read repo context
MCP is the only way Hyrax delivers discovery context to your agents — Hyrax writes no generated documentation into your repository. That is deliberate: a file committed into a repo is a snapshot that starts going stale the moment it lands, while an MCP read returns whatever the latest Discovery run produced. Re-run Discovery and every connected agent sees the new context on its next call, with no pull request to review and merge first.
To make an agent use it by default, point at the server from the instructions file your tool already reads — a CLAUDE.md, a Cursor rule — with a line such as "Before editing, read this repo's knowledge bundle and the rules that apply to the file from the hyrax MCP server."
See also
- API overview — keys, auth, and the REST surface.
- Findings & Code health — the observation model the MCP tools query.
- Issues and Missions — the work model behind the project, issue and mission tools.