Paperpile MCP server
Paperpile runs a Model Context Protocol server on its own host, so an MCP client — an AI assistant or agent — can work with your library directly. The endpoint is the host itself:
https://stage-mcp.paperpile.com
The transport is Streamable HTTP, and every request is independent — the endpoint keeps no session state.
Connect a client (Collapsed)
Any client needs two things: that URL, and a token. Clients that support OAuth can discover the authorization server
themselves; the rest take an API key as a Bearer header. Use a read_write token if the assistant should be able to
save or edit references — a read-only token can still browse, but every writing tool will fail.
Claude Code
# OAuth — opens a browser to authorize
claude mcp add --transport http paperpile https://stage-mcp.paperpile.com
claude mcp login paperpile
# …or authenticate with an API key instead
claude mcp add --transport http paperpile https://stage-mcp.paperpile.com \
--header "Authorization: Bearer YOUR_API_KEY"
The server is added to the current project only. Pass --scope user to make it available everywhere. On a headless or
SSH session, claude mcp login paperpile --no-browser prints the authorization URL instead of opening a browser. Verify
with claude mcp list, and remove it with claude mcp remove paperpile.
Claude Desktop
Remote servers are added through Connectors, not claude_desktop_config.json — that file is for local stdio servers.
- Open Settings (
Ctrl+,on desktop,⌘⇧,in the browser) and choose Connectors. - Click Add, then Add custom connector.
- Paste
https://stage-mcp.paperpile.comand click Add. - Complete the authentication prompt.
Once connected, you can enable or disable individual tools from the connector's settings.
Codex CLI
Remote servers are configured in ~/.codex/config.toml, or in .codex/config.toml to scope them to one project.
codex mcp add only handles stdio servers, so add the entry by hand:
[mcp_servers.paperpile]
url = "https://stage-mcp.paperpile.com"
bearer_token_env_var = "PAPERPILE_API_KEY"
bearer_token_env_var names the environment variable holding your token; Codex sends its value as the Authorization
bearer token. Omit it to use OAuth instead, which is the default. http_headers sets static headers if you need them.
Antigravity
Remote servers are configured in ~/.gemini/config/mcp_config.json, or in .agents/mcp_config.json to scope them to
one workspace:
{
"mcpServers": {
"paperpile": {
"serverUrl": "https://stage-mcp.paperpile.com",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
To use OAuth instead, drop the headers block entirely — Paperpile's authorization server supports dynamic client
registration, which Antigravity handles on its own. Then open settings (Cmd/Ctrl+,), go to the Customizations tab,
click Authenticate next to the server, and paste the authorization code back into the settings panel.
Any other client
Point it at https://stage-mcp.paperpile.com as a Streamable HTTP server and give it either an API key as Authorization: Bearer …,
or let it run the OAuth flow — it can discover the authorization server from /.well-known/oauth-protected-resource.
Authentication (Collapsed)
Send Authorization: Bearer <token>, exactly as for the REST API. Both token types work: an API key generated in your
Paperpile settings, or an OAuth 2.0 access token. See Authentication in the API
reference for how to obtain either.
The endpoint itself only requires the read scope, but any tool that modifies your library fails on a read-only token.
Tools (Collapsed)
tools/list is the authoritative source for what the server currently exposes. At the time of writing there are
thirteen tools:
| Area | Tools |
|---|---|
| Read your library | search_library, get_references_from_library, get_collections_from_library, get_libraries, get_text_content |
| Modify your library | update_references, update_collections, save_to_library, highlight_text |
| Search external catalogs | find_papers, lookup_papers, get_inbound_cites, get_outbound_references |
Library search output
search_library accepts output_format: MARKDOWN (default), MINIMAL, or JSON.
Markdown groups matching passages under reference cards with citation metadata and file IDs.
Minimal emits one line per match with its citekey, page, offsets and excerpt, without file IDs.
JSON returns { query, resultCount, referenceCount, data: [{ reference, matches }], total? };
batched queries retain the { results: [...] } wrapper in input order. Each match preserves its
resultType, highlighted metadata or snippet, and any file, page, character-offset and annotation identifiers.
Reference summaries reuse the SDK's published date and files attachment objects. Markdown cards
share the reference-list renderer: a ### Citekey - Title heading, Markdown website and main-PDF
viewer links, and additional attachments as nested bullets under Files:. A lone main PDF appears
only in the viewer link. Markdown responses end with guidance for presenting Paperpile-style references.
All citation summaries use surname plus initials, retaining the first three and last two authors
when there are more than five.
resultCount counts returned matches, referenceCount counts distinct references on this page, and
total counts matching references across all pages when requested. count: "only" returns a total
without retrieving reference metadata or passages. limit and offset still page references and
only apply to a single query. The REST and SDK search response formats are unchanged.
Sessions (Collapsed)
There are none: the endpoint is stateless. Every POST is a complete, independent exchange — no session is created,
no mcp-session-id header is ever issued, and one sent by a client is ignored. GET and DELETE return 405.
Clients that follow the MCP session handshake work unchanged; the server simply treats each message on its own.