PinSuite MCP Server
The PinSuite Model Context Protocol server lets any MCP-compatible AI client act on a user's PinSuite library — saving pins/boards/profiles, browsing the library, and queuing exports — over a single HTTPS endpoint with OAuth 2.1.
Endpoint
One route. Streamable HTTP transport (MCP spec rev 2025-03-26).
POST https://pinsuite.app/mcp
Content-Type: application/json
Accept: application/json (or text/event-stream for SSE responses)
Authorization: Bearer <access_token_or_pat>
Body is one JSON-RPC 2.0 request, notification, or batch. The server replies
with either a JSON object (single response) or a JSON array (batch). When
Accept: text/event-stream is present the same payload is sent as
one SSE frame; the connection then closes.
Authentication
OAuth 2.1 (recommended)
Standard OAuth 2.1 with PKCE (S256 only) and RFC 7591 Dynamic Client
Registration. Discovery metadata is published at
/.well-known/oauth-authorization-server.
| Endpoint | Purpose |
|---|---|
GET /.well-known/oauth-authorization-server | RFC 8414 metadata. |
GET /.well-known/oauth-protected-resource | RFC 9728 resource metadata — Claude.ai uses this for auto-discovery. |
POST /oauth/register | Dynamic Client Registration (rate-limited 5/hr/IP). |
GET /oauth/authorize | Authorization request — requires PKCE. |
POST /oauth/token | Exchange code or refresh token. |
POST /oauth/revoke | RFC 7009 revoke a refresh token. |
POST /oauth/introspect | RFC 7662 token introspection. |
GET /oauth/jwks | Public signing keys. |
Access tokens are RS256-signed JWTs (15-minute lifetime). Refresh tokens are 90-day opaque tokens with family-rotation: reuse of a revoked refresh token cascade-revokes the entire family.
Personal Access Tokens (PATs)
For CLI clients without an OAuth flow, users create long-lived PATs at
/account/integrations. Use the plaintext
pst_... token in the Authorization header.
Scopes
| Scope | Grants |
|---|---|
library:read | list_library, get_collection, get_usage |
library:write | save_url, preview_url, confirm_save |
library:export | export_collection, get_export_status |
profile:read | who_am_i, get_subscription |
Tool catalog
save_url
Save a Pinterest pin/board/section/profile or Instagram post/profile. Requires a paid plan.
{ "url": "https://pinterest.com/user/my-board/", "kind": "auto", "overwrite": false }
preview_url
Preview the media at a URL without saving. Returns candidate items by index.
{ "url": "https://pinterest.com/pin/123" }
confirm_save
Save selected items from a previous preview. Optionally specify item indexes.
{ "url": "...", "items": [0, 2, 5], "title": "My collection", "visibility": "private" }
list_library
{ "limit": 20, "offset": 0, "search": "marble", "type": "collections", "sort": "newest" }
get_collection
{ "collection_id": "...", "limit": 50, "offset": 0 }
export_collection
{ "collection_id": "...", "format": "zip" } # or csv, html, json, pdf
get_export_status
{ "collection_id": "...", "format": "zip" }
get_usage / get_subscription / who_am_i
No arguments; return current account state.
Errors
Auth, scope, and quota failures come back as JSON-RPC errors. User-actionable
tool failures (e.g. unsupported URL) come back as a tool result with
isError: true so the assistant can summarize them to the user.
| Code | Meaning |
|---|---|
| -32001 | unauthorized — invalid or missing bearer token |
| -32002 | payment_required — paid plan needed |
| -32003 | forbidden_scope — token lacks the required scope |
| -32004 | not_found |
| -32005 | rate_limited |
Rate limits
- 60 tool calls / minute per token.
- save_url: 60 / hour per user (shared with the browser extension).
- preview_url: 30 / minute per user.
- POST /oauth/register: 5 / hour per IP.
Examples
Initialize + list tools
curl -X POST https://pinsuite.app/mcp \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer pst_...' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26"}}'
Save a board
curl -X POST https://pinsuite.app/mcp \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer pst_...' \
-d '{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "save_url",
"arguments": { "url": "https://pinterest.com/user/board/" }
}
}'