# MCP documentation This page documents the current read-only Rewrites Studio MCP connector and its two tools. Rewrites Studio is a supportive writing workspace for memoirs, stories and professional writing. The Rewrites Studio MCP connector gives an AI assistant you choose **read-only** access to your own saved drafts, so it can read your work and help you decide what to do next. Example request: "Help me finish my autobiography: read my saved Rewrites draft and suggest what to work on next." The connector can find and read drafts only. It cannot create, edit, save or publish writing. Any new writing an assistant suggests stays in that assistant until you add it to Rewrites Studio yourself. ## Overview - Endpoint: `https://rewrites.studio/api/mcp` - Transport: MCP Streamable HTTP. Send requests with `POST`. The server does not keep sessions and returns JSON responses. - Authorization: OAuth 2.1 authorization code with PKCE (`S256`), for public clients (`token_endpoint_auth_method: none`). - Scope: `drafts:read` - Account: a Rewrites Studio account with a verified email address. You approve each connection on a consent screen. - API keys: not supported. The older pilot keys have been retired. - Credits: using the connector does not use Rewrites credits. ## Data access Available: projects that you own, that are saved and that are not archived. Tools return titles, update times, a link to open the project, and the saved text as plain text. Not available: unsaved changes, chat history, memory files, projects where you are only a collaborator, anonymous projects, and anything from another account. If a project ID is not available to you, the connector responds as if it does not exist. ## Authorization Use an MCP client SDK with OAuth support. It should discover the metadata, create its own PKCE verifier and `state` value, and handle the redirect. Never reuse values from these examples. ### Discovery - Protected resource metadata: `GET https://rewrites.studio/.well-known/oauth-protected-resource/api/mcp` - Authorization server metadata: `GET https://rewrites.studio/.well-known/oauth-authorization-server`. The path `/.well-known/oauth-authorization-server/api` redirects here. A request to `/api/mcp` without a valid token returns HTTP 401 with this header: ``` WWW-Authenticate: Bearer resource_metadata="https://rewrites.studio/.well-known/oauth-protected-resource/api/mcp", scope="drafts:read" ``` ### Client registration Dynamic client registration is available but restricted. Every callback URL must use an origin that Rewrites Studio has reviewed and approved. It must also use `https`, or `http` on `127.0.0.1` or `[::1]` for local loopback callbacks. Callback URLs cannot contain a fragment or user credentials. To ask us to review your callback origin, email support@rewrites.studio. We approve exact origins only. We do not accept wildcards or broad domains. ``` POST https://rewrites.studio/api/oauth/register Content-Type: application/json { "client_name": "Example Writing Assistant", "redirect_uris": ["https://assistant.example.com/oauth/callback"], "token_endpoint_auth_method": "none", "grant_types": ["authorization_code"], "response_types": ["code"] } ``` You can register between one and five `redirect_uris`. A successful request returns HTTP 201 with a `client_id` in the form `rw_client_...`. Invalid metadata, including any callback that has not been approved, returns HTTP 400 `invalid_client_metadata`. ### Authorization request ``` GET https://rewrites.studio/api/oauth/authorize ?response_type=code &client_id=rw_client_EXAMPLE &redirect_uri=https://assistant.example.com/oauth/callback &scope=drafts:read &state=CLIENT_GENERATED_STATE &code_challenge=CLIENT_GENERATED_S256_CHALLENGE &code_challenge_method=S256 &resource=https://rewrites.studio/api/mcp ``` `redirect_uri` must exactly match a registered URI. If it does not, the server shows an error and does not redirect. `state` is required, up to 512 characters. `resource` is optional, but if you send it, it must be the endpoint above. The user signs in if needed, then sees which app is asking and the origin of its callback, and chooses to allow or deny access. Approval returns `code` and `state` to the callback. Denial returns `error=access_denied`. Authorization codes expire after five minutes and work only once. ### Token request ``` POST https://rewrites.studio/api/oauth/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&client_id=rw_client_EXAMPLE &redirect_uri=https://assistant.example.com/oauth/callback &code=AUTHORIZATION_CODE&code_verifier=CLIENT_PKCE_VERIFIER ``` A successful response looks like this: ```json { "access_token": "rw_oauth_...", "token_type": "Bearer", "expires_in": 3600, "scope": "drafts:read" } ``` Access tokens last one hour. Refresh tokens are not issued, so when a token expires, the user reconnects. Send the token in each request as `Authorization: Bearer `. ## Tools Both tools are read-only (`readOnlyHint: true`). Call them with the MCP JSON-RPC method `tools/call`. Results arrive as one `text` content block whose text is a JSON string. Parse it with `JSON.parse(result.content[0].text)`. The tools do not return `structuredContent` or an output schema. In the examples below, all IDs and content are made up. ### find_my_projects Finds your saved, non-archived projects by title, most recently updated first. Input: - `query` (string, optional, maximum 100 characters, default `""`): matches anywhere in the title, ignoring case - `limit` (integer 1-20, default 10) Request: ```json { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "find_my_projects", "arguments": { "query": "grandmother", "limit": 5 } } } ``` Response: ```json { "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "{\"projects\":[{\"projectId\":\"00000000-0000-4000-8000-000000000001\", ...}]}" } ] } } ``` Parsed `text`: ```json { "projects": [ { "projectId": "00000000-0000-4000-8000-000000000001", "title": "Example: Summers at Grandmother's House", "updatedAt": "2026-01-15T10:30:00.000Z", "openUrl": "https://rewrites.studio/editor/00000000-0000-4000-8000-000000000001" } ] } ``` ### read_my_draft Reads a saved draft as plain text, in pages. Input: - `projectId` (UUID, required): a project ID returned by `find_my_projects` - `page` (integer 0-499, default 0) - `expectedRevision` (64 lowercase hexadecimal characters): required for every page after page 0. Use the `revision` value returned with page 0. Request for a later page: ```json { "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "read_my_draft", "arguments": { "projectId": "00000000-0000-4000-8000-000000000001", "page": 1, "expectedRevision": "0000000000000000000000000000000000000000000000000000000000000000" } } } ``` Example parsed result for page 0. The `text` value is abbreviated here; actual pages contain up to 20,000 UTF-16 code units, without splitting a surrogate pair. ```json { "projectId": "00000000-0000-4000-8000-000000000001", "title": "Example: Summers at Grandmother's House", "text": "Example text. The kitchen always smelled of... [abbreviated excerpt]", "page": 0, "nextPage": 1, "truncated": true, "revision": "0000000000000000000000000000000000000000000000000000000000000000", "updatedAt": "2026-01-15T10:30:00.000Z", "openUrl": "https://rewrites.studio/editor/00000000-0000-4000-8000-000000000001" } ``` ### Pagination Each page holds up to 20,000 UTF-16 code units. A page never splits a surrogate pair. To read a long draft, start at page 0, then keep requesting `nextPage` with the same `expectedRevision` until `nextPage` is `null`. Only pages 0-499 can be read. If a draft is longer than that, `truncated` stays `true` on page 499. If the draft changes while you are reading it, the tool returns an error and you must start again at page 0. ## Errors and limits - Tool errors are returned as a normal JSON-RPC result with `isError: true` and one of these messages: `Draft not found or not accessible.`, `Draft revision changed. Restart at page 0.`, or `expectedRevision is required for pages after page 0. Read page 0 first.` Invalid inputs fail schema validation. - HTTP 401 `invalid_token`: the token is missing, expired or revoked, the account is deleted, or the email address is not verified. Connect again. - HTTP 405: any method other than `POST`, including opening the endpoint in a browser. This is expected. - HTTP 429: rate limit reached. Wait for the time given in the `Retry-After` and `RateLimit` headers before trying again. - Rate limits per IP address: 120 requests per minute to `/api/mcp`, and 30 requests per minute shared across the OAuth registration, authorization and token endpoints. - OAuth errors: `invalid_request` (sent to the callback), `invalid_grant` (from the token endpoint), `access_denied` (the user declined). ## Revoking access In Rewrites Studio, go to **Account**, then **Read-only MCP connections**, and remove the connection. Its tokens stop working right away. Any content the assistant already read stays in that external client, under that client's own terms. ## Using with Meta AI Muse Meta's [official help page](https://www.meta.com/help/artificial-intelligence/1687253048996149/) explains that you add a custom connector by asking Muse to create one. Give Muse the endpoint `https://rewrites.studio/api/mcp`. Rewrites Studio is not reviewed or endorsed by Meta, and this connection is subject to the callback approval described above. ## Support and policies - Support: support@rewrites.studio or [rewrites.studio/support](https://rewrites.studio/support) - [Privacy Policy](https://rewrites.studio/legal#privacy) - [Terms of Service](https://rewrites.studio/legal#terms)