Muvia runs an MCP (Model Context Protocol) server so that AI assistants and agents can use Muvia directly: look up projects, read data, run queries and propose changes. It is the richest way in; the REST API is the simple, read-only one.
https://api.muviabi.com/mcp/v1
The transport is JSON-RPC 2.0 over HTTP POST. Send
Content-Type: application/json and
Accept: application/json, text/event-stream; the answer arrives as a
server-sent event with one data: line holding the JSON-RPC response. The
protocol version is 2025-06-18. A complete exchange is in the
Agent quickstart.
| Who | How |
|---|---|
| A person's assistant (Claude, ChatGPT, an IDE) | OAuth. The person adds the URL as a connector, signs in to Muvia and grants scopes. The assistant acts as that person. |
| An integration or agent without a person | An mvk_ API key, sent as Authorization: Bearer $MUVIA_API_KEY. It acts as the key, in the key's company, within the key's scopes. |
API keys are the same keys the REST API uses (X-Api-Key); see
Authentication.
Send tools/list. Every tool has a name, a description, an inputSchema
(JSON Schema) and annotations. Call whoami first, then list_projects:
every other tool acts inside one project. If your client cannot search a long
tool list, find_tools names the tools of an area (datasets, signals, nodes,
alarms, dashboards, analyses, reports, documents, predictors).
MCP tools lists every tool of the server, by area: what it does,
whether it reads or writes, its write mode and its arguments. tools/list
answers the same tools, narrowed to what your key or connection may use.
Tools return their result as structuredContent (an object) and as text in
content. Tables are {"columns": [...], "rows": [[...]]}. A failure is a
result with isError: true, not an HTTP error.
| Annotation | Meaning |
|---|---|
readOnlyHint: true | The tool only reads. Safe to call freely. |
no readOnlyHint (with destructiveHint: false) | The tool writes: it creates or changes something. |
destructiveHint: true | The tool writes and deletes or cannot be undone. Ask the person before calling it. |
All tools carry openWorldHint: false: they act on Muvia only.
A write tool does not change Muvia on the spot. It files a proposal, and what happens next is the company's policy for that kind of change:
{"status": "pending", "action_id",
"approve_url", "summary", "needs_admin"}. Nothing has changed. A person
opens approve_url in Muvia and approves or discards it. Give them the link;
do not retry.{"status": "applied", "action_id", "id",
"url"}. The change is made and url opens it in Muvia.Either way, get_action with the action_id tells what became of the proposal:
pending, applied (with its result), discarded, stale, expired or
failed (with a reason). Anything that needs an administrator waits for one,
whatever the policy.
A key writes only when an administrator has turned on «Can write through
assistants» on it, in Settings › Company › API keys. It is off by default, and
the key's scopes still apply: a key without analysis_annotate cannot annotate,
whatever the policy says. Without the switch, a write tool answers with
isError: true and this text, and reads are unaffected:
This API key can only read. To propose or make changes through an assistant, an administrator must turn on «Can write through assistants» on the key, in Settings › Company › API keys.
Some tools stay a person's even for a writing key and answer «Only a person can do this: connect the assistant with your own account.» They are: a person's own notes and the browser drop link. Changes that belong to the person who makes them are always proposed by a key, whatever the policy, and the person who confirms them applies them and owns the result: creating, editing, sharing or deleting an analysis; a notebook made from an analysis; public links to an analysis, a dashboard or a notebook; annotations and event notes; creating a project; Athena's memory; running a notebook; acknowledging, shelving, unshelving or noting an alarm. Writes that need an administrator always wait for one. Everything else (dashboards, datasets, flows, channels and the rest) follows the company's policy.
A change made by a key appears in Muvia as authored by «API key» and the key's name. A proposal that a person confirms is applied as that person. A person's OAuth assistant writes within the scopes the person granted.
The REST GET /v1/whoami answers the same writes for a key, as
mcp.writes. This tool answers who the connection acts as and what it may do:
| Field | Meaning |
|---|---|
kind | api_key for a key, user for a person's assistant. |
company | {id, name} of the company. |
key | For a key: {name, created_by}. |
user | {id, email} of the person, or null for a key. |
client | {client_id, name} of the assistant application, or null for a key. |
scopes | The scopes the connection holds. |
permissions | The permissions those scopes resolve to. |
writes | A boolean: whether this connection may write through MCP. For a key, whether «Can write through assistants» is on. |
{
"kind": "api_key",
"company": { "id": "6aa95e431b5b18b1850a2a21", "name": "ACME srl" },
"user": null,
"client": null,
"key": { "name": "Reporting agent", "created_by": "Anna Rossi" },
"scopes": ["datasets_read", "settings_read"],
"permissions": ["datasets_read", "settings_read"],
"writes": false
}
Each key has its own limits. Reads share the REST per-key per-minute limit (the
same number as REST; see Rate limits); writes are limited
to 30 per minute per key. Past a limit the tool answers isError: true with
«This key made too many requests in a minute: try again in N seconds.» or «This
key made too many changes in a minute: try again in N seconds.» Wait that long.
A call that cannot run answers isError: true; a malformed JSON-RPC
request answers a JSON-RPC error. A missing, wrong or expired key answers
HTTP 401.