discogs-mcp
by si-essence
README.md
# discogs-mcp (Discogs MCP connector)
Local MCP connector for the [Discogs API](https://www.discogs.com/developers). One user, bring-your-own personal access token, stdio by default. HTTP mode binds to `127.0.0.1` and is not a hosted service.
This application uses Discogs' API but is not affiliated with, sponsored or endorsed by Discogs. "Discogs" is a trademark of Zink Media, LLC.
The registry covers 60 of the 62 operations in `discogs.openapi.json`. Two OAuth 1.0a endpoints are excluded because this connector uses personal access tokens only. `scripts/gen-operations.mjs` holds that allow-list, and `test/operations.test.ts` repeats it. Image URLs are not an endpoint. Parsers drop image fields and never fetch them.
## Setup
```bash
npm install
npm run ci
npm start
npm run start:http
```
`npm start` speaks stdio. `npm run start:http` serves Streamable HTTP at `http://127.0.0.1:3000/mcp` and `GET /health`. HTTP mode has no authentication. Keep it on localhost.
Create a Discogs personal access token in the Discogs developer settings. Put it in `DISCOGS_TOKEN`. The connector sends `Authorization: Discogs token=<token>` and never puts the token in the query string.
```json
{
"mcpServers": {
"discogs": {
"command": "node",
"args": ["/workspace/connectors/discogs/dist/index.js"],
"env": {
"DISCOGS_TOKEN": "...",
"DISCOGS_CONTACT": "you@example.com",
"DISCOGS_ALLOW_WRITES": "false",
"DISCOGS_TOOLSETS": "database,user,collection,wantlist,lists"
}
}
}
}
```
Docker (HTTP, no authentication, localhost only):
```bash
docker build -t discogs .
docker run -p 127.0.0.1:3000:3000 \
-e DISCOGS_TOKEN=... \
-e DISCOGS_CONTACT=you@example.com \
discogs
```
Do not put tokens in the image.
Regenerate the operations registry after a spec change:
```bash
npm run gen:operations
```
## Config
| Variable | Meaning |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `DISCOGS_TOKEN` | Personal access token. Required unless `DISCOGS_ANONYMOUS=true`. At least 8 characters. Sent as `Authorization: Discogs token=<token>`. |
| `DISCOGS_CONTACT` | Required. Email or http(s) URL. Used in the User-Agent `GrokBotConnectorForDiscogs/0.1 (+<contact>)`. The server refuses to start without it. |
| `DISCOGS_ANONYMOUS` | Set to `true` for public read-only calls with no token (25 requests per minute). Database toolset plus marketplace stats only. |
| `DISCOGS_ALLOW_WRITES` | Must be the literal `true` before a confirmed write is sent. |
| `DISCOGS_USERNAME` | Default `username` path parameter. If unset, the connector calls `GET /oauth/identity` once and caches the name in memory. |
| `DISCOGS_TOOLSETS` | Comma list of toolsets, or `all`. Default `info,database,user,collection,wantlist,lists`. `marketplace` and `inventory` are opt-in. |
| `DISCOGS_CACHE_TTL_SECONDS` | In-memory TTL for public database GETs. Default 300. Hard cap 21600 (6 hours). Larger values are rejected. |
| `DISCOGS_MAX_CSV_BYTES` | Inventory CSV size cap. Default 1000000. |
| `DISCOGS_BASE_URL` | Override for tests. Default `https://api.discogs.com`. Must be https, or http on 127.0.0.1 or localhost. |
| `DISCOGS_TIMEOUT_MS` | Upstream timeout. Default 20000. |
| `MCP_TRANSPORT` | `stdio` or `http`. `--http` overrides. |
| `PORT` | HTTP port. Default 3000. Bound to 127.0.0.1. |
Invalid values are reported by field name and issue code. The rejected value is not included. The token is redacted in logs, errors, tool results, thrown messages, and URLs.
Without `DISCOGS_TOKEN` and without `DISCOGS_ANONYMOUS=true` the server refuses to start.
## Toolsets and tools
Eight tools. `discogs_info` is always on. Each other tool takes an `action` enum.
| Tool | Default | Actions |
| --------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `discogs_info` | always | Connector version, toolsets, writes, rate-limit state, cache TTL, attribution, terms note. |
| `discogs_database` | yes | search, get_release, get_release_rating, get_release_stats, get_user_release_rating, get_master, get_master_versions, get_artist, get_artist_releases, get_label, get_label_releases |
| `discogs_user` | yes | get_identity, get_profile, edit_profile, list_submissions, list_contributions |
| `discogs_collection` | yes | list_folders, create_folder, get_folder, update_folder, delete_folder, list_folder_releases, find_release, add_release, update_instance, delete_instance, list_fields, update_field, get_value, set_release_rating, delete_release_rating |
| `discogs_wantlist` | yes | list, add, update, delete |
| `discogs_lists` | yes | list, get |
| `discogs_marketplace` | opt-in | list_inventory, get_listing, create_listing, update_listing, delete_listing, list_orders, get_order, update_order, list_messages, create_message, get_fee, get_fee_for_currency, get_price_suggestions, get_stats |
| `discogs_inventory` | opt-in | request_export, list_exports, get_export, download_export, list_uploads, get_upload, upload_add, upload_change, upload_delete |
Marketplace and inventory carry buyer addresses and seller data (Restricted Data). Enable them with `DISCOGS_TOOLSETS`.
Anonymous mode publishes `discogs_info`, `discogs_database`, and `discogs_marketplace`. Search and every user or write action is refused.
Folder 0 is All. Folder 1 is Uncategorized. Folder 0 and folder 1 cannot be edited or deleted. Add a release to folder 1, not folder 0.
`include_image_urls` is an optional boolean on every tool. Default drops `images`, `thumb`, `cover_image`, and `avatar_url`. When true, those fields become URL strings. The connector never fetches images.
Inventory upload actions take `body.csv` as a string. Headers are lowercased. Required columns: add needs `release_id,price,media_condition`; change needs `release_id` plus at least one other field; delete needs `listing_id`. The dry-run preview shows the row count and the first 5 rows. Export download returns CSV text capped at 200 data rows plus `total_rows` and `truncated`.
## Write safety
Writes need `confirm` set to the boolean `true` and `DISCOGS_ALLOW_WRITES=true`. Omit `confirm` for a dry-run preview (method, path, redacted body, summary, `what_would_change`). The preview does not send a request. `confirm: true` with writes disabled returns a blocked preview.
Destructive operations are flagged: delete folder, delete collection instance, delete wantlist item, delete listing, delete rating, inventory delete CSV, and order status changes to Cancelled* or Refund Sent. Shipping and status cannot be set in the same order edit.
## Rate limits
Authenticated traffic is capped at 60 requests per minute. Anonymous traffic is capped at 25. A local sliding window runs in addition to Discogs headers `X-Discogs-Ratelimit`, `X-Discogs-Ratelimit-Used`, and `X-Discogs-Ratelimit-Remaining`. When remaining is 2 or less the client waits for the window. On HTTP 429 it honors `Retry-After` if present, otherwise it waits for the next window, retries at most once, then returns a typed rate-limit error.
Requests send `Accept: application/vnd.discogs.v2.plaintext+json`.
## Terms and data use
Every successful tool result includes `attribution` ("Data provided by Discogs. https://www.discogs.com") and `fetched_at` (ISO-8601). The full non-affiliation notice lives in the server instructions and in this README. It is not repeated as a long block on every result.
API data is cached in memory only. The connector never writes Discogs payloads to disk. Only public database GETs are cached. Collection, wantlist, marketplace, lists, and profile responses are not cached. The TTL cannot exceed 6 hours. Treat cached public data as no fresher than that cap.
Restricted Data (collections, wantlists, marketplace, images, user data) is for personal use by the token holder. No commercial use, no transfer to third parties, no sublicensing. This connector must remain free. Do not use it to charge for Discogs data. Do not bulk-copy Discogs data.
## Comparison with cswkim/discogs-mcp-server
[cswkim/discogs-mcp-server](https://github.com/cswkim/discogs-mcp-server) publishes many flat tools. This connector publishes eight tools with `action` enums, confirm-gated writes with dry-run previews, inventory CSV add/change/delete with validation, order tracking, price suggestions/fee/stats, per-user release ratings, attribution and Restricted-Data handling, Discogs rate-limit headers, typed parsers, and spec-coverage tests. Those differences are from reading that project's public description and from this repo's tests. This README does not claim a live run of the other server.
## Live check
See `LIVE-CHECK.md`. Run `node scripts/live-check.mjs --mock` against the built stdio server. `--live-public` is a small anonymous check the operator runs. `--live-token` runs only when `DISCOGS_TOKEN` is set and prints no secrets.
## License
MIT, see [LICENSE](LICENSE). This is an independent, unofficial connector and is not endorsed by the Discogs project or its owners.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues