MCP server
Connect Claude, ChatGPT, Cursor, or any MCP client to Openhandle with OAuth and call every endpoint as a tool.
Openhandle runs a remote MCP server over Streamable HTTP. Every public API endpoint is one tool. The tool names, inputs, and responses match the REST API.
https://api.openhandle.dev/mcpConnect a client
Add the URL to your MCP client. The client discovers the OAuth settings, opens Openhandle in your browser, and asks you to approve the connection. You pick the workspace environment on that screen:
- Test answers every tool with synthetic data at $0.000 actual charge.
- Live uses real public data and normal billing.
Both need a verified workspace owner email.
Each connection gets its own usage identity, named after the client, for
example Claude (MCP). Its usage and request history are tracked like any API
key, but it does not appear under API keys.
Manage connections under Settings → MCP server in the dashboard. Set a monthly budget per connection there. Disconnect a client to revoke its access and every token at once.
Claude Code plugin
The Openhandle plugin for Claude Code adds the server, the account tools, and two skills that teach Claude how to use them. Run these commands in Claude Code:
/plugin marketplace add openhandlehq/openhandle-claude
/plugin install openhandle@openhandleThen type /mcp, pick openhandle, and approve in the browser. The plugin
requests the mcp read:account scope.
OAuth details
The server follows the MCP authorization specification.
| Document | URL |
|---|---|
| Protected resource metadata | https://api.openhandle.dev/.well-known/oauth-protected-resource/mcp |
| Authorization server metadata | https://api.openhandle.dev/.well-known/oauth-authorization-server |
| Dynamic client registration | https://api.openhandle.dev/oauth/register |
| Authorization | https://api.openhandle.dev/oauth/authorize |
| Token | https://api.openhandle.dev/oauth/token |
| Revocation | https://api.openhandle.dev/oauth/revoke |
- Grant types:
authorization_codewith PKCE (S256), andrefresh_token. - Scopes:
read:instagram,read:tiktok,read:twitter,read:reddit, andread:account. mcpgrants every platform tool. It does not grantread:account.- Default scope:
mcp read:accountwhen a client omits the scope. The401challenge names this scope too. - Public clients register with
token_endpoint_auth_method: none. Confidential clients receive a client secret. - Access tokens live for one hour. Refresh tokens rotate on every use and live for 30 days.
- Send
resource=https://api.openhandle.dev/mcpwhen your client supports resource indicators.
Browser authorization flow
The authorization endpoint validates the OAuth parameters and stores a short-lived
authorization request. It then redirects the browser to the dashboard consent page
with an opaque request identifier. The dashboard loads the stored request from the
API and shows the client, requested access, environment, and spend-cap options.
Production sessions use a cookie shared across the api.openhandle.dev and
app.openhandle.dev subdomains. An unauthenticated user signs in through the
dashboard and then returns to the same consent request. Approval sends the browser
to the client's registered redirect URI with the authorization code and original
state.
API key instead of OAuth
Scripts and CI jobs can skip the browser flow. Send an API key as the bearer token:
Authorization: Bearer $OPENHANDLE_TEST_KEYThe key prefix selects the environment. There is no environment argument, header, or setting.
Tools
find_test_dataandget_test_datafind stable synthetic inputs. They are unmetered.- Endpoint tools such as
instagram_get_profilecall the public API. They are metered exactly like REST calls and appear in request history with channelmcp. - Every result carries metadata:
environment,requestId,actualCharge,liveEquivalentPrice, anddatasetVersion.
Account tools
Account tools read your own workspace. They are unmetered and need the
read:account scope.
| Tool | Returns |
|---|---|
account_get_balance | Prepaid balance, billing state, auto top-up trigger, and free requests left |
account_get_usage | Requests, outcomes, and spend for a date range, compared with the previous range |
account_list_requests | Request history, newest first, with filters for status, platform, and channel |
account_get_request | One request by its requestId |
account_list_api_keys | API keys with status, last use, and monthly caps. Secrets are never returned |
Usage, requests, and keys cover the credential's environment only. The balance is shared by Test and Live. Each call also checks that the user who approved the connection can still view that data in the workspace. No tool changes the workspace.
Read Test with MCP for the agent sequence in the test environment.
Machine-readable discovery and permissions
Use https://api.openhandle.dev/mcp as the server endpoint. The MCP setup guide explains how to connect each client.
Protected resource metadata
publishes mcp, read:instagram, read:tiktok, read:twitter, read:reddit, and
read:account in scopes_supported.
Request only the platforms your agent needs, for example scope=read:instagram.
Combine scopes with spaces to allow multiple platforms. The consent page shows
these permissions before approval. Each endpoint tool also declares its
requiredScope in _meta.
| Scope | Allowed tools |
|---|---|
read:instagram | Instagram tools |
read:tiktok | TikTok tools |
read:twitter | X (Twitter) tools |
read:reddit | Reddit tools |
read:account | Account tools |
mcp | All platform tools. Excludes account tools |
Discovery tools and synthetic catalog resources remain available to every connection. No scope grants dashboard administration or social account writes. API keys retain access to all tools. Use OAuth for platform restrictions.
A call outside the token's permissions returns HTTP 403 before metering.
Its WWW-Authenticate challenge declares error="insufficient_scope", the
required scope, and the protected resource metadata URL.
Authorize the additional scope in the browser before retrying.
Refresh requests can narrow access-token permissions. Rotated refresh tokens retain their original permissions, as required by OAuth. Reauthorizing a connection never expands permissions on an existing token.
The Openhandle MCP manifest uses the official MCP Registry
server.json format and declares the actual Streamable HTTP endpoint.
GET /mcp returns this JSON description without special request headers.
The same manifest remains available at /mcp.json.
JSON-RPC POST requests to the website URL redirect to the API endpoint;
configure the API URL directly to avoid redirects.
An unauthenticated request returns HTTP 401 and a WWW-Authenticate header
pointing to the protected resource metadata. This is expected. Verify a server
with an authenticated JSON-RPC initialize request using Streamable HTTP,
not by expecting a public JSON document from an unauthenticated website GET.