# Coding agents (MCP)

Copying a [prompt](/docs/prompts.md) is one round. Connected over MCP, a coding agent can go round after
round on its own: read what Repodar found, fix it, push, wait for the rescan, see what is left,
and stop when only the unfixable remains. Repodar is a remote MCP server at
`https://repodar.dev/mcp` (your `APP_URL` plus `/mcp` when self-hosted) over Streamable HTTP,
stateless: every request stands alone, answers are JSON, there is no session and no event stream.
It reads and queues rescans; it changes nothing, and it still never touches your repositories.

## Connect Claude Code

1. Register the server once, for every folder:

   ```sh
   claude mcp add --scope user --transport http repodar https://repodar.dev/mcp
   ```

   Without `--scope user` the server exists only in the folder you ran the command in.
2. Start a new Claude Code session. Servers load when a session starts, so a session that was
   already open does not see it.
3. Run `/mcp`, pick **repodar**, choose **Authenticate**. Claude Code finds the sign-in on its own
   (OAuth 2.1 discovery, dynamic client registration, authorization code with PKCE) and opens your
   browser on Repodar.
4. Sign in with GitHub if you are not already, read what the agent asks for (read your repos and
   findings, queue rescans) and click **Allow**. Back in the terminal, repodar shows as connected.
5. Try it: "list my repos in repodar", or "get the vulnerability prompt for `owner/name` and work
   through it". The agent keeps its token and renews it by itself for up to 90 days.

**Settings > Coding agents (MCP)** lists every connected agent with a **Revoke** button; revoking
ends its tokens at once and it has to ask again.

## Other clients

Any MCP client that supports Streamable HTTP and OAuth 2.1 with dynamic client registration
connects the same way: point it at `https://repodar.dev/mcp`, approve it once in the browser.
Clients that only take a static bearer token are not supported: Repodar issues no long-lived
tokens to paste.

## Tools

Every tool answers with one JSON text block whose first field, `summary`, is a one-line account of
the result; every object about a repository carries `repo` (`owner/name`). A repository is named
`owner/name` (case does not matter) or by its Repodar id. A repository outside your workspace is
"not found", exactly like one that does not exist. Answers are compact JSON; a list longer
than 200 rows is cut at 200 with `truncated: true`. Dates in and out are ISO 8601 date-times
(`2026-10-27T09:30:00Z`); a date without a time is refused.

| Tool | Input | Returns |
| --- | --- | --- |
| `list_repos` | `filter?` (the dashboard's [filter syntax](/docs/filter-syntax.md)) | the dashboard rows, worst first: runtime and CI versions, frameworks, deploy target, open vulnerabilities by severity (production; dev-only and no-fix-yet counted apart), last scan |
| `get_repo` | `repo` | the repository page as data: Runtime and CI groups, frameworks, deploy target and where it came from, package managers, scan paths, warnings, the latest scan, every open finding (for vulnerabilities: package, version, ecosystem, advisory ids and link, `fixedIn` = lowest fixed version, `noFixYet`, `dev`, `firstSeenAt`), the findings resolved in the last 7 days and what each platform observes (`observations`: provider, `connection` = the label when the workspace has several connections of that provider, else null, kind, name, runtimes, last deploy) |
| `get_prompt` | `repo`, `kind`: `upgrades` or `vulnerabilities` | the Markdown prompt, byte for byte what `upgrade.md` / `vulns.md` serve, after a JSON header |
| `rescan` | `repo` | `queued: true` with `at`, or `queued: false` with `reason` `in_flight` (a scan is already queued or running) or `cap` (the workspace's daily scan cap is used up) |
| `scan_status` | `repo`, `since?` (ISO 8601) | `serverTime`, the latest scan (status, trigger, start, finish, error) and `doneSince`: whether a scan finished, ok or failed, after `since` |
| `findings_diff` | `repo`, `since` (ISO 8601) | findings opened after `since` (`new`, including reopened ones), resolved after it (`resolved`), vulnerabilities that gained a fix after it (`fixAvailable`), and counts of what is still open |

The two prompts are also MCP prompts, `repodar-upgrades` and `repodar-vulnerabilities`, with a
`repo` argument; those end with the loop below.

## The loop

1. `get_prompt` for the repository (or one of the two MCP prompts).
2. Make the changes it lists, one commit per item, as the prompt says.
3. Just before pushing, call `scan_status` and keep its `serverTime`; then push to the default
   branch: a push scans the repository automatically. If nothing was pushed to the default branch,
   call `rescan` instead and keep the `at` it returns.
4. Call `scan_status` with `since` set to that `serverTime` (or `at`) every 10 seconds until
   `doneSince` is true. Use Repodar's time, never the agent's own clock: the two can disagree. A
   scan usually takes under a minute; one that checks your runtime sources first can take a few.
5. Call `findings_diff` with the same `since`: what was resolved, what is new, what gained a fix.
6. Repeat until the only open findings are vulnerabilities with `noFixYet: true`. Those have
   nothing to update to yet: the agent lists them and stops. The daily digest says so the day a
   fix is published.

## Limits and what it can do

The agent can read your repositories, findings and prompts and queue scans; it cannot change
anything in Repodar (no settings, no tokens, no repositories) and Repodar still never touches the
repositories themselves. Each signed-in user gets 60 requests a minute across their agents.
Rescans from MCP follow the **Rescan** button (sources collected first when one is connected,
coalesced with a scan already queued or running) with one difference: they are exempt from the
12-per-repository daily limit, because a fix loop rescans the same repository many times, and
they still count towards, and stop at, the workspace's 500 scans a day. Token lifetimes and
revocation are in [security](/security.md#coding-agents-mcp).
