Skip to main content
Version: Next

MCP

OpenReader is a remote MCP server at BASE_URL/api/mcp. It lets an assistant search a user's library, add documents and make audiobooks, as that user. Clients sign in with OAuth, so there is no package to install and no API key to copy.

Connect a client​

Add https://reader.example/api/mcp, with your own BASE_URL, as a remote MCP server or connector. The client opens a browser, you sign in, and you approve what it can do. For example, in Claude Code:

claude mcp add --transport http openreader https://reader.example/api/mcp

Clients configured with a JSON file usually take the same address, though field names vary between clients:

{
"mcpServers": {
"openreader": { "url": "https://reader.example/api/mcp" }
}
}

Hosted connectors connect from the vendor's servers, so they need an instance with a public HTTPS address. A client on your own computer can reach a local instance.

To check an instance by hand, run MCP Inspector and connect to the URL with the streamable HTTP transport:

npx @modelcontextprotocol/inspector

Administrators can stop new clients from connecting with Open OAuth client registration. Clients that are already connected keep working.

Tools​

ToolScopeWhat it does
list_documentsdocuments:readLists or searches the library, a page at a time
add_documentdocuments:writeAdds a public web page, or up to 2 MB of text
list_providersdocuments:readLists the speech providers and models the user can use
list_voicesdocuments:readLists voices for one provider and model, including the user's cloned voices
create_audiobookaudio:generateStarts an audiobook of a document or one chapter
get_audiobookdocuments:readReports an audiobook's status and progress

create_audiobook can use any enabled provider, model and voice. If it names none, it uses the user's saved settings. A model outside what the instance allows falls back to the provider's default, and the result reports the provider, model and voice it used.

create_audiobook returns at once with a status, and sending the same request again returns the same audiobook. Use get_audiobook to check on it.

Results include a webUrl that opens the document in OpenReader. Once an audiobook is ready, get_audiobook also returns a webDownloadUrl, a page that starts the download. Both links need the user to be signed in to the account that owns the document, in the browser that opens them. Without access, the page offers to sign in or switch account and then returns to the link. Tools do not return audio files, API file addresses or storage links. A tool that fails returns an error result with a code, a message and, when it applies, retryAfterMs. A call without the scope it needs gets an HTTP 403 insufficient_scope challenge, so the client can ask for more access.

See Connected Apps for what the approval screen shows and how to disconnect.

MCP shares the user's compute limits and storage with the web app. It has no request limit of its own.

Staying connected​

Access tokens last 15 minutes. A client that asks for offline_access refreshes them without another sign-in. You need to approve the client again when:

  • it has not refreshed its token for 30 days, or it never asked for offline_access;
  • you disconnect it in Settings → Account → Connected apps;
  • it asks for a scope you did not approve;
  • the instance's BASE_URL changes, or AUTH_SECRET is replaced.

Some clients also end connections on their own schedule. Reconnect from the client if that happens; your library is not affected.

Security​

  • Only a bearer token issued for BASE_URL/api/mcp works. Browser sessions and tokens for BASE_URL/api/v1 are rejected, and the reverse is also true.
  • The endpoint sends no CORS headers and rejects a browser Origin the instance does not trust.
  • Provider credentials and worker tokens never reach a client.