pinterest-mcp
# pinterest-mcp
An MCP server for extracting **images, gifs, videos, and search results** from
Pinterest — using Pinterest's own **web `/resource/` API**.
**No authentication required.** The web resource API serves search, pins,
boards, and related pins fully unauthenticated — no login, token, cookie,
reCAPTCHA, or API key. So it works for anyone, anywhere, out of the box. (An
optional session cookie can be supplied to unlock personalized resources, but
it's never required for extraction.)
The endpoints, request shapes, and pin/media JSON were reverse-engineered from
pinterest.com captures and validated live.
## Tools
| Tool | Description |
| --- | --- |
| `pinterest_search` | Search pins by keyword. Filter by `mediaType`: `image` \| `gif` \| `video` \| `all`. Returns a `bookmark` for pagination. |
| `pinterest_get_pin` | Full detail for one pin — every image size and video stream. |
| `pinterest_board_pins` | Pins from a board (numeric id or `username/board-slug`). |
| `pinterest_related_pins` | Pins related to a given pin id. |
| `pinterest_autocomplete` | Search-term suggestions for a partial query. |
| `pinterest_download` | Save a pin's best media (or a direct URL) to disk. |
## Install & build
```bash
npm install
npm run build
```
## Install as a Claude Code plugin (recommended)
This repo is also a Claude Code plugin marketplace. Install with no local build:
```
/plugin marketplace add Martin-Code202/pinterest-mcp
/plugin install pinterest-mcp@pinterest-mcp
```
The plugin ships a self-contained bundle (`server.mjs`), so there's nothing to
`npm install` — the `pinterest` MCP server is registered automatically.
## Or register the MCP server manually
```bash
git clone https://github.com/Martin-Code202/pinterest-mcp.git
cd pinterest-mcp && npm install && npm run build
claude mcp add -s user pinterest -- node "$PWD/dist/index.js"
```
Either way — no credentials to configure.
## Downloading media
`pinterest_download` streams images/gifs directly to disk. Pinterest **videos
on the web are HLS (`.m3u8`) only**, so video downloads are remuxed into a
single `.mp4` with **ffmpeg** (`-c copy`, no re-encode). ffmpeg must be on
`PATH` (or set `FFMPEG_PATH`); without it, video URLs return a `skipped` note.
Default destination is `~/Downloads/pinterest`.
## Optional authentication
Not needed for extraction. If you want personalized/authenticated resources
(home feed, your own private boards), supply a web session cookie:
```bash
npm run login -- --cookie "_pinterest_sess=...; csrftoken=...; _auth=1"
# or via a browser login window (requires Playwright):
npm i -D playwright && npx playwright install chromium
npm run login -- --browser
```
Or set the `PINTEREST_COOKIE` env var. Stored at
`~/.config/pinterest-mcp/credentials.json` (mode 600).
## Confirmed API (unauthenticated)
Base: `https://www.pinterest.com/resource/<Name>Resource/get/?source_url=<path>&data=<url-encoded {options,context}>&_=<ms>`
| Operation | Resource |
| --- | --- |
| Search | `BaseSearchResource` — `options.query`, paginate via `options.bookmarks: [bookmark]` |
| Single pin | `PinResource` — `options.id`, `field_set_key: auth_web_main_pin` |
| Related pins | `RelatedModulesResource` — `options.pin_id` |
| Board pins | `BoardFeedResource` — `options.board_id` |
| Resolve board path | `BoardResource` — `options.username`, `options.slug` |
| Autocomplete | `AdvancedTypeaheadResource` — `options.term` (returns `data.items`) |
- Envelope: `{ resource_response: { status, data: {...}|{results:[...]}, bookmark } }`
- Only required header: `x-pinterest-pws-handler: www/index.js` (the
`x-app-version` build hash is **not** validated — no time bomb).
- Web videos expose HLS only (`V_HLSV4`, `V_HLSV3_MOBILE`); images are
`{ "236x": {url,width,height}, … }`.
## Architecture
```
.claude-plugin/
marketplace.json Claude Code marketplace manifest
plugin.json plugin manifest (registers the MCP server)
server.mjs self-contained bundle used by the plugin (esbuild)
src/
config.ts web base, required headers, optional cookie
index.ts MCP server + tool definitions
auth/ OPTIONAL cookie handling
store.ts cookie persistence
login-cli.ts `npm run login` (cookie / browser / status / clear)
browser-login.ts browser cookie capture (Playwright, optional)
pinterest/
client.ts web /resource/ GET client + envelope parsing
endpoints.ts search / pin / board / related / autocomplete
media.ts normalize pins -> images/videos/gifs
download.ts stream images; ffmpeg-mux HLS -> mp4
```
TDQS
Scored across 6 tools
Each tool has a clear, distinct purpose: search, detail, board listing, related, autocomplete, and download. No two tools appear to overlap in functionality, making selection unambiguous.
All tools share the pinterest_ prefix, but the pattern is mixed: some are verbs (pinterest_search, pinterest_download), some are verb+noun (pinterest_get_pin), and some are noun+noun or adjective+noun (pinterest_board_pins, pinterest_related_pins). While readable, the lack of a uniform verb_noun structure is a minor deviation.
Six tools is well within the ideal range for a focused media search and retrieval server. Each tool earns its place and the count feels neither thin nor bloated.
The surface covers the core read-only workflows: searching, fetching details, listing board pins, finding related content, getting suggestions, and downloading media. Minor gaps like board metadata or user profiles exist, but they are not essential for the apparent purpose.