MCP
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.
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.
{
"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#
- Start. Your client calls
create_projectorsend_message. MAIA starts at once and returns a project id and a run id. - Follow. Your client calls
get_run, and the report shows progress. Setwait_seconds, up to 45, to hold the call open until the run ends. - Answer, if asked. When MAIA needs a decision, the status is
needs_input. Your client brings the question to you and sends your answer withrespond. For an approval you agree to, it callsapprove_step. The run continues. - 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, respond, and approve_step all return the same report.
| Field | What it holds |
|---|---|
project_id | What it holdsThe project the run belongs to |
project_url | What it holdsThe link to the project in MAIA |
run_id | What it holdsThe run's id |
status | What it holdsWhere the run stands. See Statuses |
current_step | What it holdsWhat MAIA is doing now |
steps | What it holdsThe run's most recent steps, oldest first. The last one is in progress |
message | What it holdsMAIA's answer, once there is one |
pending_input | What it holdsWhat MAIA is waiting on, when the status is needs_input |
error | What it holdsWhat went wrong, when the run failed |
Statuses#
| Status | Meaning | What your client does |
|---|---|---|
running | MeaningMAIA is working | What your client doesCalls get_run again |
needs_input | MeaningMAIA is waiting on a question or an approval | What your client doesBrings it to you. Calls respond with your answer or your decline, or approve_step when you approve |
complete | MeaningThe run ended with an answer | What your client doesReads message and gives you project_url |
failed | MeaningThe run ended with an error, or reached its time limit | What your client doesReads error and tells you what went wrong. What MAIA finished is saved, and a new request is safe to send |
stopped | MeaningThe run was stopped | What your client doesOpens project_url to show what MAIA kept |
idle | MeaningNo run has started on the project | What your client doesStarts 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, and every approval to you before it calls approve_step.
pending_input has a kind, and the kind decides how to answer.
| Kind | MAIA is asking | Your client answers with |
|---|---|---|
question | MAIA is askingFor a choice, from a list of options | Your client answers withrespond with choice set to the option's id or label |
approval | MAIA is askingFor permission to run a step | Your client answers withapprove_step with the approval_id and the summary, unchanged, once you say yes. To decline, respond with decline set to true and an optional note |
A question looks like this.
{
"kind": "question",
"prompt": "Which size should I screen for?",
"options": [
{ "id": "a", "label": "Over 5 acres" },
{ "id": "b", "label": "Over 10 acres" }
]
}An approval looks like this. summary says what the step does and what it uses.
{
"kind": "approval",
"prompt": "MAIA needs approval before it runs this step.",
"action": "Enriching owner contacts",
"approval_id": "toolu_01A2B3C4D5E6F7G8",
"summary": "Enrich 1,200 rows of Owner contacts on Parcels. That is past your 500-row limit per reply. This run uses 1,200 credits, and leaves 3,800."
}Four 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. For a run above your row limit, the summary names the column, the row count, and the credits. Approving spends credits.
- Only
approve_stepapproves a step, and your client asks you first. Your client must send theapproval_idand thesummaryexactly asget_rungave them, or MAIA refuses the call. Your client asks you before eachapprove_stepcall. If you set the tool to "always allow" in your client, it no longer asks. - Decline with
respondand MAIA does not run the step. Setdeclinetotrue. The run goes on without the step, and anotetells MAIA why.
A worked sequence#
You ask
Find vacant industrial parcels over 5 acres in Maricopa County, Arizona.
find_countywithquery"Maricopa, AZ". It returns the county's five-digit code.create_projectwith that code and therequest"vacant industrial parcels over 5 acres". It returns a project id, a run id, and the statusrunning.get_runwith the project id. The status is stillrunning, andstepsshows what MAIA has done.get_runagain. The status isneeds_input, andpending_inputholds a question with its options.respondwith thechoiceyou picked. The run continues.get_runagain. The status isneeds_inputagain, andpending_inputholds an approval. Your client shows you itssummary.- You say yes. Your client asks you to confirm the
approve_stepcall, then sends theapproval_idand thesummaryunchanged. The run continues. get_runagain. The status iscomplete.messageholds MAIA's answer, andproject_urlopens the map and the table.send_messagewith the next request, such as "find contact details for these owners". A new run starts on the same project. Wait forcompletefirst. 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.
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.