Skip to main content
wondeya exposes a Model Context Protocol (MCP) server so an AI agent can build and run a page without a browser: create it, teach it, restyle it, publish it, and check what it would answer. It is the same engine the console drives: every tool runs the exact command or query the console’s own API runs, so the two surfaces cannot grow two behaviours.
Authentication is OAuth 2.1. You connect by signing in to wondeya in your browser and approving a consent screen; there is no key to create or paste. That is what lets browser assistants (Claude, ChatGPT) connect, not only coding agents. tools/list on a live connection is always the authoritative answer about what the server offers.

The endpoint

  • Transport: Streamable HTTP.
  • Server name: wondeya.
  • Stateless by design. GET and DELETE answer 405: there is no server-initiated stream and no session to terminate, and advertising either would be advertising a capability that does not exist.

Authentication

You sign in; you never paste a credential. The first time a client reaches the endpoint it is refused with a 401 whose WWW-Authenticate header points at wondeya’s discovery metadata. From there the client runs the standard OAuth 2.1 handshake on its own: it registers itself, opens your browser to wondeya, and, once you have signed in and approved, receives a short-lived access token it sends as a bearer token on every call. What you see is one screen: a consent screen naming the client asking to connect, the workspace the connection will be bound to, you, and the scopes it is asking for. Approve it and the client is connected; the token never touches your disk in plain sight and expires on its own. Under the hood the chain is the standard every MCP client expects:
  • Resource metadata (RFC 9728) at /.well-known/oauth-protected-resource, served on both the bare path and the /mcp-suffixed variant, because clients probe different ones.
  • Authorization-server metadata (RFC 8414) advertising the authorization, token and registration endpoints and code_challenge_methods_supported: ["S256"].
  • Dynamic client registration (RFC 7591), so a client no one pre-configured can register itself.
  • PKCE (S256) on every authorization, and audience binding (RFC 8707): the token is issued for this MCP endpoint and no other, and the server refuses a token minted for anything else.
wondeya is the resource server; the authorization server, sign-in and consent are hosted by wondeya’s identity provider on a wondeya domain. There is no anonymous access, and every authentication failure answers the same generic 401 with the code wondeya.oauth.unauthorized, so a scanner cannot tell one cause from another.

One connection, one workspace

Approving the consent binds the connection to one workspace (the one active in your session when you approve), and nothing can move it. There is no parameter for choosing a workspace and no tool that can reach another one: every id you pass is resolved inside the bound workspace, and a page id copied from somewhere else simply does not exist as far as your connection is concerned. To connect an agent to a different workspace, switch workspace in the console first, then start the connection: the consent screen always shows which workspace you are about to grant, so there is no silent wrong-workspace grant. This is the same isolation the rest of the product runs on: the same four layers, not a second implementation for agents. Security and privacy describes them.

Scopes gate tools

The connection carries the scopes you approved, and every tool checks its scope on every call: The consent screen may also offer chat:write: it gates the developer REST API’s generative chat endpoint and unlocks no MCP tool, so leave it ungranted for an MCP connection. Calling a tool your connection lacks the scope for answers with the code wondeya.oauth.insufficient_scope; the tool is not run. Grant the narrowest set that does the job: a connection with only landings:read and knowledge:read can audit a workspace and cannot change a thing. Your role caps what you can grant. An owner or admin can grant read and write; a member can grant read only, and the consent screen dims the scopes your role cannot give. Authorization stays wondeya’s own: the consent gate decides only what a connection may ask for, and every tool is still checked against the scopes actually granted.

Managing and revoking connections

A connection is listed in the console under Configuration → Connected apps, with the scopes it holds, and you revoke it there. Revocation takes effect on the next request: the client’s token stops working and it must sign in again to reconnect.

What tool results look like

A successful call returns the same JSON the API returns, as pretty-printed text. A failure is not a protocol error: it is a normal MCP result marked isError, carrying the same RFC 9457 problem document the HTTP API returns: code, title, detail, status, requestId, and instance naming the tool that failed. That is deliberate on two counts: a transport-level error never reaches the model, and wondeya.project.slug_taken has to mean one thing in the product rather than one thing per surface. An agent should branch on code, never on detail. The error reference lists them.

What the tools cover today

Agents and their widget site keys, sites and pages (including publishing), knowledge, images, the brand and the theme, and workspace usage. The tool reference documents each one. Not covered yet, and worth knowing before you plan around it:
  • Members and invitations. Team management stays in the console.
  • API keys and connections. A connection cannot mint or manage credentials, its own included; creating API keys and revoking connections stay in the console, where a human approves them. Widget site keys are the exception: a site key identifies an agent and authorizes nothing, so creating, listing and rotating them is covered.
  • Custom domains. Connecting and verifying one is a console job (and an HTTP one); there is no MCP tool for it.

Two rules an agent gets wrong without being told

The server states both in its own instructions, and they are worth repeating here because they are the two things that surprise people:
  1. Creating a page does not publish it. A page is born a draft and answers nobody. publish_page is the single act that opens it to the world.
  2. Ingestion is asynchronous. Adding a document or a URL answers immediately with the source in pending. Poll list_knowledge_sources until it is ready before assuming the page can answer from it.