Skip to content

MCP

The same API, addressed to an assistant rather than to a scenario. An MCP client chooses what to call while it is running, from the tool descriptions — so what it reaches is exactly what the credential behind it reaches, and every tool is a public API call underneath.

One endpoint

Everything goes to POST /v1/mcp. There is no session to open and no stream to hold: GET and DELETE answer 405, and each message is its own request.

POST https://api.mosaqo.app/v1/mcp
Authorization: Bearer $MOSAQO_KEY
MCP-Protocol-Version: 2026-07-28

Protocol revisions 2025-03-26 through 2026-07-28 are all answered. A client that opens with initialize gets the handshake it expects; one that states its version on every request is served that way instead.

Connecting with an API key

The quickest route, and the right one for a tool you run yourself. Any key works as a bearer token, and the tools the assistant is offered are cut to that key's scopes.

Most clients take a block like this one:

{
  "mcpServers": {
    "mosaqo": {
      "type": "http",
      "url": "https://api.mosaqo.app/v1/mcp",
      "headers": { "Authorization": "Bearer $MOSAQO_KEY" }
    }
  }
}
curl -X POST https://api.mosaqo.app/v1/mcp \
  -H "Authorization: Bearer $MOSAQO_KEY" \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: tools/list" \
  -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }'

Connecting through OAuth

For a connector in somebody else's directory, where the person never handles a key. Discovery follows RFC 9728 and RFC 8414, clients register themselves with RFC 7591, and every authorization uses PKCE with S256.

curl https://api.mosaqo.app/.well-known/oauth-protected-resource
curl https://api.mosaqo.app/.well-known/oauth-authorization-server

An unauthorized call says where to go and what to ask for:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="Mosaqo MCP",
  resource_metadata="https://api.mosaqo.app/.well-known/oauth-protected-resource",
  scope="qr:read analytics:read reviews:read exports:read"

Whoever approves is signed in to Mosaqo, picks the workspace it applies to, and can only do so where they are an owner or an admin — the same line that decides who may issue an API key. They can disconnect it afterwards under Bulk & API.

What an assistant can do

The scopes you already know, unchanged. A tool the credential does not allow is not listed in tools/list and cannot be called by naming it anyway, so the live answer for any connection is tools/list itself.

ScopeGrants
qr:readList and read QR codes, folders and templates
qr:writeCreate, update, retarget, publish, archive and delete
exports:readDownload rendered cards
analytics:readAggregate analytics and individual scans
bulk:writeCreate and read bulk jobs
webhooks:writeManage webhook subscriptions
reviews:readPlaces, surveys and how they are doing — never the answers themselves

What it will never reach

What people wrote in a survey. reviews:read opens your places, your surveys and how they are doing — the counts, the scores, the spread of answers per question. The sentences a visitor typed are returned here no more than anywhere else a credential can reach, for the same reason the feedback.* events carry a score and never the words.

Deleting a code. The REST route asks for a typed confirmation because destroying a printed code's redirect cannot be undone, and that is not a confirmation an assistant gives on somebody's behalf. Archiving is offered instead, and it reverses.

Writing is marked as writing. A tool that changes something carries readOnlyHint: false, and archiving carries destructiveHint: true — which is what makes a client stop and ask a person before it runs.