Skip to main content
Glama
crunchypancake1

Linkwarden MCP

Linkwarden MCP

An MCP server that exposes a Linkwarden bookmark collection as a tool set, running as a stateful agent on Cloudflare Workers. Point an MCP client (Claude, etc.) at the deployed endpoint and it can browse, search, filter, create, and archive links directly against your own Linkwarden instance.

How it works

Every tool call goes straight to the Linkwarden REST API on your live instance — there's no index, cache, or background sync involved. The instance isn't exposed publicly: requests reach it over a Workers VPC service binding, which tunnels to the private host via cloudflared.

MCP client ──HTTP/SSE──► Worker (/mcp) ──► LinkwardenMCP (Durable Object)
                                                  │
                                     LINKWARDEN_VPC binding (+ LINKWARDEN_TOKEN)
                                                  │
                                    Cloudflare Tunnel → Linkwarden API (private)

LinkwardenMCP is a McpAgent hosted on a Durable Object.

Related MCP server: OpenViking MCP Server

Tools

Tool

Description

list_links

List links, optionally filtered to specific collections

search_links

Full-text search and filter by collection/tag

get_link

Fetch a single link by ID

create_link

Save a new bookmark

archive_link

Trigger or refresh a link's archive snapshot

list_collections

List all Linkwarden collections

list_tags

List all tags

Setup

npm install

Linkwarden is reached through a VPC Service, created once against the Cloudflare Tunnel that runs on the same network as the instance:

wrangler vpc service create linkwarden \
  --type http --tunnel-id <tunnel-id> --hostname <internal-host> --http-port 9000

wrangler.jsonc binds the returned service ID under vpc_services, and the LINKWARDEN_URL var supplies the URL used for the request path and Host header (the VPC Service — not this URL — decides where the request actually goes):

"vars": { "LINKWARDEN_URL": "http://mediaserver:9000" },
"vpc_services": [
  { "binding": "LINKWARDEN_VPC", "service_id": "<service-id>", "remote": true }
]

LINKWARDEN_TOKEN (a Linkwarden API access token) is read from Cloudflare's Secrets Store, not a plain Wrangler secret. Create it once per account and it's reusable across Workers:

wrangler secrets-store secret create <store-id> \
  --name linkwarden-token --scopes workers --remote

wrangler.jsonc then binds it via secrets_store_secrets:

"secrets_store_secrets": [
  { "binding": "LINKWARDEN_TOKEN", "store_id": "<store-id>", "secret_name": "linkwarden-token" }
]

For local dev, create a local-only secret with the same name (omit --remote) so wrangler dev has something to read. The VPC binding is marked remote: true, so wrangler dev connects to the real VPC Service — there is no local emulation of it.

See CLAUDE.md for the full architecture and binding reference.

Development

npm run dev         # wrangler dev — local development with hot reload
npm run test        # vitest run
npm run typecheck   # tsc --noEmit

Deploy

Cloudflare Workers Builds is connected to this repo — pushing to master deploys automatically (npm run build then wrangler deploy). npm run deploy remains available for manual/ad-hoc deploys. Either way, the linkwarden-token secret must exist in the account's Secrets Store — it is never stored in the repo.

Stack

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Lightweight MCP server that connects to OpenViking for semantic search, resource management, and memory storage via natural language.
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server for Linkding bookmarks and web archival, enabling Claude to search, add, tag, archive, and delete bookmarks including archival snapshots.
    MIT