picright-mcp
v0.1.0
Published
License-aware image search & insert MCP server (Openverse / Pixabay / Pexels) with a provenance ledger
Downloads
83
Maintainers
Readme
picright-mcp
License-aware image search & insert MCP server. While you write markdown, an agent can
search Openverse (CC0/CC-BY/PD), Pixabay and Pexels, check the license against a policy,
download the image next to your document, insert it with a proper credit line, and record a
provenance ledger (images/provenance.json) of what license was verified at insert time.
Tools
| tool | purpose |
|---|---|
| search_images | policy-filtered, ranked candidates with normalized license + risk + attribution text |
| get_license | full license details / caveats for one candidate |
| analyze_document | markdown → indexed blocks so the agent can pick insertion points |
| insert_image | download + insert  + credit + ledger entry |
| replace_image | swap an inserted image for another candidate |
| list_ledger | read provenance.json |
| screenshot_url | capture a page/region with headless Chromium — recorded as basis=quotation with source URL + capture date credit |
| render_diagram | Mermaid → PNG from the article's own ideas — copyright-clean (basis=original), Korean labels fine |
| render_snippet | markdown/HTML snippet + credit for remote clients without a filesystem |
Prompt illustrate bundles the AUTO workflow: analyze → choose stock / screenshot / diagram per spot → insert (last block first).
Policy defaults
usage=commercial (drops CC-NC) · need_modification=true (drops CC-ND) · no_share_alike=true (drops CC-SA) ·
no_attribution_only=false (set true for CC0/PD/Pixabay/Pexels only).
Install (Claude Code)
claude mcp add picright -- npx -y picright-mcpWorks out of the box with Openverse (no API key). Optional keys widen the pool:
claude mcp add picright \
-e PIXABAY_API_KEY=... -e PEXELS_API_KEY=... \
-- npx -y picright-mcpscreenshot_url / render_diagram need a headless Chromium once per machine
(everything else works without it):
npx playwright install chromiumDevelopment setup
npm install && npm run build
cp .env.example .env # optional: PIXABAY_API_KEY, PEXELS_API_KEY (Openverse works without keys)
npm run smoke # end-to-end check in a temp dirThen in a session: "이 글에서 이미지가 있으면 좋은 곳을 찾아 상업적 사용 가능한 이미지만 넣어줘" or /picright:illustrate.
Output example

<small>Image: Jane Doe / Pixabay (https://pixabay.com/…) — Pixabay Content License</small>Notes on sources
- Openverse: CC / public-domain only; API pre-filters with
license_type=commercial. CC-BY etc. → TASL attribution generated automatically. - Pixabay: free commercial use, no attribution required; identifiable people/logos may carry separate rights (surfaced as
caveats). - Pexels: same; the API terms ask for a credit link where possible, so
attribution_recommended=true. - Unsplash intentionally left out of the MVP (hotlink/download-event requirements).
Remote mode (Grok / ChatGPT / claude.ai web)
The same server runs over Streamable HTTP for clients that only accept remote MCP:
PORT=3000 PICRIGHT_TOKEN=<secret> PIXABAY_API_KEY=… PEXELS_API_KEY=… npm run start:http
# → POST http://localhost:3000/mcp (Authorization: Bearer <secret>) GET /healthzRemote clients have no filesystem, so use search_images → render_snippet (returns markdown/HTML with
credit + provenance record) instead of insert_image. screenshot_url and render_diagram also work
remotely: omit target_file and the PNG is returned inline as an image result.
xAI Grok (Remote MCP tools, Streamable HTTP only):
from xai_sdk import Client, user
from xai_sdk.tools import mcp
client = Client(api_key=XAI_API_KEY)
chat = client.chat.create(
model="grok-4",
tools=[mcp(server_url="https://<your-host>/mcp", headers={"Authorization": "Bearer <secret>"})],
)
chat.append(user("이 문단에 어울리는 상업적 사용 가능 이미지 1장을 출처와 함께 markdown으로: ..."))
print(chat.sample().content)Deploy (Fly.io)
brew install flyctl && fly auth login
fly launch --no-deploy --copy-config --name picright-mcp
fly secrets set PICRIGHT_TOKEN=<secret> PIXABAY_API_KEY=… PEXELS_API_KEY=…
fly deployQuick test without deploying: ngrok http 3000.
