# Prontto > Prontto is the workspace a design studio and its clients share: requests and briefs, deliverables > and revisions, tasks, quotes, invoices, presentations, knowledge base, chat and calls. Everything a > person can do in the app is available to you as an operation — 638 of them, over MCP > or HTTP — and you perform each one AS the person who signed in, never above their permissions. ## Connect - **MCP endpoint (preferred):** https://portal.prontto.co/api/mcp — Streamable HTTP, stateless. - **Authentication:** OAuth 2.1. Dynamic client registration and PKCE (S256) are supported, so you need no credentials in advance: register, send the person to the authorize URL, they sign in and approve, you receive tokens. Ask for the `offline_access` scope to get a refresh token. Discovery: https://portal.prontto.co/.well-known/oauth-authorization-server and https://portal.prontto.co/.well-known/oauth-protected-resource. An unauthenticated call answers 401 with a `WWW-Authenticate` header pointing at that metadata. - **Alternative for clients that cannot open a browser:** the person creates a personal API key at https://portal.prontto.co/admin/settings (staff) or https://portal.prontto.co/portal/settings (clients) and you send it as `Authorization: Bearer pk_…` — to https://portal.prontto.co/api/mcp or to the REST API at https://portal.prontto.co/api/v1. - **Narrow the toolset** when 638 tools is too many for your client: `https://portal.prontto.co/api/mcp?modules=requests,comments,tasks`. The `core` module is always included. ## Start here 1. `core.me` — who the person is, whether they are studio staff or a client, and which organisations they belong to. Call this first; several operations need an `organizationId` and this is where you learn it. 2. `core.capabilities` — every operation this person may call, with its kind and summary. 3. `core.search` — one query across requests, tasks, deliverables, quotes, people and documents. 4. `core.events.list` — what changed since a timestamp, for "what happened while I was away". ## Conventions - **Tool input is flat.** Over MCP the path, query and body fields of an operation are merged into one object. Over HTTP they are where you expect them. - **Confirmation.** 65 operations delete, archive, charge, or send something to a customer. They refuse to act until you pass `confirm: true`, and return a preview of what they would do instead. Show that preview to the person and let them decide. Never pass `confirm` on your own initiative for anything that spends money or contacts a client. - **Reads are free of side effects** (249 of them) and are the ones marked `readOnlyHint`. - **Idempotency.** Operations that say so accept an `idempotencyKey`; reuse the same key when you retry so a timeout cannot create the same thing twice. - **Paging.** List operations take `page` and `pageSize` and return `total`. - **Asking, rather than fetching and counting.** The main list operations take a window over a NAMED date — `dateField` with `from`/`to`, where a civil date (`2026-08-01`) is read in the workspace time zone and a `to` covers that whole day — plus `count: true` for a total with no rows and `groupBy` for a count per bucket, labelled. "How many critical errors did each designer log in August" is one call: `tasks.list` with `deliverableQuality`, `dateField=created`, `from`, `to` and `groupBy=assignee`. Do not page through rows to count them; a page boundary you cannot see makes the answer confidently wrong. Speaking it today: `tasks.list`, `requests.list`, `invoices.list`, `quotes.list`, `audit.events.list`, `deliverables.recent`. - **Too much data?** Narrow the ROWS with `fields`, naming the columns you want (`id` always survives). Do not retry with a smaller `pageSize` — that loses rows rather than weight. - **Acting on a set** is one call: `tasks.bulk` applies one change to many ids. Do not loop. - **Errors** arrive as `{ error: { code, message, details } }` with a stable `code` from: missing_bearer, invalid_api_key, rate_limited, forbidden, read_only_key, not_found, validation_failed, conflict, confirmation_required, unprocessable, payload_too_large, budget_exceeded, module_disabled, job_pending, unavailable, internal. - **Rate limit:** 300 requests per minute per key. A 429 carries `Retry-After`. ## Modules announcements, audit, billing, calls, chat, comments, configuration, configurator, core, customers, deliverables, files, identity, instant_render, invoices, knowledge_base, news, notifications, organizations, people, presentations, projects, quotes, recordings, remote_desktop, requests, shares, tasks, tgeo, webhooks. ## Numbers, and what they mean `tasks.analytics.kpis` returns the studio KPIs for a window — delivery reliability, client outcome, data integrity, flow dwells, delivery quality, judgment and supervision coverage, client reply latency and silent misses. Narrow it with `sections`. It takes no organizationId on purpose: these measure the studio's own operation, not one client's work. Before quoting any of them, read `tasks.analytics.metrics`. For each of the 40 metrics it gives the label, what it measures, why it matters, which rows it reads, and the CAVEAT — the common misreading. Several are rates whose denominator is the point: a CSAT over a 5% response rate is a vox pop, and saying the number without the denominator is how a figure becomes a lie. `tasks.analytics.evidence` returns the exact rows behind one number, so it can be checked rather than believed; that one does accept an organizationId. For one person, `people.kpis.get` returns the scorecard and the flow figures together. ## Building furniture The configurator is a parametric furniture builder — parts drawn as formulas, components of parts placed by formula, items that may be sizes, rooms with units placed and checked — and every act of its three builders is an operation (`configurator.*`, 43 of them). Before building anything read the guide: the MCP resource `prontto://guides/configurator`, or https://portal.prontto.co/llms-configurator.txt over HTTP. It gives the model, the formula vocabulary and the order of calls; the `build_cabinet` prompt encodes the same sequence. Start with `configurator.draft.get`, check with `configurator.parts.solve` and `configurator.components.compile` before every save, and place units with `configurator.environments.place` so they snap the way a drag would. ## Prompts worth reusing The MCP server ships workflow prompts that encode the sequencing these operations expect: `morning_briefing` (what needs the person's attention), `triage_queue` (studio staff only), `client_update` (draft an update for a client and post it after approval), and `quote_from_brief` (turn a written brief into a priced quote), and `build_cabinet` (studio staff: draw, build and place a cabinet in the configurator, checking every step). ## Interactive views Six read operations carry an interactive card for hosts that render MCP Apps or the ChatGPT Apps SDK: `requests.list`, `requests.get`, `deliverables.pendingReview`, `quotes.list`, `quotes.get` and `tasks.attention`. If your host does not render UI, ignore the `_meta` and use the structured output; nothing is lost. ## Reference - Human-readable API reference: https://portal.prontto.co/api/docs - OpenAPI 3.1 document: https://portal.prontto.co/api/v1/openapi.json - Install instructions for people: https://portal.prontto.co/connect ## What to tell the person After you connect, say plainly what you can now do for them and what you will always ask before doing. If they are a client, that is: follow their requests, read and approve deliverables, and chase what is late. If they are studio staff, add: triage the queue, assign and schedule work, draft client updates, and build quotes.