# Runs and approvals over MCP

A run is one request worked by MAIA's agent. Over MCP, your client starts a run and gets back a run report, which holds progress while MAIA works, a question when MAIA needs your decision, and the answer with a link to the project at the end.

Updated: 2026-09-29. Source: https://maia-analytics.com/docs/mcp/runs-and-approvals

## What a finished run looks like

A run ends with a report like this one. `message` holds MAIA's answer, and `project_url` opens the map and the table.

```json
{
  "project_id": "3f6c1a2e-0000-0000-0000-000000000000",
  "project_url": "https://app.maia-analytics.com/project/3f6c1a2e-0000-0000-0000-000000000000",
  "run_id": "8d41b7c0-0000-0000-0000-000000000000",
  "status": "complete",
  "current_step": null,
  "steps": ["Searched parcels", "Created a layer", "Checked the result"],
  "message": "I found the parcels that match and added them as a layer.",
  "pending_input": null,
  "error": null
}
```

## The life of a run

1. **Start.** Your client calls `create_project` or `send_message`. MAIA starts at once and returns a project id and a run id.
2. **Follow.** Your client calls `get_run`, and the report shows progress. Set `wait_seconds`, up to 45, to hold the call open until the run ends.
3. **Answer, if asked.** When MAIA needs a decision, the status is `needs_input`. Your client brings the question to you and sends your answer with `respond`. The run continues.
4. **Read.** When the run ends, the report carries MAIA's answer and a link to the project.

A run takes from under a minute to several minutes.

## The run report

`create_project`, `send_message`, `get_run`, and `respond` all return the same report.

| Field | What it holds |
| --- | --- |
| `project_id` | The project the run belongs to |
| `project_url` | The link to the project in MAIA |
| `run_id` | The run's id |
| `status` | Where the run stands. See [Statuses](https://maia-analytics.com/docs/mcp/runs-and-approvals#statuses) |
| `current_step` | What MAIA is doing now |
| `steps` | The run's most recent steps, oldest first. The last one is in progress |
| `message` | MAIA's answer, once there is one |
| `pending_input` | What MAIA is waiting on, when the status is `needs_input` |
| `error` | What went wrong, when the run failed |

## Statuses

| Status | Meaning | What your client does |
| --- | --- | --- |
| `running` | MAIA is working | Calls `get_run` again |
| `needs_input` | MAIA is waiting on a question or an approval | Brings the question to you, then calls `respond` |
| `complete` | The run ended with an answer | Reads `message` and gives you `project_url` |
| `failed` | The run ended with an error, or reached its time limit | Reads `error` and tells you what went wrong. What MAIA finished is saved, and a new request is safe to send |
| `stopped` | The run was stopped | Opens `project_url` to show what MAIA kept |
| `idle` | No run has started on the project | Starts one |

## Questions and approvals

> **Note:** A question from MAIA is a question for you, not for your client. The connector's prompts tell the client to bring every question to you before it calls `respond`.

`pending_input` has a `kind`, and the kind decides how to answer.

| Kind | MAIA is asking | Your client answers with |
| --- | --- | --- |
| `question` | For a choice, from a list of options | `respond` with `choice` set to the option's id or label |
| `approval` | For permission to run a step | `respond` with `approve` set to `true` or `false`, and an optional `note` |

A question looks like this.

```json
{
  "kind": "question",
  "prompt": "Which size should I screen for?",
  "options": [
    { "id": "a", "label": "Over 5 acres" },
    { "id": "b", "label": "Over 10 acres" }
  ]
}
```

Three things to know before you answer:

- **MAIA asks a question only when the answer would change the result.** Everything else it decides, and it tells you which default it chose.
- **Every approval the web app asks for reaches your client.** The list is on [Dispatch](https://maia-analytics.com/docs/using-maia/dispatch). For a run above your row limit, the approval names the column and the row count. Approving spends credits.
- **Set `approve` to `false` and MAIA does not run the step.** The run goes on without it, and a `note` tells MAIA why.

## A worked sequence

> **You ask:** Find vacant industrial parcels over 5 acres in Maricopa County, Arizona.

1. `find_county` with `query` "Maricopa, AZ". It returns the county's five-digit code.
2. `create_project` with that code and the `request` "vacant industrial parcels over 5 acres". It returns a project id, a run id, and the status `running`.
3. `get_run` with the project id. The status is still `running`, and `steps` shows what MAIA has done.
4. `get_run` again. The status is `needs_input`, and `pending_input` holds a question with its options.
5. `respond` with the `choice` you picked. The run continues.
6. `get_run` again. The status is `complete`. `message` holds MAIA's answer, and `project_url` opens the map and the table.
7. `send_message` with the next request, such as "find contact details for these owners". A new run starts on the same project. Wait for `complete` first. MAIA refuses a new request while a run is in progress.

## Stopping a run

`stop_run` stops the current run on a project. A stop is not instant. MAIA halts at the next safe point and keeps what it has finished. Calling `stop_run` when nothing is running does no harm.

## Retrying safely

Pass a `request_id` to `create_project`. A repeated call with the same id returns the same project and the same run, and does not start a second one.

`request_id` protects `create_project` only. The other tools do not take one. See [Tools](https://maia-analytics.com/docs/mcp/tools).

## Limits

- **One run per project at a time.** MAIA refuses a new request on a project until its current run ends.
- **Several projects at once.** Runs on different projects do not wait for each other.
- **Approvals cannot be skipped.** A step that needs approval waits for it, over MCP as in the app.
- **Runs have a time limit.** Send a long request as several short ones.

## Related

- [Tools](https://maia-analytics.com/docs/mcp/tools) lists each tool's parameters.
- [Dispatch](https://maia-analytics.com/docs/using-maia/dispatch) covers questions and approvals in the web app.
