# Nightjar MCP

Delegate background work to Codex or Claude from your AI assistant. Start with a prompt; saved agents are optional.

**Endpoint:** `https://app.usenightjar.com/mcp` · Streamable HTTP · OAuth or workspace API key

The domain changed on September 19, 2026. Update older MCP configurations to this endpoint and sign in again: OAuth grants are bound to their original server address. Browser bookmarks for the old dashboard redirect to the new address; MCP clients must use the endpoint directly.

Read the [pilot limits and reliability contract](./pilot.md) before delegating sensitive or irreplaceable work.

## Connect

Connect your own Codex or Claude account in the Nightjar dashboard, then add Nightjar to your client:

**Codex**

```sh
codex mcp add nightjar \
  --url https://app.usenightjar.com/mcp
codex mcp login nightjar
```

**Claude Code**

```sh
claude mcp add --transport http nightjar \
  https://app.usenightjar.com/mcp
claude mcp login nightjar
```

In an interactive Claude session, `/mcp` also offers authentication. For a headless session, use `claude mcp login nightjar --no-browser`. The browser asks you to select a workspace and choose **Read only** or **Delegate and manage runs**. Read-only access can inspect work; delegation access can also start, answer, follow up, recover, and cancel runs. Manage or revoke access under **Developers → MCP** in Nightjar.

Clients refresh their connection automatically, including after you sign out of Nightjar in the browser. To end a client's access, use **Disconnect** under **Developers → MCP**. Losing workspace membership also blocks access.

Then try:

> Use Nightjar to create a short checklist for testing a signup flow in the background. Give me the run link.

For another deployment, replace the endpoint. If authorization expires or is revoked, sign in again through your client's MCP settings.

## API keys for unattended clients

As an alternative to browser sign-in, create a workspace key under **Developers → API keys**. Set `NIGHTJAR_API_KEY` in the environment that launches the client, then configure it with one of these commands:

```sh
codex mcp add nightjar \
  --url https://app.usenightjar.com/mcp \
  --bearer-token-env-var NIGHTJAR_API_KEY
```

```sh
claude mcp add-json nightjar \
  '{"type":"http","url":"https://app.usenightjar.com/mcp","headers":{"Authorization":"Bearer ${NIGHTJAR_API_KEY}"}}'
```

Keep the single quotes in the Claude command: its configuration stores the variable reference, and Claude expands it when connecting. Add `--scope user` to make the Claude entry available across projects. A `401` with API-key authentication means the key is missing, invalid or revoked; check that the client inherited the variable. [Claude configuration reference](https://code.claude.com/docs/en/mcp)

## Tools

| Tool              | Use it to                                                                      |
| ----------------- | ------------------------------------------------------------------------------ |
| `get_environment` | Check available providers, execution setup and authorized connections.         |
| `list_agents`     | Find optional saved instructions and defaults.                                 |
| `create_run`      | Start background work; only `prompt` is required.                              |
| `get_run`         | Read status, results and recent events; optionally wait for completion.        |
| `list_runs`       | Find previous work with bounded filtering and pagination.                      |
| `follow_up_run`   | Start a new invocation using an earlier run's goal and result as context.      |
| `answer_run`      | Answer a saved question by exact request ID; continue with its goal and files. |
| `recover_run`     | Request bounded recovery of the existing Environment without repeating work.   |
| `cancel_run`      | Stop work or close a saved question.                                           |

Tools expose their argument schemas through MCP. List tools accept bounded queries, limits and cursors. The small tool catalog works with both upfront loading and client-managed tool search.

## Start and collect work

The minimum `create_run` arguments are:

```json
{ "prompt": "Return a short checklist for testing a signup flow." }
```

Give a self-contained prompt: chat history and local files are not transferred. Nightjar selects a ready provider account belonging to the signed-in user or API-key creator. Override defaults with `provider`, `model`, `reasoning`, `environmentId`, `agentId`, `connectionIds`, `outputSchema` or `timeoutSeconds`. Use `get_environment` when setup or available choices are unclear. Select connections explicitly for an ad hoc run; a workspace connection is not automatically granted to every run. Connection selection controls service access, not machine isolation.

Submission returns a durable run ID, status and dashboard URL. Continue other work, or call `get_run` with that ID:

```json
{ "runId": "RUN_ID_FROM_CREATE_RUN", "waitSeconds": 20 }
```

`waitSeconds` is 0–20; use 20 when waiting instead of rapid polling. The wait returns early when the run no longer needs observation. Follow `next` and `run.lifecycle`: read the final result only when `resultReady` is true, and keep observing while `observing` is true, including recovery and pending publication. `terminal` describes a stopped provider outcome; it does not establish that a result is ready or that cleanup was confirmed. Closing the chat, disconnecting MCP, or ending a wait does not cancel execution. Use `cancel_run` explicitly.

Results are bounded: `outputLimit` defaults to 8,000 characters and accepts up to 16,000. Pass `output.nextOffset` as `outputOffset` until it is null to read the full result. `eventLimit` defaults to 3 and accepts 0–20. Lists return `nextCursor` for more matches.

## Live applications

Ask for a live application in the ordinary goal, for example: `{"prompt":"Build a React habit tracker and give me its public URL."}`. `get_environment` reports whether publishing is enabled for the workspace. Static and React/Vite apps publish to a dedicated Vercel project with a stable public URL; updates reuse the same app. No Vercel connection is required.

The agent inside the dev box automatically receives four local tools: `publish_app`, `get_deployment`, `list_apps`, and `get_deployment_logs`. These build local files and request deployment through Nightjar. The remote delegation endpoint includes nine tools; it does not upload files from your local machine. The native agent follows structured status and diagnostics, with at most two repair attempts after the initial attempt.

Read the `apps` entries returned by `get_run`; only `state: "live"` with a non-null `liveUrl` establishes a verified publication. A completed model run can still have a pending or failed deployment, so reread `get_run` while an app is pending. Follow up on the run to request changes to its existing app. Published files are public; servers, SSR, databases, and app secrets are unsupported. The current pilot allows ten apps per workspace and 25 MiB per deployment, with a finite hosting lease. See the [pilot limits and current lease](./pilot.md#hosting-lease) before depending on a public URL. Publication metadata records the last verified deployment; a later operator pause or lease expiry can make that URL unavailable.

## Collect project files and GitHub work

For a coding goal, ask Nightjar to leave the project files in its workspace. To deliver through GitHub, explicitly select a connection with write access and ask for a pushed branch or pull request. The final `get_run` response includes optional artifact metadata and verified GitHub delivery links alongside the existing summary and structured result.

Artifact entries include the ZIP name, byte size, SHA-256 digest, and an authenticated `downloadUrl`. Open the run's dashboard URL and choose **Download ZIP**, or have your backend download with SDK 1.1.0's `runs.downloadArtifact(runId, artifactId)`. The ZIP bytes are not embedded in MCP responses, and the URL requires access to the run. **Download summary** in the dashboard saves only the Markdown response. Saved ZIPs remain available while the Environment sleeps.

GitHub entries identify the repository, branch, commit SHA, branch URL, and optional pull request. Return those links to the user when present. Do not claim a project download or pull request exists from summary text alone; report `artifactError` if capturing the ZIP was unavailable. Runs without project files and older runs can omit these fields. See [project downloads in the SDK guide](./sdk.md#project-downloads-and-github-work) for API access, download limits, and backend examples.

Supply `idempotencyKey` for submissions you may retry. Retry an uncertain submission with the same arguments and key; changing the key can create duplicate work. Use `follow_up_run` when `lifecycle.canFollowUp` is true. It starts a new provider invocation with prior goal/result context; it does not resume the native Codex or Claude session. Your own run retains its Environment. Following up on a teammate's run uses your own account and Environment; files are not copied between Environments.

Signed webhooks can notify your application when work changes. They do not automatically wake the originating chat. See the [SDK guide](./sdk.md) for API integration and webhook verification.

## Durable conversations and notifications

The updated server adds `conversationId`, `originalGoal`, structured `attention`, `recovery`, queue explanations, and `lifecycle` to run summaries. List summaries bound the original goal and attention message to 240 characters and omit choices and accepted answer text; call `get_run` for the full question before asking the user. An answer returns a new attempt in the same conversation and Environment, retaining accepted answers and files. `answer_run` and `recover_run` require write scope and access to that Environment. Client tool discovery may need refreshing after the server update.

When `lifecycle.canAnswer` is true, display the question and optional choices from `run.attention`. Obtain the user's answer, then call `answer_run`:

```json
{
  "runId": "RUN_ID_WITH_THE_QUESTION",
  "requestId": "EXACT_ATTENTION_ID_FROM_GET_RUN",
  "answer": "The answer supplied by the user."
}
```

The `next` suggestion identifies the question but deliberately omits the answer; obtain it from the user before calling the tool. Persist and observe the returned continuation's `run.id`. Repeating the same question ID and answer returns that same continuation. A conflicting or closed question returns an error; reread the run and use `attention.continuationId` when an answer was already accepted. An attention event can precede a safe pause, so wait for `canAnswer` before submitting.

Automatic environment recovery needs no user response. If its five attempts are exhausted, `recovery` includes the diagnostic and `next` suggests `recover_run` for another bounded cycle. This inspects the same existing process without repeating the goal or extending its lease. Keep observing until `executionUnconfirmed` clears, then answer the saved question or explicitly follow up when the lifecycle allows it.

With explicit user authorization, `create_run` can include `notification: {connectionId}` for the selected Slack account’s self destination. The server delivers actionable attention, failure, and completion notices independently of the model; the run exposes delivery status. Routine progress and automatic recovery do not require a Slack interruption. Never infer a Slack recipient from a prompt.
