Skip to main content
Glama

Pinterest MCP

A read-only Model Context Protocol server that lets AI agents such as Claude read your own Pinterest boards and pins. You can turn a moodboard into usable design references inside an AI workflow.

It runs two ways from one shared codebase:

  • Hosted, as a Supabase Edge Function with its own OAuth 2.1 server. You add it as a custom connector in claude.ai (web, desktop or mobile).

  • Local, as a stdio server for Claude Code or Claude Desktop, with credentials in the macOS Keychain.

"Pull my Landing Pages board and design three directions from it." The agent reads the board, sees each pin's image, title, source link and your private notes, and works from your actual taste instead of generic defaults.

Why I built it

I use Claude as a creative director for web design work. My reference material lives on Pinterest, often on secret boards with notes on why I saved a pin. I had no clean way to get it to an agent, and copying screenshots by hand lost the context. This server closes that gap. It has four focused tools, uses OAuth, and never asks for write access.

Related MCP server: pinterest-mcp

Tools

Tool

What it does

list_boards

Lists your boards (public, protected and secret) with pin counts. Optional name filter.

get_board_pins

Returns pins from one board (by name, id or URL), optionally from one section: title, description, your note, alt text, source link and full-size image URL. Pages through up to 500 pins.

search_my_pins

Keyword search across your saved pins, like "japandi", "serif" or "pricing page".

view_pins

Returns the actual images (base64) for pins from a board or a search, so the model can see and critique the visual style, not just read URLs.

download_board

(Local only.) Saves a board's full-size images plus a pins.json manifest to a local folder, ready for moodboarding.

Board lookup is forgiving. "landing pages", landing-pages, a board id or a full pinterest.com/user/board/ URL all resolve to the same board. If a name is ambiguous, you get a clear error that lists the candidates.

Hosted version: how claude.ai connects

claude.ai can only talk to MCP servers on the internet, and it signs users in with OAuth. Pinterest's own OAuth doesn't support what MCP clients expect (discovery metadata, dynamic client registration, PKCE). So the Edge Function is its own authorization server and delegates the actual login to Pinterest:

claude.ai                       pinterest-mcp (Edge Function)              Pinterest
   │ POST /mcp (no token) ─────────▶ 401 + WWW-Authenticate: resource_metadata
   │ GET  /.well-known/oauth-protected-resource  ─▶ "my auth server is BASE"
   │ GET  BASE/.well-known/openid-configuration  ─▶ endpoints, S256 only
   │ POST /register (DCR) ─────────▶ client_id  (redirect URI must be allowlisted)
   │ GET  /authorize + PKCE ───────▶ 302 ─────────────────────────────────▶ user clicks Allow
   │                                 GET /callback ◀── code ────────────────┘
   │                                 swap code for Pinterest tokens, encrypt, store
   │ ◀── 302 redirect_uri?code=…  (our code, single-use, 5 min)
   │ POST /token + code_verifier ──▶ access (1 h) + refresh (30 d, rotating)
   │ POST /mcp  Bearer … ──────────▶ tools ── Pinterest API (refreshed as needed) ─▶
  • The client never sees Pinterest credentials. It holds only this server's tokens. The Pinterest tokens are AES-256-GCM encrypted at rest (HKDF-derived key).

  • Tokens are stored hashed (SHA-256). A database leak exposes no usable tokens.

  • PKCE S256 is mandatory. Codes are single-use and atomic (DELETE … RETURNING). Refresh tokens rotate, and a replayed token is rejected.

  • Open registration, closed redirects. Anyone can register a client, but only claude.ai/claude.com callbacks and loopback URLs are accepted. That closes the usual "malicious client phishes a consent" hole without a consent page.

  • Stateless MCP. Each request builds a fresh server over Streamable HTTP (JSON responses), so it scales to zero on serverless.

  • Path-based issuer. Supabase functions live under /functions/v1/<name>, so root /.well-known URLs aren't available. The server publishes openid-configuration under its own path, which MCP clients try as a discovery fallback.

The state lives in one table (pmcp_kv: namespace, key, JSON value, expiry), with RLS on and access for the service role only.

Design decisions

  • Read-only by design. It only requests boards:read, boards:read_secret, pins:read, pins:read_secret and user_accounts:read. The agent can't post, pin or delete anything.

  • No secrets on disk (local). The app credentials and OAuth tokens are stored in the macOS Keychain (service pinterest-mcp), not in .env files or config. Nothing secret can be committed by accident.

  • Automatic token refresh. The access token refreshes about an hour before it expires, so long agent sessions don't fail partway through.

  • OAuth with CSRF protection. auth.mjs runs a short-lived local callback server on port 8085 and checks a random state value before it swaps the code for a token.

  • Agent-friendly output. The raw Pinterest API responses are cut down to the fields an agent needs (slim()), which saves tokens. Errors come back as readable tool results the agent can act on, not crashes.

  • Small footprint. About 250 lines across three files. The only dependencies are @modelcontextprotocol/sdk and zod.

Code layout

src/
  pinterest.mjs        Pinterest API v5 client: paging, board lookup, token exchange (Node + Deno)
  tools.mjs            MCP tool definitions + zod schemas, shared by both transports
server.mjs             local stdio server (+ download_board)
keychain.mjs, auth.mjs local credential storage + one-time OAuth sign-in
supabase/
  functions/pinterest-mcp/
    index.ts           hosted server: OAuth 2.1 AS + Streamable HTTP MCP endpoint
    store.ts           KV store (Postgres in prod, in-memory for tests)
    crypto.ts          token hashing, PKCE, AES-GCM
    shared -> ../../../src
  migrations/          pmcp_kv table
test/
  e2e.test.mjs         full OAuth + MCP flow against a mock Pinterest
  live-probe.mjs       checks a deployed URL up to the Pinterest login

Tests

npm test starts the real Edge Function under Deno, a mock Pinterest API, and the official MCP TypeScript client. The client runs its own discovery, registration and PKCE flow. The suite covers:

  • end-to-end sign-in, tool listing and every tool call, including real image bytes from view_pins

  • 401s that point at resource metadata, for missing and invalid tokens

  • redirect-URI allowlist, including look-alike hosts (claude.ai.evil.example)

  • PKCE enforcement, single-use codes, cross-client code theft

  • refresh-token rotation and replay rejection

  • confidential-client authentication at the token endpoint

Setup: hosted (claude.ai)

  1. Create a Pinterest app at developers.pinterest.com/apps and add the redirect URI https://<project>.supabase.co/functions/v1/pinterest-mcp/callback.

  2. Deploy:

    supabase db push                                    # creates pmcp_kv
    supabase secrets set PINTEREST_CLIENT_ID=… PINTEREST_CLIENT_SECRET=… PMCP_ENC_KEY=$(openssl rand -base64 32)
    supabase functions deploy pinterest-mcp --no-verify-jwt
  3. In claude.ai, go to Settings → Connectors → Add custom connector and paste https://<project>.supabase.co/functions/v1/pinterest-mcp/mcp. Click Connect, approve on Pinterest, and you're done.

Check a deployment without a browser: node test/live-probe.mjs <mcp-url>.

Setup: local (Claude Code / Claude Desktop)

Requirements: macOS (for Keychain), Node 18+, and a Pinterest account.

git clone https://github.com/careerhubau-spec/pinterest-mcp.git
cd pinterest-mcp
npm install
  1. Create an app at developers.pinterest.com/apps and add the redirect URI http://localhost:8085/callback.

  2. Connect your account. A browser opens; approve read-only access:

    node auth.mjs --client-id <APP_ID> --client-secret <APP_SECRET>
    npm run status   # → connected as <username>
  3. Register the server with your MCP client. For Claude Code:

    claude mcp add pinterest -- node /absolute/path/to/pinterest-mcp/server.mjs

    For Claude Desktop, add this to claude_desktop_config.json:

    { "mcpServers": { "pinterest": { "command": "node", "args": ["/absolute/path/to/pinterest-mcp/server.mjs"] } } }

Try it

Once it's connected, ask Claude:

  • "List my Pinterest boards."

  • "What's on my Typography board? Summarise the common style."

  • "Search my pins for 'dark mode dashboard', look at the images, and pick the best three for a SaaS landing page."

  • "Download my Brand Refs board to ~/design-refs/acme so we can build a moodboard."

Scripts

Command

Purpose

npm start

Run the server on stdio

npm run auth

Connect a Pinterest account

npm run status

Show which account is connected

npm test

End-to-end OAuth + MCP test suite (needs Deno)

npm run check

Syntax-check the Node modules and type-check the Edge Function

To disconnect: security delete-generic-password -s pinterest-mcp -a token

Notes

  • Downloaded pin images are for reference only. They belong to their creators and aren't licensed for reuse.

  • It reads only the connected account's own boards.

  • New Pinterest developer apps start in "trial" access, which is enough for personal use.

License

MIT

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    • Read-only tools for your own Pinterest results: weak pins, posts to pin next, pin drafts.

      1
      https://api.sleuthlens.com/mcp
    • Your agent needs Pinterest as a demand signal — what people are saving in a category, which pins earn engagement, what a competitor's boards are collecting. **What you can ask for** • "What pins come up for 'home office setup', and which get saved most?" • "Page through this board and list the products it links to." • "Which boards does this user keep, and what are they about?" • "Show the engagement on this pin." **How to use it** Point any MCP client at https://mcp.aisa.one/pinterest/mcp and sign in with OAuth — there is no key to create or paste. 4 read tools: search pins, read one pin and its engagement, page through a board, and list a user's boards. **It is also a door to the rest** The same login reaches 26 sources and 580+ operations. Spot the trend here, then ask the same agent for search volume on the same phrase or who already ranks for it — without adding a second server. **What it costs** Finding and inspecting an operation is free. Running one is billed per call at API prices, with no seat and no monthly minimum, and every call takes max_price_usd so an agent cannot overspend by accident. **Where else it reaches** https://mcp.aisa.one/social/mcp for X plus Instagram, Reddit, Pinterest and YouTube; https://mcp.aisa.one/gtm/mcp for those plus Similarweb and Apollo.

    • Read your Savee saves, boards and home feed, and search its public library. Read-only.

      https://mcp.savee.com/mcp
    • Pinterest pins, boards, profiles and keyword search to JSON: saves, images, links, creators.

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI agents to manage Pinterest boards and pins, create and update pins, and track analytics via the Pinterest API v5.
      8
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Read-only MCP server for exposing Pinterest boards, sections, pins, and imagery as a visual reference library. Enables ChatGPT and other clients to list, search, and retrieve Pinterest content through natural language.
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      Enables AI agents to manage Pinterest accounts through the Pinterest API v5, including creating and editing pins, organizing boards, searching public content, and retrieving pin and account analytics.
      11
      MIT