lychee-mcp
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
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:httpnpm 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-mcpDo not put secrets in the image.
Regenerate the registry after a route bump.
npm run gen:operationsscripts/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 |
| Required. Origin only, |
| Required. The raw token. The client sends |
| Must be the literal |
| Comma list, or |
| Local request budget. Default 30. Cache hits do not spend it. |
| Upstream timeout. Default 20000. |
| Read cache TTL. Default 60. Writes clear the cache. |
| Contact token in the User-Agent. Must not contain the API token. |
|
|
| 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 |
| list, get, tree | yes |
photos |
| list, get | yes |
tags |
| list, get | yes |
search |
| init, search | yes |
sharing |
| list, list_all, list_albums | yes |
users |
| current, rights, list, count | yes |
settings |
| init, upload_limits, get, version | yes |
albums_write |
| create, rename, set_protection, delete, move | no |
sharing_write |
| create, edit, delete | no |
photos_write |
| import, upload, edit, rename, tags, move, copy, star, delete | no |
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 |
| 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.
This server cannot be deployed
Maintenance
Related MCP Connectors
Read-only MCP connector for Charmshots photoshoots, photo metadata and owner-authenticated links.
Read-only MCP server over the JENRIKS daily photoblog: one photo per day since 2006. No auth.
MCP server exposing the YourImageShare upload API (upload/list/delete) as tools for AI agents.
Browse, search, upload, tag, transfer, and delete images in your Raster libraries over MCP.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables 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.1AGPL 3.0
- FlicenseNot gradedqualityCmaintenanceEnables read-only access to a personal Google Photos library, allowing listing, searching, inspecting, and viewing photos and albums via MCP tools.-
- AlicenseNot gradedqualityBmaintenanceEnables 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
- AlicenseCqualityCmaintenanceIt 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.27676 npmMIT