{
  "markdown": "<p align=\"center\">\n  <a href=\"https://linkwarden.app/\">\n    <img src=\"docs/linkwarden-icon.svg\" alt=\"Linkwarden\" width=\"72\" height=\"72\">\n  </a>\n</p>\n\n# linkwarden-mcp\n\n<!-- mcp-name: io.github.flumpiey/linkwarden-mcp -->\n\n**MCP server for self-hosted [Linkwarden](https://linkwarden.app/): ask your AI about bookmarks, collections, and tags.**\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-%3E%3D3.10-blue.svg)](https://www.python.org/)\n[![MCP](https://img.shields.io/badge/MCP-stdio-green.svg)](https://modelcontextprotocol.io/)\n[![CI](https://github.com/flumpiey/linkwarden-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/flumpiey/linkwarden-mcp/actions/workflows/ci.yml)\n[![PyPI](https://img.shields.io/pypi/v/linkwarden-mcp.svg)](https://pypi.org/project/linkwarden-mcp/)\n\n## What is Linkwarden?\n\n[Linkwarden](https://linkwarden.app/) is a self-hosted, open-source bookmark manager. You collect, organize, annotate, and preserve webpages in one place, with full-page archives so content stays readable after the original page disappears. It also supports collaboration and public sharing.\n\nThis project wires the Linkwarden HTTP API into the [Model Context Protocol](https://modelcontextprotocol.io/) so Cursor, Claude, VS Code Copilot, and other MCP hosts can query your live library in natural language.\n\nUseful Linkwarden links:\n\n- [Documentation](https://docs.linkwarden.app/)\n- [GitHub](https://github.com/linkwarden/linkwarden)\n- [Cloud](https://linkwarden.app/)\n- [Demo](https://demo.linkwarden.app/)\n- [Self-hosting setup](https://docs.linkwarden.app/self-hosting/installation)\n\n## What this server does\n\nDefault is **read-only**. You get:\n\n- **18 read tools** - discovery (`list_resources`), six core reads (search, get, preserved content, collections, tags, overview), and eleven triage/hygiene workflows\n- **Task tools (opt-in)** - intent-shaped writes such as `save_link`, `smart_save_link`, `organise_links`, `create_collection`, `apply_triage_plan` (register when matching write scopes are set)\n- **Delete tools (opt-in)** - `delete_links`, `delete_tags`, `merge_tags`, `delete_collection` (register only under delete scopes; never implied by write)\n- **Hard denylist** - tokens, session, auth, user admin (except `GET /api/v1/users/me`), migration, and whole-instance preservation stay blocked even when writes are on\n\nTransport is **stdio**. No HTTP server. No global install required if you use [`uv`](https://docs.astral.sh/uv/) / `uvx`.\n\n## Branding / icons\n\nFour surfaces (keep them in sync when the mark changes):\n\n1. **stdio hosts (Cursor, Claude Desktop via `mcp.json`):** `serverInfo.icons` from [`server_icons()`](src/linkwarden_mcp/server.py) — embedded data URI from [`src/linkwarden_mcp/assets/icon.png`](src/linkwarden_mcp/assets/icon.png), plus HTTPS fallback [`docs/icon-512.png`](docs/icon-512.png) (`https://raw.githubusercontent.com/flumpiey/linkwarden-mcp/main/docs/icon-512.png`). `website_url` is `https://linkwarden.app/`.\n2. **Cursor plugin:** [`.cursor-plugin/plugin.json`](.cursor-plugin/plugin.json) `logo` → [`docs/linkwarden-icon.svg`](docs/linkwarden-icon.svg).\n3. **Claude Desktop Extension:** [`mcpb/icon.png`](mcpb/icon.png) (packed with `npx @anthropic-ai/mcpb pack mcpb`).\n4. **Claude.ai remote connectors:** Claude.ai ignores `serverInfo.icons` and uses the **root-domain favicon** of the connector URL. If you host a remote MCP later, serve [`docs/favicon.ico`](docs/favicon.ico) at the registrable domain root (e.g. `https://acme.com/favicon.ico` for `https://mcp.acme.com/...`).\n\n[`server.json`](server.json) registry metadata also points its `icons[0].src` at the same raw `docs/icon-512.png` URL.\n\n## Requirements\n\n- Python ≥ 3.10 (pulled in automatically by `uvx`)\n- [uv](https://docs.astral.sh/uv/) (provides `uvx`)\n- A reachable Linkwarden instance: `LINKWARDEN_API_URL` + `LINKWARDEN_API_KEY`\n\n### Access token\n\n1. Sign in to your Linkwarden instance (self-hosted or Cloud).\n2. Open **Settings → Access Tokens** (or go to `/settings/access-tokens`).\n3. Create a **New Access Token**, give it a name, and copy the value into `LINKWARDEN_API_KEY`.\n4. Set `LINKWARDEN_API_URL` to your instance base URL (usually without `/api/v1`; include `/api/v1` only if your deployment requires it), e.g. `https://links.example.com` or local Docker `http://127.0.0.1:3000`.\n\n`linkwarden-mcp` sends the token as `Authorization: Bearer …`. API overview: [API Introduction](https://docs.linkwarden.app/api/api-introduction).\n\nCopy [`.env.example`](.env.example) to `.env` for local runs — **never commit `.env`**. Prefer the Cursor plugin **Configure** UI for credentials, or a secret manager in production.\n\n## Quick start\n\nRun the [PyPI](https://pypi.org/project/linkwarden-mcp/) package with [`uvx`](https://docs.astral.sh/uv/guides/tools/):\n\n```bash\nuvx linkwarden-mcp\n```\n\nPaste a client config below, set `LINKWARDEN_API_URL` / `LINKWARDEN_API_KEY`, restart the host, then ask: *“Find my unread bookmarks about Python”* or *“What's in my Dev collection?”*\n\nFrom a git clone (dev): `uvx --from git+https://github.com/flumpiey/linkwarden-mcp linkwarden-mcp` or `uv run --directory /path/to/linkwarden-mcp linkwarden-mcp`.\n\n## Installation\n\nConfigs below pull [`linkwarden-mcp`](https://pypi.org/project/linkwarden-mcp/) from PyPI. Leave write-scope env vars unset for read-only.\n\n<details>\n<summary><strong>Cursor</strong></summary>\n\n**Plugin (Configure UI for URL, key, and scopes):** this repo is a Cursor plugin via [`.cursor-plugin/plugin.json`](.cursor-plugin/plugin.json) + root [`mcp.json`](mcp.json).\n\n1. Symlink or copy the clone to `~/.cursor/plugins/local/linkwarden-mcp` (Windows: `%USERPROFILE%\\.cursor\\plugins\\local\\linkwarden-mcp`).\n   - **macOS / Linux:** `ln -s /path/to/linkwarden-mcp ~/.cursor/plugins/local/linkwarden-mcp`\n   - **Windows:** Cursor does **not** follow symlinks for local plugins. Use a junction or copy instead:\n     ```bat\n     mklink /J \"%USERPROFILE%\\.cursor\\plugins\\local\\linkwarden-mcp\" \"E:\\Development\\linkwarden-mcp\"\n     ```\n     or:\n     ```bat\n     robocopy \"E:\\Development\\linkwarden-mcp\" \"%USERPROFILE%\\.cursor\\plugins\\local\\linkwarden-mcp\" /E\n     ```\n2. Reload the window.\n3. Open **Plugins → Configure** on `linkwarden-mcp`. Set **Linkwarden API URL** and **Linkwarden API key**. Leave **Write scopes** / **Delete scopes** empty for read-only, or paste a CSV such as `links,collections`.\n4. Confirm the `linkwarden` MCP server is enabled under Customize / MCP.\n\nMarketplace listing is a separate submit at [cursor.com/marketplace/publish](https://cursor.com/marketplace/publish).\n\n**Manual `mcp.json`:** project [`.cursor/mcp.json`](.cursor/mcp.json) or user-wide `~/.cursor/mcp.json`. Root [`mcp.json`](mcp.json) is plugin wiring with `${…}` placeholders only — never commit real secrets there.\n\nFrom PyPI:\n\n```json\n{\n  \"mcpServers\": {\n    \"linkwarden\": {\n      \"type\": \"stdio\",\n      \"command\": \"uvx\",\n      \"args\": [\"linkwarden-mcp\"],\n      \"env\": {\n        \"LINKWARDEN_API_URL\": \"https://links.example.com\",\n        \"LINKWARDEN_API_KEY\": \"your-token\"\n      }\n    }\n  }\n}\n```\n\nLocal editable (dev):\n\n```json\n{\n  \"mcpServers\": {\n    \"linkwarden\": {\n      \"type\": \"stdio\",\n      \"command\": \"uv\",\n      \"args\": [\"run\", \"--directory\", \"/path/to/linkwarden-mcp\", \"linkwarden-mcp\"],\n      \"env\": {\n        \"LINKWARDEN_API_URL\": \"https://links.example.com\",\n        \"LINKWARDEN_API_KEY\": \"your-token\"\n      }\n    }\n  }\n}\n```\n\nOptional scoped writes in the `env` block:\n\n```json\n\"LINKWARDEN_MCP_WRITE_SCOPES\": \"links,collections\",\n\"LINKWARDEN_MCP_DELETE_SCOPES\": \"links\"\n```\n\nRestart Cursor after saving. Confirm `linkwarden` under MCP settings.\n\n</details>\n\n<details>\n<summary><strong>Claude Desktop</strong></summary>\n\n**Desktop Extension (`.mcpb`):** download [`mcpb.mcpb`](https://github.com/flumpiey/linkwarden-mcp/releases/latest/download/mcpb.mcpb) from [GitHub Releases](https://github.com/flumpiey/linkwarden-mcp/releases). Use **v0.1.5+** (needs [`uv`](https://docs.astral.sh/uv/) on PATH). Launch is `uv tool run --python 3.12 linkwarden-mcp`. Do not put the PyPI package in `mcpb/pyproject.toml` dependencies — Claude Desktop syncs that file at install and can fail on system Python 3.13.\n\n1. Open Claude Desktop → **Settings → Extensions**.\n2. Open **Advanced settings** → **Install Extension…**\n3. Select `mcpb.mcpb`. Review permissions, enter **Linkwarden API URL** and **Linkwarden API key**, then click **Install**.\n4. Leave **Write scopes** and **Delete scopes** empty for read-only.\n5. Restart Claude Desktop if tools do not appear.\n\nBuild your own bundle from a clone:\n\n```bash\nnpx @anthropic-ai/mcpb pack mcpb\n```\n\nOn Windows, double-click often does nothing and dragging the file into chat attaches it to the conversation instead of installing it. Use **Install Extension…** in Settings.\n\n**Manual `claude_desktop_config.json` fallback:** edit the Claude Desktop config, then restart the app.\n\n| OS | Path |\n|----|------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n\n```json\n{\n  \"mcpServers\": {\n    \"linkwarden\": {\n      \"command\": \"uvx\",\n      \"args\": [\"linkwarden-mcp\"],\n      \"env\": {\n        \"LINKWARDEN_API_URL\": \"https://links.example.com\",\n        \"LINKWARDEN_API_KEY\": \"your-token\"\n      }\n    }\n  }\n}\n```\n\nLocal clone:\n\n```json\n{\n  \"mcpServers\": {\n    \"linkwarden\": {\n      \"command\": \"uv\",\n      \"args\": [\"run\", \"--directory\", \"/path/to/linkwarden-mcp\", \"linkwarden-mcp\"],\n      \"env\": {\n        \"LINKWARDEN_API_URL\": \"https://links.example.com\",\n        \"LINKWARDEN_API_KEY\": \"your-token\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><strong>Claude Code</strong></summary>\n\nAdd via CLI:\n\n```bash\nclaude mcp add linkwarden --env LINKWARDEN_API_URL=https://links.example.com --env LINKWARDEN_API_KEY=your-token -- uvx linkwarden-mcp\n```\n\nOr edit `~/.claude.json` / project MCP config:\n\n```json\n{\n  \"mcpServers\": {\n    \"linkwarden\": {\n      \"command\": \"uvx\",\n      \"args\": [\"linkwarden-mcp\"],\n      \"env\": {\n        \"LINKWARDEN_API_URL\": \"https://links.example.com\",\n        \"LINKWARDEN_API_KEY\": \"your-token\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><strong>VS Code / GitHub Copilot</strong></summary>\n\nCreate [`.vscode/mcp.json`](.vscode/mcp.json) in the project root:\n\n```json\n{\n  \"servers\": {\n    \"linkwarden\": {\n      \"type\": \"stdio\",\n      \"command\": \"uvx\",\n      \"args\": [\"linkwarden-mcp\"],\n      \"env\": {\n        \"LINKWARDEN_API_URL\": \"https://links.example.com\",\n        \"LINKWARDEN_API_KEY\": \"your-token\"\n      }\n    }\n  }\n}\n```\n\nLocal editable:\n\n```json\n{\n  \"servers\": {\n    \"linkwarden\": {\n      \"type\": \"stdio\",\n      \"command\": \"uv\",\n      \"args\": [\"run\", \"--directory\", \"/path/to/linkwarden-mcp\", \"linkwarden-mcp\"],\n      \"env\": {\n        \"LINKWARDEN_API_URL\": \"https://links.example.com\",\n        \"LINKWARDEN_API_KEY\": \"your-token\"\n      }\n    }\n  }\n}\n```\n\nReload the window. Open Copilot Chat and confirm the `linkwarden` tools are available.\n\n</details>\n\n<details>\n<summary><strong>Windsurf</strong></summary>\n\nEdit `~/.codeium/windsurf/mcp_config.json` (macOS/Linux) or the Windsurf MCP settings UI:\n\n```json\n{\n  \"mcpServers\": {\n    \"linkwarden\": {\n      \"command\": \"uvx\",\n      \"args\": [\"linkwarden-mcp\"],\n      \"env\": {\n        \"LINKWARDEN_API_URL\": \"https://links.example.com\",\n        \"LINKWARDEN_API_KEY\": \"your-token\"\n      }\n    }\n  }\n}\n```\n\nRestart Windsurf after saving.\n\n</details>\n\n<details>\n<summary><strong>Zed</strong></summary>\n\nAdd under `context_servers` in Zed `settings.json` (Agent Panel → settings also works):\n\n```json\n{\n  \"context_servers\": {\n    \"linkwarden\": {\n      \"command\": \"uvx\",\n      \"args\": [\"linkwarden-mcp\"],\n      \"env\": {\n        \"LINKWARDEN_API_URL\": \"https://links.example.com\",\n        \"LINKWARDEN_API_KEY\": \"your-token\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><strong>Cline</strong></summary>\n\nEdit the Cline MCP settings file (`cline_mcp_settings.json` via the Cline MCP UI):\n\n```json\n{\n  \"mcpServers\": {\n    \"linkwarden\": {\n      \"command\": \"uvx\",\n      \"args\": [\"linkwarden-mcp\"],\n      \"env\": {\n        \"LINKWARDEN_API_URL\": \"https://links.example.com\",\n        \"LINKWARDEN_API_KEY\": \"your-token\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><strong>Continue</strong></summary>\n\nIn `.continue/config.yaml`:\n\n```yaml\nmcpServers:\n  - name: linkwarden\n    command: uvx\n    args:\n      - linkwarden-mcp\n    env:\n      LINKWARDEN_API_URL: https://links.example.com\n      LINKWARDEN_API_KEY: your-token\n```\n\n</details>\n\n<details>\n<summary><strong>Generic / any stdio MCP host</strong></summary>\n\nAny host that can spawn a stdio MCP server:\n\n| Field | Value |\n|-------|-------|\n| Command | `uvx` |\n| Args | `linkwarden-mcp` |\n| Env | `LINKWARDEN_API_URL`, `LINKWARDEN_API_KEY` (+ optional write scopes) |\n\n```bash\nuvx linkwarden-mcp\n```\n\nDev from a clone: `uv run --directory /path/to/linkwarden-mcp linkwarden-mcp`.\n\n`npx` only runs npm packages. This is a Python package; use `uvx`.\n\n</details>\n\n## Environment\n\n| Variable | Required | Notes |\n|----------|----------|-------|\n| `LINKWARDEN_API_URL` | yes | Base URL (include `/api/v1` only if required; typical: `https://links.example.com`) |\n| `LINKWARDEN_API_KEY` | yes | Access token from Settings → Access Tokens; sent as `Authorization: Bearer`; never logged |\n| `LINKWARDEN_MCP_WRITE_SCOPES` | no | Comma-separated domains for create/update. Empty = no writes. |\n| `LINKWARDEN_MCP_DELETE_SCOPES` | no | Comma-separated domains for delete only. Never implied by WRITE_SCOPES. |\n| `LINKWARDEN_MAX_BULK` | no | Max records per bulk op (default `25`) |\n| `TEST_LINKWARDEN_API_URL` | integration only | Live sandbox URL for `pytest -m integration` |\n| `TEST_LINKWARDEN_API_KEY` | integration only | Live sandbox token for `pytest -m integration` |\n\nValid scopes: `links`, `collections`, `tags`, `raw`. No wildcards (`*`, `all`). `raw` expands effective scopes to all domain scopes (escape hatch).\n\n**Recommended** (covers most bookmark workflows without every mutating tool):\n\n```json\n\"LINKWARDEN_MCP_WRITE_SCOPES\": \"links,collections\",\n\"LINKWARDEN_MCP_DELETE_SCOPES\": \"links\"\n```\n\nDefault with no scopes: **18 tools**. All three domain scopes in WRITE and DELETE: **31 tools**.\n\nLegacy `LINKWARDEN_MCP_ALLOW_WRITES` / `ALLOW_WRITES` / `LINKWARDEN_MCP_WRITES` hard-fail if set. Use the scoped vars instead.\n\nMCP host env (`.cursor/mcp.json` or Cursor plugin Configure) **must match** process env / `.env` or scope behavior drifts.\n\nSee [`.env.example`](.env.example). **Never commit `.env`.** Prefer Cursor plugin Configure UI or a secret manager in production.\n\n## Write scopes and task tools\n\nWhen a scope is listed in `LINKWARDEN_MCP_WRITE_SCOPES`, the server registers **task tools** for that domain. `LINKWARDEN_MCP_DELETE_SCOPES` enables delete/merge tools per domain. Call `list_resources` to inspect `read_only`, scope lists, and the live boundary string.\n\n| Tool | Scopes | Purpose |\n|------|--------|---------|\n| `save_link` | WRITE `links` | Save a URL into a collection (by name) |\n| `smart_save_link` | WRITE `links` | Save with optional heuristic collection/tags |\n| `organise_links` | WRITE `links` | Move or retag multiple links |\n| `update_link` | WRITE `links` | Update link fields (read-modify-write) |\n| `queue_archive` | WRITE `links` | Queue preservation (async; not immediate) |\n| `apply_triage_plan` | WRITE `links` | Apply `[{link_id, collection?, tags?}]`; default `dry_run=true` |\n| `bulk_sort_by_rules` | WRITE `links` | Match `domain_pattern` rules then organise; default `dry_run=true` |\n| `create_collection` | WRITE `collections` | Create a collection (optional parent) |\n| `auto_tag_by_domain` | WRITE `links` + `tags` | Apply domain→tag rules; default `dry_run=true` |\n| `delete_links` | DELETE `links` | Delete multiple links |\n| `delete_tags` | DELETE `tags` | Delete tags by id or name |\n| `merge_tags` | DELETE `tags` | Merge tags into a new name (destructive) |\n| `delete_collection` | DELETE `collections` | Delete a collection after user chooses delete/move/cancel for its links (elicitation or `on_links`) |\n\nExample with recommended scopes only:\n\n```json\n\"LINKWARDEN_MCP_WRITE_SCOPES\": \"links,collections\",\n\"LINKWARDEN_MCP_DELETE_SCOPES\": \"links\"\n```\n\n**Denylist (always blocked):** `/api/v1/tokens`, `/api/v1/session`, `/api/v1/auth`, `/api/v1/users/**` (except `GET /api/v1/users/me`), migration, and whole-instance preservation worker actions.\n\n## Tools\n\n### Read tools\n\nAlways registered (18 total).\n\n| Tool | Purpose |\n|------|---------|\n| `list_resources` | Discovery; reports `read_only` + live write/delete scopes |\n| `search_links` | Search by query, collection, tag, or pin status |\n| `get_link` | Full metadata for one link |\n| `read_link_content` | Preserved plain text (`textContent` or archive fallback) |\n| `list_collections` | Collections with link counts |\n| `list_tags` | Tags with link counts |\n| `get_library_overview` | Totals, empty collections, unused tags |\n| `suggest_collection_for_url` | Heuristic collection suggestions for a URL |\n| `suggest_tags_for_link` | Suggest existing-library tags (never invents names) |\n| `find_unsorted_links` | List unsorted links (default collection: Unorganized) |\n| `triage_links` | Propose collection/tags for link ids (no writes) |\n| `find_duplicate_links` | Group links with the same normalized URL |\n| `recommend_collection_for_links` | Consensus collection for a batch of links |\n| `suggest_links_for_collection` | Find links elsewhere that likely belong |\n| `analyze_collection_overlap` | Compare two collections for shared domains/tags/URLs |\n| `suggest_collection_structure` | Hygiene: empty, near-duplicate names, overcrowded |\n| `align_tags_with_similar_links` | Tags used on similar-domain links |\n| `get_sorting_dashboard` | One-shot triage: unsorted, duplicates, empty, largest |\n\n### Write tools\n\nRegistered only when matching scopes are set (see table above). Prefer `smart_save_link` / triage tools over raw field edits when you are sorting an inbox.\n\n| Pattern | Requires | Notes |\n|---------|----------|-------|\n| Link create/update/organise/archive | WRITE `links` | Includes workflow writers with `dry_run` defaults |\n| Collection create | WRITE `collections` | Optional parent by name |\n| Domain auto-tag | WRITE `links` + `tags` | Only existing tag names |\n| Deletes / tag merge | matching DELETE scope | Destructive; confirm ids first |\n\n## Agent Skill\n\nCompanion skill: [`skills/linkwarden-bookmarks/SKILL.md`](skills/linkwarden-bookmarks/SKILL.md).\n\nThe Cursor plugin discovers this skill from `skills/`. Without the plugin, copy or symlink that folder into your agent skills path. It tells the model to call `list_resources` first, verify after writes, and which workflow tools to prefer.\n\n## Development\n\n```bash\nuv sync --extra dev\nnpm install          # installs lefthook + commitlint; registers git hooks\nuv run linkwarden-mcp\n```\n\nOffline tests only (respx). No live Linkwarden required:\n\n```bash\nuv run ruff check src tests\nuv run pytest\n```\n\n### Git hooks (lefthook)\n\n| Hook / command | What it runs |\n|----------------|--------------|\n| **pre-commit** | `ruff check` + full `pytest` (mocked suite) |\n| **commit-msg** | [commitlint](https://commitlint.js.org/) Conventional Commits |\n| **`npm run pre-publish`** | ensure build/twine → ruff → pytest → sdist contents → `python -m build` → `twine check` → `npx @anthropic-ai/mcpb pack mcpb` |\n\nCommit messages must follow Conventional Commits, e.g. `feat(api): add delete_links tool`.\n\nRun the local publish gate before tagging a release:\n\n```bash\nnpm run pre-publish\n```\n\nGitHub Actions matrix: Python 3.10 and 3.12.\n\n## Caveats\n\n- One process ↔ one `LINKWARDEN_API_URL`. Multi-instance routing is out of scope.\n- Multi-user / team disambiguation on a shared instance is **unverified**. Do not claim multi-tenant support until validated against a live shared library.\n- Collection/tag suggestions are heuristic and library-local; they do not invent new tag names.\n- Bulk mutating workflows default to `dry_run=true`; set `dry_run=false` only after you review the plan.\n- ChatGPT Apps need a hosted HTTP MCP endpoint. This package is stdio-only.\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n",
  "bytes": 20346,
  "sha": "06445d328dc3343bcef2271e222041abbf2ace36d7918af90fd995d381d880ff",
  "repo_slug": "flumpiey/linkwarden-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_flumpiey_linkwarden_mcp_397f3e6c/readme"
}