Skip to main content
Glama
crosbyh

linkding-mcp

by crosbyh

linkding-mcp

An MCP server for Linkding bookmarks and web archival, designed to work as a claude.ai / Claude Desktop custom connector — so Claude can search, add, tag, archive, and delete your bookmarks (and inspect their archival snapshots) from the web or desktop app.

Talks to Linkding's REST API with a personal API token. Targets Linkding v1.31+ (token auth, limit/offset pagination, assets API for HTML snapshots). Built with FastMCP; authentication uses GitHub OAuth via FastMCP's OAuth proxy, restricted to an allowlist of GitHub usernames.

Tools

Tool

Description

list_bookmarks

Search/list, newest first; Linkding query syntax (#tag, !unread, …)

get_bookmark

Full detail for one bookmark, including notes and archive URL

check_url

Is a URL already bookmarked? Returns scraped page metadata too

add_bookmark

Bookmark a URL — title/description/notes/tags; upserts by URL

edit_bookmark

Change url / title / description / notes / tags / unread / shared

archive_bookmark / unarchive_bookmark

Move to/from the archive (reversible)

delete_bookmark

Permanent delete; requires confirm=true

list_tags

Show all tags

list_snapshots

Archival snapshots: local HTML assets + Internet Archive URL

Bookmarks are matched by numeric id, exact URL, or title/URL substring; ambiguous matches return candidates so the model can retry with an id. Adding a URL that is already bookmarked updates the existing bookmark (Linkding upserts by URL); omitted title/description are scraped from the page.

Setup

1. Linkding API token

In Linkding: Settings → Integrations → REST API. Copy the token into LINKDING_API_TOKEN (or a secret file via LINKDING_API_TOKEN_FILE).

2. GitHub OAuth app (connector authentication)

  1. https://github.com/settings/developersOAuth Apps → New OAuth App.

  2. Authorization callback URL: https://linkding-mcp.example.com/auth/callback (your MCP_BASE_URL + /auth/callback).

  3. Register, generate a client secret, and set GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET / ALLOWED_GITHUB_USERS.

Leaving the client ID/secret unset runs the server unauthenticated — local testing only.

3. Configuration reference

Variable

Required

Description

LINKDING_URL

yes

Linkding base URL, e.g. https://links.example.com

LINKDING_API_TOKEN

yes

API token (or LINKDING_API_TOKEN_FILE)

TZ

no

Timezone for date display

MCP_BASE_URL

with auth

Public URL of this server

GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET

with auth

OAuth app credentials (or _FILE)

ALLOWED_GITHUB_USERS

with auth

Comma-separated GitHub logins allowed in

CONSENT_MODE

no

external (default), true, remember, false — see below

ALLOWED_CLIENT_REDIRECT_URIS

no

Redirect-URI patterns clients may register (default: claude.ai callback + localhost)

HOST / PORT / MCP_PATH

no

Bind address (0.0.0.0), port (8000), path (/mcp)

FASTMCP_HOME

no

OAuth client-registration storage (/data in Docker)

4. Run it

See compose.example.yml. Expose it publicly at MCP_BASE_URL through your reverse proxy; optionally restrict ingress to Anthropic's egress range (160.79.104.0/21). Persist /data or connected clients must re-authorize after every restart.

5. Verify, then connect Claude

npx @modelcontextprotocol/inspector   # → https://linkding-mcp.example.com/mcp

Then claude.ai (or Claude Desktop) → Settings → Connectors → Add custom connector with the same URL. You'll land on GitHub's authorize page; approve, and the tools appear. Ask Claude: "what did I bookmark about docker?"

Why CONSENT_MODE=external is the default

FastMCP's built-in consent page (as of 3.4.4) regenerates its CSRF token on every GET of the consent URL. Browsers and claude.ai routinely prefetch that URL, invalidating the token the visible page holds, so submitting the form fails with "Invalid or expired consent token". external skips that page and delegates consent to GitHub's own authorization screen. The client redirect-URI allowlist (claude.ai + localhost by default) prevents the classic risk of a consent-less flow — an arbitrary dynamically-registered client silently capturing an authorization code.

Failure modes

  • 401 from Linkding → the API token is wrong or was revoked; copy it again from Settings → Integrations → REST API.

  • GitHub login succeeds but tools are denied → your login isn't in ALLOWED_GITHUB_USERS (check logs for denied authenticated GitHub user).

  • Connector breaks after a redeploy/data wasn't persisted, or the GitHub client secret changed (registration storage is keyed to it). Re-add the connector.

  • list_snapshots shows no local snapshots → Linkding's HTML snapshots require LD_ENABLE_SNAPSHOTS=True on the Linkding instance; the Internet Archive URL only appears when Linkding's web-archive integration is enabled.

Development

uv sync
uv run pytest

License

MIT

-
license - not tested
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/crosbyh/linkding-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server