MCP endpoint (POST only)
- Sandbox: available
- Staging: available
- Production: unknown
curl -X GET 'https://api.sandbox.ovok.com/mcp'Create or update a localization PUT
Sets the value of one key in one language. Creates the localization if it does not exist yet. **Auth:** bearer token. **Scope:** the caller's project (from the token). Localizations are read and written with your token. ## Behaviour - `language` must be one of the languages in your project's locale settings (`GET /locales`). - `key` is a dot-separated path such as `home.screen.title`. It may contain letters, digits, `_`, `-` and `.`, and must not start with `.`. - Ovok sets `author` to your profile. If more than one entry exists for this key and language, the first is kept and the others are deleted. - After the write, a background job runs for every project language. It creates an AI translation of the default-language value for each language that has no entry for this key yet. Existing translations are not changed. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/localization/en-US/home.screen.title' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "value": "Home" }' ```
MCP endpoint POST
Ovok's MCP server, for Claude or any MCP client: it sets up the project it is connected to, as one of the project's admins. **Auth:** an access token from Ovok's MCP OAuth server, never a Medplum token. Clients find it the standard way: 1. A `GET`, `POST` or `DELETE` without a token answers 401 with `WWW-Authenticate: Bearer resource_metadata="…/.well-known/oauth-protected-resource/mcp"`. 2. That document names the authorization server, `<this host>/mcp`. Its metadata is at `/.well-known/oauth-authorization-server/mcp`. 3. The client registers itself at `/mcp/register`, sends the user to `/mcp/authorize` (PKCE S256), and exchanges the code at `/mcp/token`. The answer to the client carries `iss`, this authorization server's issuer (RFC 9207), on allow and on deny. Sign-in and consent happen on the Ovok console. Only an admin of the project can connect a client, and never to the Super Admin project. ## Behaviour - Streamable HTTP, stateless: send every JSON-RPC message with `POST`, one per request. A batch answers 400. There are no sessions: `GET` and `DELETE` answer 405 to a caller with a valid token, and 401 without one. - `server/discover` (MCP 2026-07-28) answers the protocol versions this server speaks, its `tools` capability and its name. None of those versions is 2026-07-28 yet: start with `initialize`. - `/mcp`, its OAuth routes and both MCP metadata documents answer with `Strict-Transport-Security: max-age=31536000; includeSubDomains`. - Every request checks the token, then that its account is still an admin of the project. An account that is no longer an admin gets 403 at once, whatever the token's expiry. When that can't be read, the answer is 503: try again. - Tools act on the project the connection was granted for: - `get_project`; - `get_settings`, `set_setting`, `set_setting_value`; - `list_members`, `invite_member`; - `list_apps` (without the apps' secrets), `create_app`; - `get_signals`. - Each tool runs the same service as the matching API route, with the same rules. A refused call answers a tool error carrying the route's status and error body. - Limits: - Each admin may send 300 messages a minute. Over that, the answer is 429 with `Retry-After`. - Each tool allows 60 calls a minute per admin; `create_app` and `invite_member` allow 10. Over that, the tool error has status 429 and `retryAfterSec`. - Tool errors carry the route's status and body for a refusal (4xx). A failure (5xx) is logged and answered without its detail. - MCP calls are not API usage: like the console's own calls, they are left out of statistics and the plan's monthly request cap. - Access tokens last an hour. Refresh tokens last 30 days, and each one works once: a refresh answers a new pair. A repeat within 30 seconds, such as parallel refreshes, gets a pair of its own. A refresh token used again later ends the connection, and so does revoking either token. A connection ends 90 days after its consent, however often it refreshes: connect again. ## Example Add it to Claude Code, which signs in through the browser on first use: ```bash claude mcp add --transport http ovok https://api.sandbox.ovok.com/mcp ```