Skip to main content
Glama

lychee

MCP connector for a self-hosted Lychee photo gallery. It speaks the Lychee /api/v2 routes over stdio and over stateless Streamable HTTP on localhost.

LycheeOrg/Lychee is MIT software. This connector does not copy the PHP application. It is not affiliated with LycheeOrg.

lychee.routes.json lists every uncommented Route::get|post|put|patch|delete call in routes/api_v2.php. 67 routes are tool actions. 193 are exclusions. scripts/gen-operations.mjs writes src/operations.ts from that file. Do not edit src/operations.ts by hand. Shop, embed, and v3 route files are out of scope. The commented Photo::getArchive line is not a route.

LYCHEE_URL and LYCHEE_API_TOKEN are required. There is no default origin. The client sends Authorization: Bearer <token>. Lychee stores a SHA-512 hash of the token and answers HTTP 400 Invalid token when the header is wrong.

Setup

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 of its own. Keep it on localhost.

{
  "mcpServers": {
    "lychee": {
      "command": "node",
      "args": ["/workspace/connectors/lychee/dist/index.js"],
      "env": {
        "LYCHEE_URL": "http://127.0.0.1:8099",
        "LYCHEE_API_TOKEN": "...",
        "LYCHEE_ALLOW_WRITES": "false",
        "LYCHEE_TOOLSETS": "albums,photos,tags,search,sharing,users,settings"
      }
    }
  }
}

Docker, HTTP, no authentication, keep it on localhost.

docker build -t lychee-mcp .
docker run -p 127.0.0.1:3000:3000 \
  -e LYCHEE_URL=http://127.0.0.1:8099 \
  -e LYCHEE_API_TOKEN=... \
  lychee-mcp

Do not put secrets in the image.

Regenerate the registry after a route bump.

npm run gen:operations

scripts/live-check.mjs talks to a real server over stdio. It reads the token from LYCHEE_API_TOKEN or from LYCHEE_API_TOKEN_FILE (default /workspace/tools/lychee/api.token). It unsets DATABASE_URL. It sets LYCHEE_TOOLSETS=all for the child process. It prints pass or fail lines only, and it redacts the token. It does not run inside npm run ci.

Related MCP server: gphotos-mcp

Config

Variable

Meaning

LYCHEE_URL

Required. Origin only, http or https, no userinfo, query, hash, or path. Example http://127.0.0.1:8099. A URL whose path is already /api/v2 is rejected.

LYCHEE_API_TOKEN

Required. The raw token. The client sends Authorization: Bearer <token>. A leading Bearer in the variable is stripped. Redacted in logs, errors, and tool results.

LYCHEE_ALLOW_WRITES

Must be the literal true before a confirmed write is sent.

LYCHEE_TOOLSETS

Comma list, or all. Default is the read-only set below.

LYCHEE_PER_MINUTE

Local request budget. Default 30. Cache hits do not spend it.

LYCHEE_TIMEOUT_MS

Upstream timeout. Default 20000.

LYCHEE_CACHE_TTL_SEC

Read cache TTL. Default 60. Writes clear the cache.

LYCHEE_CONTACT

Contact token in the User-Agent. Must not contain the API token.

MCP_TRANSPORT

stdio or http. --http overrides.

PORT

HTTP port. Default 3000.

Invalid values are reported by field name and issue code. The rejected value is not included.

Every mapped route is called as /api/v2 plus the PHP path. Accept is application/json. JSON writes send Content-Type: application/json. Multipart upload leaves the boundary to fetch.

Safety

Default toolsets are reads. Album, photo, tag, and share writes, plus diagnostic maintenance GETs, live on separate toolsets. Those toolsets are off until LYCHEE_TOOLSETS includes them or is all.

A write on an enabled toolset still needs confirm set to the boolean true and LYCHEE_ALLOW_WRITES=true. The string "true" is rejected. Otherwise the tool returns a dry-run preview of method, path, query, and body, and it sends nothing. Omit confirm and blocked is false. Confirm true with writes disabled and blocked is true.

Upload preview does not read body.file_path and does not echo the absolute path. A missing file is an input error and sends no bytes.

HTTP 401 is unauthorized. HTTP 400 whose message is Invalid token is also unauthorized (Lychee's bad-token response). Other HTTP 400 is invalid input. HTTP 403 is forbidden. HTTP 404 is not found. HTTP 422 is invalid input. HTTP 429 includes Retry-After when the header is present. Other failures are server, network, or timeout. Response bodies are capped at 1,000,000 bytes.

Password fields, including album protection passwords, are redacted in previews and errors. The API token is redacted the same way.

Tools

Default LYCHEE_TOOLSETS publishes 7 tools and 20 read operations. LYCHEE_TOOLSETS=all publishes 12 tools and 67 operations. Each tool takes action plus optional params, query, body, and, on write tools, confirm.

action help with optional target returns the fields for one action. Descriptions list action names only, so the tool list stays small.

Toolset

Tool

Operations

Default

albums

lychee_albums

list, get, tree

yes

photos

lychee_photos

list, get

yes

tags

lychee_tags

list, get

yes

search

lychee_search

init, search

yes

sharing

lychee_sharing

list, list_all, list_albums

yes

users

lychee_users

current, rights, list, count

yes

settings

lychee_settings

init, upload_limits, get, version

yes

albums_write

lychee_albums_write

create, rename, set_protection, delete, move

no

sharing_write

lychee_sharing_write

create, edit, delete

no

photos_write

lychee_photos_write

import, upload, edit, rename, tags, move, copy, star, delete

no

maintenance

lychee_maintenance

errors, info, space, config, permissions, cleaning, jobs, tree, gensizevariants, missingfilesize, fulltree, countduplicates, searchduplicates, statisticsintegrity, missingpalettes, oldorders, fulfillorders, fulfillprecompute, flushqueue, backfillalbumsizes, recomputetakenatrange, bulkscanfaces, runfaceclustering, destroydismissedfaces, syncfaceembeddings, resetfacescanstatus, purgeorphanfaceembeddings

no

tags_write

lychee_tags_write

rename, merge, delete

no

lychee_albums list is GET /api/v2/Albums. tree is GET /api/v2/Album::albums. get is GET /api/v2/Album::head.

lychee_sharing list is GET /api/v2/Sharing and requires query album_id. list_all is GET /api/v2/Sharing::all.

lychee_photos list is GET /api/v2/Album::photos with query album_id. get is GET /api/v2/Photo/{photo_id}/albums and only returns album membership. Pass photo_id in params.

lychee_search search takes plain text in query q. The connector base64-encodes q into terms and drops q. Do not hand-encode. init is GET /api/v2/Search::init. Pass query album_id. An empty string means the root.

lychee_photos_write upload is multipart POST /api/v2/Photo. Pass body.file_path plus optional album_id, title, and description. Chunk 1 sends an empty uuid_name. Later chunks reuse the uuid_name from the previous response. A one-chunk file is only chunk 1. album_id may be null for the root. The final tool result includes expected_id when Lychee sets it. import is POST /api/v2/Photo::fromUrl. tags needs photo_ids, tags, and shall_override. delete needs photo_ids and from_id (the album the photos are shown from).

lychee_albums_write set_protection is POST /api/v2/Album::updateProtectionPolicy. Album passwords are not a sharing action.

lychee_settings get is GET /api/v2/Settings. A non-admin token can receive 403. upload_limits is GET /api/v2/Gallery::getUploadLimits. init is GET /api/v2/Gallery::Init. version is GET /api/v2/Version.

lychee_users reads GET /api/v2/Auth::user, GET /api/v2/Auth::rights, GET /api/v2/Users, and GET /api/v2/Users::count.

lychee_maintenance is every diagnostic GET under /Diagnostics and /Maintenance::. GET /Diagnostics is action errors. Non-GET maintenance routes are excluded.

What this connector leaves out

Session, login, logout, registration, token reset, WebAuthn, OAuth, gallery unlock, and album unlock stay out. The connector uses a pre-issued API token.

Admin mutations, user management, user groups, settings writes, webhooks, landing editors, moderation, bulk album edit, metrics, statistics, renamer rules, import browsing, and contact forms are excluded.

AI vision, people, faces, and NSFW routes are excluded. So are timeline, map, flow, frame, and other gallery chrome reads.

Binary zip downloads and album track uploads are excluded. PUT /Sharing (propagate) is excluded. Album and photo mutations outside the named actions are excluded. Every non-GET maintenance route is excluded.

Each exclusion has a reason longer than 20 characters in lychee.routes.json.

Other servers

There is no public LycheeOrg MCP.

These names are not this connector.

lycheeverse/lychee is a link checker.

Lychee-rb2/lychee_mcp is an empty repository.

ssoma-dev/mcp-server-lychee-redmine is a Redmine MCP server.

delfianto/lychee is a manga server.

The nearest photo-library servers are drolosoft/immich-photo-manager and barryw/ImmichMCP. Those Immich servers enable writes by default. This connector does not.

Live check

Last run: PASS, passed=25, failed=0 against local Lychee 7.12.1 at http://127.0.0.1:8099 (SQLite, admin token, DATABASE_URL unset). Reads, create/rename/upload/tag/delete, write guard, and a bad-token HTTP 400 were exercised. See LIVE-CHECK.md.

The parent harness runs scripts/live-check.mjs against http://127.0.0.1:8099 when it chooses to. This package does not start Lychee.

License

MIT. See LICENSE. LycheeOrg/Lychee stays under the Lychee MIT license.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI assistants to search a self-hosted photo and video library, view photos, and manage albums through MCP, with all actions scoped to the connected account and vault items hidden.
    1
    AGPL 3.0
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables read-only access to a personal Google Photos library, allowing listing, searching, inspecting, and viewing photos and albums via MCP tools.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP clients to search, filter, and manage a private local photo library with CLIP-based text and similarity search, EXIF/GPS metadata, duplicate detection, albums, and folder indexing, returning ranked results and optional contact sheets.
    MIT
  • A
    license
    C
    quality
    C
    maintenance
    It exposes the full official Immich API (276 tools across 41 groups) to MCP clients, letting them search and manage assets, albums, people, tags, memories, shared links, users, jobs and admin settings. It supports file uploads and downloads, stdio or streamable HTTP transports, and filtering/read-only safety modes.
    276
    76 npm
    MIT