upAPI Docs

Connect an MCP client

Working configuration for Claude Code, Claude Desktop, Cursor and VS Code.

View as Markdown

Pick a transport, then copy the block for your client. Both transports expose tools with the same schemas and draw on the same monthly pool of weighted units. They differ in how a call is authenticated, and — following from that — in what the per-minute burst limit is counted against: the hosted server meters per organization, the local server per API key. The hosted server serves every public operation; the local server catches up in the next @upapi/mcp release (0.2.0 serves 63 and still withholds Social Media and Utility in directory mode).

See MCP server for what the tools look like once connected.

To let a coding agent do all of this itself, see Agent setup.

TransportHostedLocal
Endpointhttps://app.upapi.io/api/mcpnpx -y @upapi/mcp (stdio)
Authsign in to upAPI in a browserUPAPI_API_KEY in the config
Runson upAPIon your machine
Best fordesktop clients and IDEsscripts, CI, self-hosted agents

Prefer the hosted server. It authorizes over OAuth 2.1 with PKCE against the same accounts system as the dashboard, so there is no key to paste into a file on disk and no key to rotate when a laptop is lost.

The hosted server needs a full account

A guest session cannot connect: the endpoint answers 401 GUEST_FORBIDDEN. Guest identities are temporary and get reaped, which would break a long-lived integration in a way you could not diagnose from the client. Convert the guest account first — the local server has no such restriction, since it authenticates with an API key.

For the local server, create a key at Dashboard → API keys first. It reads two environment variables:

VariableRequiredValue
UPAPI_API_KEYYesan upapi_ key
UPAPI_BASE_URLNogateway origin, defaults to https://api.upapi.io
UPAPI_TOOL_MODENocompact (default), directory, claude or full — see below

Which tools you get

Within a transport, every mode serves the same operations. What changes between modes is how many of them are advertised in tools/list — a context-budget and presentation choice, never an access one. An operation a mode does not list is still callable by name.

ModeAdvertisesUse it when
compactsearch_ops + call_op + three always-on operationsa long chat that re-sends its tool table every turn
directory11 named flagship tools, read tools and write tools separateda desktop client, or anywhere a human reads the tool list
claude8 named tools upAPI computes itself, reads and writes splitthe Claude connector listing
fullone tool per public operationa fixed workflow that wants every schema present without a lookup

Every tool in every mode carries the four MCP behavioural hints — readOnlyHint, destructiveHint, idempotentHint and openWorldHint — so a client can decide what may run unattended without inferring it from a name.

The hosted server picks the mode from the URL and defaults to compact:

https://app.upapi.io/api/mcp                    # compact
https://app.upapi.io/api/mcp?tools=directory    # named flagship tools
https://app.upapi.io/api/mcp?tools=claude       # named tools upAPI computes itself
https://app.upapi.io/api/mcp?tools=full         # one tool per operation

The local server reads UPAPI_TOOL_MODE and defaults to compact, the same shape the hosted endpoint defaults to. full (one tool per operation, this server's original default) remains available as a rollback for a client already configured against it. An unrecognized value falls back to the default rather than refusing to start.

Claude Code

Hosted
claude mcp add --transport http upapi https://app.upapi.io/api/mcp

Claude Code opens a browser to authorize the connection on first use.

Local
claude mcp add upapi --env UPAPI_API_KEY=upapi_YOUR_KEY -- npx -y @upapi/mcp

Claude Desktop

The shortest path is the desktop extension. Download upapi.mcpb from the latest release, double-click it, and paste your API key when Claude Desktop asks: the key is held as a sensitive setting rather than written into a config file on disk, and the extension defaults to the directory tool table.

For the hosted server, add it through the app rather than the config file: Settings → Connectors → Add → Add custom connector, then enter https://app.upapi.io/api/mcp and click Add. Claude connects from Anthropic's infrastructure rather than from your machine, which is fine here — the endpoint is public.

The local server goes in claude_desktop_config.json:

claude_desktop_config.json
{
  "mcpServers": {
    "upapi": {
      "command": "npx",
      "args": ["-y", "@upapi/mcp"],
      "env": {
        "UPAPI_API_KEY": "upapi_YOUR_KEY"
      }
    }
  }
}

Restart Claude Desktop; the operations appear in its tool list.

Cursor

One click installs the hosted server: Add upAPI to Cursor. The link only opens Cursor's install dialog — nothing is written until you confirm there.

Both forms also go in .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):

.cursor/mcp.json — hosted
{
  "mcpServers": {
    "upapi": {
      "url": "https://app.upapi.io/api/mcp"
    }
  }
}
.cursor/mcp.json — local
{
  "mcpServers": {
    "upapi": {
      "command": "npx",
      "args": ["-y", "@upapi/mcp"],
      "env": {
        "UPAPI_API_KEY": "upapi_YOUR_KEY"
      }
    }
  }
}

VS Code

VS Code uses servers rather than mcpServers, and wants an explicit type. Put this in .vscode/mcp.json for one workspace, or in your user profile's mcp.json for all of them:

.vscode/mcp.json — hosted
{
  "servers": {
    "upapi": {
      "type": "http",
      "url": "https://app.upapi.io/api/mcp"
    }
  }
}

For the local server, take the key from a prompted input rather than hardcoding it — .vscode/mcp.json is usually committed:

.vscode/mcp.json — local
{
  "inputs": [
    {
      "type": "promptString",
      "id": "upapi-key",
      "description": "upAPI API key",
      "password": true
    }
  ],
  "servers": {
    "upapi": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@upapi/mcp"],
      "env": {
        "UPAPI_API_KEY": "${input:upapi-key}"
      }
    }
  }
}

Other clients

Any client that can launch a stdio server takes the same command (npx -y @upapi/mcp) with UPAPI_API_KEY in its environment, and any client that speaks remote MCP takes the hosted URL. Nothing in either transport is client-specific.

Your key is a credential in a config file

Every UPAPI_API_KEY block above puts a live key in plain text on disk. Use a key created for this purpose so you can delete it without disturbing production, keep the file out of dotfile repositories, and prefer the hosted server or VS Code's inputs prompt where you can.