lilygo-doc-mcp
OfficialClick on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@lilygo-doc-mcpwhat are the specs for the T-Display S3"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
lilygo-doc-mcp
English | 简体中文
MCP server for LILYGO product documentation. Exposes LILYGO hardware docs as structured tools for LLM clients via the Model Context Protocol.
Documentation is served from a local sparse git checkout of Xinyuan-LilyGO/documentation. No runtime GitHub API calls — zero rate limit issues. Docs can stay up to date automatically via a GitHub webhook.
Hosted service
The production service is available at these public endpoints:
Endpoint | Method | Description |
| MCP SSE connection endpoint used by MCP clients. | |
| Health endpoint returning | |
| GitHub push webhook used to update the documentation checkout. |
Connect an MCP client to the hosted service with:
{
"mcpServers": {
"lilygo-docs": {
"type": "sse",
"url": "https://mcp.lilygotech.com/sse"
}
}
}The SSE transport advertises a session-specific https://mcp.lilygotech.com/messages?sessionId=... endpoint automatically. MCP clients manage that endpoint; do not configure or call it manually.
The webhook URL is public but accepts GitHub POST requests only. Configure GITHUB_WEBHOOK_SECRET and use the same value in the GitHub webhook settings before exposing it; when the variable is empty, signature verification is skipped.
Related MCP server: Godot Docs MCP
Architecture
flowchart LR
CLIENT["MCP clients"]
MONITOR["Health monitoring"]
subgraph GITHUB["GitHub"]
APP_REPO["Xinyuan-LilyGO/lilygo-doc-mcp"]
ACTIONS["GitHub Actions<br/>test, build, and deploy"]
GHCR["GitHub Container Registry<br/>latest and sha-* images"]
DOCS_REPO["Xinyuan-LilyGO/documentation<br/>en/products"]
end
subgraph HOST["Production server"]
COMPOSE["Docker Compose<br/>application deployment"]
NPM["Nginx Proxy Manager<br/>mcp.lilygotech.com<br/>TLS, SSE proxying, and limits"]
subgraph CONTAINER["lilygo-doc-mcp container"]
MCP["Node.js MCP server"]
DOCS["Sparse documentation checkout<br/>vendor/docs/en/products"]
end
end
APP_REPO -->|"push to master"| ACTIONS
DOCS_REPO -->|"sparse clone during image build"| ACTIONS
ACTIONS -->|"build and publish"| GHCR
ACTIONS -->|"SSH: upload Compose files and restart"| COMPOSE
GHCR -->|"pull image"| COMPOSE
COMPOSE -->|"create or update"| MCP
CLIENT -->|"HTTPS: GET /sse, POST /messages"| NPM
MONITOR -->|"HTTPS: GET /health"| NPM
DOCS_REPO -->|"HTTPS: push event to POST /webhook"| NPM
NPM -->|"HTTP over npm_proxy"| MCP
MCP -->|"run update-docs.mjs"| DOCS
DOCS_REPO -->|"git pull --ff-only"| DOCS
DOCS -->|"reload product cache"| MCPGitHub Actions deploys the MCP application but does not deploy Nginx Proxy Manager; the production server must provide NPM and the external npm_proxy network. A valid push webhook returns 202 Accepted, then the server updates the sparse checkout and reloads its in-memory product cache asynchronously.
Quick start
1. Clone and install
git clone https://github.com/Xinyuan-LilyGO/lilygo-doc-mcp.git
cd lilygo-doc-mcp
npm install
npm run docs:init
npm run buildnpm run docs:init clones only the en/products documentation subtree into vendor/docs.
To point at another docs checkout, set DOCS_REPO_DIR before running the command:
DOCS_REPO_DIR=/path/to/documentation npm run docs:update2. Start the server
PORT=3000 npm start3. Connect your MCP client
{
"mcpServers": {
"lilygo-docs": {
"type": "sse",
"url": "http://localhost:3000/sse"
}
}
}Keeping docs up to date
Manual update
npm run docs:updateThen restart the server (or let the webhook do it automatically).
Automatic via GitHub webhook
Set up a webhook on the Xinyuan-LilyGO/documentation repository:
Go to Settings → Webhooks → Add webhook
Set Payload URL to
https://mcp.lilygotech.com/webhook(or the corresponding URL for a self-hosted domain)Set Content type to
application/jsonSet Secret to the exact value configured as
GITHUB_WEBHOOK_SECRETon the serverChoose Just the push event
Start the server with the webhook secret:
GITHUB_WEBHOOK_SECRET=your-secret PORT=3000 npm startDo not expose /webhook with an empty GITHUB_WEBHOOK_SECRET, because the server skips signature verification when no secret is configured.
On every push to the documentation repo, the server will:
Run
node scripts/update-docs.mjsReload the in-memory product cache. Product categories are discovered automatically.
Logging
The server logs MCP SSE connections, message requests, disconnections, and tool calls. Tool-call logs include the tool name and arguments, but not returned document content.
Follow logs from Docker with:
docker logs -f lilygo-doc-mcpTools
Tool | Description |
| List all products, filter by series / tags / keyword |
| Get full docs plus the programming guide, or a specific section (overview, quickstart, features, parameters, pins, faq) |
| Get the dedicated |
| Full-text search across product pages and programming guides with ranked excerpts |
| Extract structured specs: key features, parameter table, pin tables |
Environment variables
Variable | Default | Description |
|
| HTTP server port |
| (empty) | GitHub webhook secret for signature verification. If unset, signature check is skipped. |
|
| Path to local documentation directory |
|
| Path to the local documentation git checkout updated by |
|
| Documentation repository URL |
|
| Documentation repository branch |
|
| Sparse checkout path to serve |
Docker deployment
Both deployment methods require Docker Engine with the Docker Compose plugin. Clone this repository on the server before following either method.
Option 1: standalone deployment
Use this method for local-only access, direct LAN access, or when an external reverse proxy is not required. It uses only compose.yaml and creates a private Docker network automatically. It does not provide TLS termination.
Create the runtime configuration:
git clone https://github.com/Xinyuan-LilyGO/lilygo-doc-mcp.git
cd lilygo-doc-mcp
cp .env.example .envEdit .env before starting the service:
LILYGO_DOC_MCP_IMAGE=ghcr.io/xinyuan-lilygo/lilygo-doc-mcp:latest
LILYGO_DOC_MCP_BIND_ADDRESS=127.0.0.1
LILYGO_DOC_MCP_PORT=3000
GITHUB_WEBHOOK_SECRET=replace-with-a-random-secretKeep
LILYGO_DOC_MCP_BIND_ADDRESS=127.0.0.1when only software on the same server needs access.Set it to
0.0.0.0only when direct LAN access is intentional and the host firewall restricts access appropriately.Replace
GITHUB_WEBHOOK_SECRETwith a strong random value before exposing/webhook.
For example, generate a 32-byte hexadecimal secret and place the output in .env:
openssl rand -hex 32Pull and start the service:
docker compose pull
docker compose up -d --waitVerify the health endpoint and inspect the service state:
curl http://127.0.0.1:3000/health
docker compose ps
docker compose logs --tail=100 lilygo-doc-mcpTo update or stop a standalone deployment:
# Update
docker compose pull
docker compose up -d --remove-orphans --wait
# Stop and remove the container
docker compose downTo build the current checkout instead of pulling the published image:
docker compose -f compose.yaml -f compose.local.yaml up -d --build --waitOption 2: deployment with Nginx Proxy Manager
Use this method for the public https://mcp.lilygotech.com endpoint. Nginx Proxy Manager (NPM) remains a separate, server-level service, while compose.npm.yaml attaches this application to NPM's shared Docker network.
Create the shared network before starting either stack:
docker network inspect npm_proxy >/dev/null 2>&1 || docker network create npm_proxyNPM itself must also join this network. The persistent approach is to add the external network to the NPM Compose configuration and recreate the NPM service:
services:
app:
networks:
- default
- npm_proxy
networks:
npm_proxy:
external: true
name: npm_proxyThe NPM service is commonly named app; use its actual service name when it differs. Apply the NPM Compose change before deploying this application:
cd /opt/nginx-proxy-manager
docker compose up -dThen prepare this application's runtime configuration:
git clone https://github.com/Xinyuan-LilyGO/lilygo-doc-mcp.git
cd lilygo-doc-mcp
cp .env.example .envKeep LILYGO_DOC_MCP_BIND_ADDRESS=127.0.0.1, select the required host port in .env, and replace GITHUB_WEBHOOK_SECRET with a strong random value. Start the application with both Compose files:
docker compose -f compose.yaml -f compose.npm.yaml pull
docker compose -f compose.yaml -f compose.npm.yaml up -d --waitThe service joins both its private default network and the external npm_proxy network. NPM reaches it by container name and port, so the host loopback binding does not prevent proxy access.
Create an NPM Proxy Host with these forwarding settings:
Setting | Value |
Domain Names |
|
Scheme |
|
Forward Hostname / IP |
|
Forward Port |
|
Configure the SSL certificate and Force SSL in NPM. For reliable long-lived SSE connections, add the following to the Proxy Host's Advanced configuration:
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;The following global NPM configuration is recommended for limiting concurrent SSE connections and message request rates. Save it as data/nginx/custom/http.conf inside the NPM installation (for example, /opt/nginx-proxy-manager/data/nginx/custom/http.conf):
map "$host:$uri" $mcp_sse_ip_key {
default "";
"mcp.lilygotech.com:/sse" $binary_remote_addr;
}
map "$host:$uri" $mcp_sse_total_key {
default "";
"mcp.lilygotech.com:/sse" $host;
}
map "$host:$uri" $mcp_message_key {
default "";
"mcp.lilygotech.com:/messages" $binary_remote_addr;
}
limit_conn_zone $mcp_sse_ip_key zone=mcp_sse_ip:10m;
limit_conn_zone $mcp_sse_total_key zone=mcp_sse_total:10m;
limit_req_zone $mcp_message_key zone=mcp_messages:10m rate=600r/m;
limit_conn mcp_sse_ip 10;
limit_conn mcp_sse_total 500;
limit_req zone=mcp_messages burst=60 nodelay;
limit_conn_status 429;
limit_req_status 429;This configuration allows up to 10 concurrent /sse connections per client IP, 500 total /sse connections, and an average of 600 /messages requests per minute per client IP with a burst of 60. Requests for other hosts and paths use empty map keys and are not counted by these limits.
If a different domain is used, replace all three occurrences of mcp.lilygotech.com before loading the configuration. Validate and reload NPM after changing it:
cd /opt/nginx-proxy-manager
docker compose exec app nginx -t
docker compose restart appThe NPM Compose service is normally named app; adjust the command if the local service name is different.
Verify the public endpoint after NPM reloads:
curl https://mcp.lilygotech.com/health
docker compose -f compose.yaml -f compose.npm.yaml psTo update or stop this deployment, always specify both Compose files:
# Update
docker compose -f compose.yaml -f compose.npm.yaml pull
docker compose -f compose.yaml -f compose.npm.yaml up -d --remove-orphans --wait
# Stop and remove the application container
docker compose -f compose.yaml -f compose.npm.yaml downGitHub Actions deployment
The workflow in .github/workflows/deploy.yml runs tests for pull requests. A push to master runs the tests, publishes latest and sha-* images to GHCR, and deploys the latest image to the production server using Option 2, including compose.npm.yaml. It can also be started manually with Run workflow; select the master branch to run the publish and deploy jobs.
GitHub environment configuration
Create an Environment named production under Settings > Environments > New environment, then configure these Environment secrets:
Secret | Required | Description |
| Yes | Production server hostname or IP address, without a URL scheme. |
| Yes | SSH user used for deployment. |
| Yes | Complete, passphrase-free OpenSSH private key dedicated to deployment. Install its public key in the deployment user's |
| Yes | Trusted |
Configure these Environment variables when the defaults are not suitable:
Variable | Required | Default | Description |
| No |
| Production server SSH port. |
| No |
| Directory receiving the deployment files and persistent |
GITHUB_TOKEN is created automatically by GitHub Actions and is used to publish the container image. Do not add a separate secret for it. The workflow has only the contents: read and packages: write permissions required for this operation.
Generate DEPLOY_KNOWN_HOSTS from a trusted machine, then verify the server fingerprint before saving the output as a GitHub secret:
ssh-keyscan -p 22 -H your-server.example.comUse the configured DEPLOY_PORT instead of 22 when SSH listens on a different port.
Production server requirements
Before the first Actions deployment, verify that:
Docker Engine and the Docker Compose plugin are installed.
DEPLOY_USERcan rundockerwithout an interactive password prompt.DEPLOY_USERcan create and write toDEPLOY_PATH. Pre-create the directory when the user cannot write to its parent directory.The GHCR package is public, or the server has already authenticated to
ghcr.iowith permission to pull it.Nginx Proxy Manager is attached to the external Docker network named
npm_proxyand has the Proxy Host configuration described above.DNS for
mcp.lilygotech.compoints to the production server and inbound ports80and443are available to NPM.
The first deployment creates DEPLOY_PATH/.env and generates GITHUB_WEBHOOK_SECRET. Later deployments preserve this file. To change runtime settings such as the published port, image, or webhook secret, edit the server-side .env:
cd /opt/lilygo-doc-mcp
vi .env
docker compose -f compose.yaml -f compose.npm.yaml up -d --remove-orphans --waitWhen DEPLOY_PATH is customized, use that path instead. For a fork or renamed repository, set LILYGO_DOC_MCP_IMAGE in the server-side .env to the image published by that repository, for example ghcr.io/owner/lilygo-doc-mcp:latest.
License
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides tools to search and retrieve Google Gemini API documentation with full-text search capabilities and automatic documentation updates stored in a local SQLite database.Last updated3101MIT
- Alicense-qualityCmaintenanceEnables searching and retrieving Godot Engine documentation across multiple versions (stable, latest, 4.3-4.5) using fuzzy search, returning documentation content as markdown.Last updated25MIT
- Flicense-qualityDmaintenanceEnables AI models to access GitHub repository information and search local documentation files. Provides three basic tools: fetching repository details, retrieving file contents from GitHub, and searching through local markdown documentation.Last updated
- AlicenseAqualityCmaintenanceEnables AI assistants to search, list, and retrieve documentation from the Slice.js official GitHub repository. It provides full-text search capabilities and can deliver individual doc pages or a complete documentation bundle for comprehensive LLM context.Last updated4395MIT
Related MCP Connectors
@latest documentation and code examples to 9000+ libraries for LLMs and AI code editors in a singl…
Search and read the StitchAPI docs: search_docs finds relevant sections, get_doc reads a page.
Get up-to-date, version-specific documentation and code examples from official sources directly in…
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Xinyuan-LilyGO/lilygo-doc-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server