v0.1.0
OpenAPI 3.1.0

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.

  1. Open Settings (Ctrl+, on desktop, ⌘⇧, in the browser) and choose Connectors.
  2. Click Add, then Add custom connector.
  3. Paste https://stage-mcp.paperpile.com and click Add.
  4. 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.