{"id":51229651,"url":"https://github.com/imateo/fastpanel-mcp","last_synced_at":"2026-06-28T15:01:06.537Z","repository":{"id":362766120,"uuid":"1217371264","full_name":"iMateo/fastpanel-mcp","owner":"iMateo","description":"MCP server for FastPanel 2 — manage sites, databases, SSL, nginx configs from Claude/Cursor via natural language","archived":false,"fork":false,"pushed_at":"2026-06-05T19:34:45.000Z","size":65,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-05T21:11:40.453Z","etag":null,"topics":["anthropic","automation","claude","claude-code","devops","fastpanel","hosting","lets-encrypt","llm-tools","mcp","mcp-server","model-context-protocol","nginx","server-management","sysadmin","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iMateo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-21T20:23:04.000Z","updated_at":"2026-06-05T19:34:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/iMateo/fastpanel-mcp","commit_stats":null,"previous_names":["imateo/fastpanel-mcp"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/iMateo/fastpanel-mcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iMateo%2Ffastpanel-mcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iMateo%2Ffastpanel-mcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iMateo%2Ffastpanel-mcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iMateo%2Ffastpanel-mcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iMateo","download_url":"https://codeload.github.com/iMateo/fastpanel-mcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iMateo%2Ffastpanel-mcp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34892547,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-28T02:00:05.809Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anthropic","automation","claude","claude-code","devops","fastpanel","hosting","lets-encrypt","llm-tools","mcp","mcp-server","model-context-protocol","nginx","server-management","sysadmin","typescript"],"created_at":"2026-06-28T15:01:05.656Z","updated_at":"2026-06-28T15:01:06.524Z","avatar_url":"https://github.com/iMateo.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fastpanel-mcp\n\n\u003e Talk to your [FastPanel 2](https://fastpanel.direct/) server from Claude, Cursor, or any MCP-compatible client. Create sites, provision databases, attach SSL, harden nginx configs — through natural language, with production-grade safety rails.\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)\n[![Node](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](https://nodejs.org/)\n[![MCP](https://img.shields.io/badge/MCP-compatible-blue.svg)](https://modelcontextprotocol.io/)\n[![Version](https://img.shields.io/badge/version-1.1.0-blue.svg)](./CHANGELOG.md)\n\n**Keywords:** FastPanel, MCP, Model Context Protocol, Claude Code, Claude Desktop, server management, hosting automation, nginx, Let's Encrypt, DevOps, LLM ops, AI sysadmin.\n\n---\n\n## What you get\n\nAsk an LLM, get real infra changes on your FastPanel server:\n\n\u003e **You:** \"Create a new site `foo.example.com` under user `www-root`, PHP 8.4, no database, and attach our wildcard SSL cert. Also enable HTTP/2 and HTTP/3.\"\n\u003e\n\u003e **LLM (~30 seconds, 5 tool calls later):** Site id 53 is live at https://foo.example.com with HTTP/2, HTTP/3, wildcard TLS, and an auto-provisioned HTTPS redirect.\n\n\u003e **You:** \"Show me the nginx config for site 1 — check if it blocks `.env`, `.git`, and other sensitive paths. If not, add hardening.\"\n\u003e\n\u003e **LLM:** Reads the config, notes that `.env` and `.htaccess` are served as static files (security gap), edits the frontend to add deny rules for dotfiles + sensitive extensions + framework files, previews the diff via `dry_run`, then deploys it. `.env` now returns 404; `.well-known/acme-challenge` still works.\n\n\u003e **You:** \"What sites are running on this server, who owns them, and which ones don't force HTTPS?\"\n\u003e\n\u003e **LLM:** Queries `sites_list` and reports the 5 sites without `https_redirect: true`.\n\n## Features\n\n- **32 tools** covering sites, databases (incl. SSH dump/import), users, DNS zones, SSL certificates, system load, queue, site logs, backup plans, host-level diagnostics, file upload/deploy into a site's web root, and raw nginx/apache/php.ini configs.\n- **Dual-token safety model.** Read operations use a read-only token; mutating operations require a separate write token (`FASTPANEL_WRITE_TOKEN`). Unset the write token and every write tool fails closed.\n- **`confirm: true` required** on every write. Accidental LLM outputs cannot mutate state.\n- **`dry_run: true` previews** the exact HTTP body the server would receive — passwords redacted as `***`, no network call fired.\n- **Compact response mode** on sites_list to avoid overflowing LLM context on large panels.\n- **stderr audit log** for every executed write, with passwords redacted.\n- **Tested against a live FastPanel 2 panel** with 38 sites in production.\n\n## Why this exists\n\nFastPanel publishes no OpenAPI spec. The endpoints and payload shapes in this server were reverse-engineered from the panel's Angular SPA bundle and live DevTools captures, including non-obvious quirks like:\n\n- List endpoints require `filter[limit]=…\u0026filter[type]=…` wrapped params — bare `?limit=…` is silently ignored.\n- Site creation is a two-step wizard (`POST /api/master/domain` probe → `PUT /api/master`), not a conventional `POST /api/sites`.\n- The `backend` field in site configuration is PHP-FPM pool config when `handler=php_fpm`, but an Apache VirtualHost block when `handler=fcgi`.\n- SSL attach/detach flows through `PUT /api/sites/{id}` (site-side) not `POST /api/sites/{id}/certificate` (there is no such endpoint).\n\nThese are documented in the tool descriptions so the LLM doesn't have to rediscover them.\n\n## Requirements\n\n- Node.js 20 or newer\n- A FastPanel 2 installation reachable over HTTPS\n- Root SSH on the panel host to create API tokens (one-time)\n\n## Install\n\n```bash\ngit clone https://github.com/iMateo/fastpanel-mcp.git\ncd fastpanel-mcp\npnpm install      # or: npm install\npnpm build\n```\n\n## Get API tokens\n\nOn the FastPanel host, create a read-only token for day-to-day use:\n\n```bash\nfastpanel users tokens add -n mcp-read -s read_only -e 2026-12-31\n```\n\nCopy the `msg` field from the returned JSON — that's your token. It bypasses 2FA and survives session TTLs, so treat it as a server credential.\n\nOptional write token, with short expiry and IP lock:\n\n```bash\nfastpanel users tokens add -n mcp-write -c \u003cyour-ip\u003e -e 2026-05-31\n```\n\nLeave `FASTPANEL_WRITE_TOKEN` unset in configs where you don't need writes.\n\n## Configure\n\n```bash\ncp .env.example .env\n```\n\nMinimum viable `.env`:\n\n```\nFASTPANEL_URL=https://panel.example.com:8888\nFASTPANEL_TOKEN=\u003cyour read token\u003e\nFASTPANEL_INSECURE_TLS=1   # only if panel uses self-signed cert\n```\n\n## Use with Claude Code\n\n```bash\nclaude mcp add fastpanel \\\n  -s user \\\n  -e \"FASTPANEL_URL=https://panel.example.com:8888\" \\\n  -e \"FASTPANEL_TOKEN=…\" \\\n  -e \"FASTPANEL_INSECURE_TLS=1\" \\\n  -- node $PWD/dist/index.js\n```\n\nAdd `-e \"FASTPANEL_WRITE_TOKEN=…\"` when you want write tools enabled.\n\n## Use with Claude Desktop / Cursor / other MCP clients\n\n`claude_desktop_config.json` (or equivalent):\n\n```json\n{\n  \"mcpServers\": {\n    \"fastpanel\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/fastpanel-mcp/dist/index.js\"],\n      \"env\": {\n        \"FASTPANEL_URL\": \"https://panel.example.com:8888\",\n        \"FASTPANEL_TOKEN\": \"…\",\n        \"FASTPANEL_INSECURE_TLS\": \"1\"\n      }\n    }\n  }\n}\n```\n\n## Debug\n\nInspect tools with the MCP Inspector GUI:\n\n```bash\npnpm inspect\n```\n\nDrive JSON-RPC over stdio manually:\n\n```bash\nFASTPANEL_URL=… FASTPANEL_TOKEN=… node scripts/smoke.mjs\n```\n\n## Tools\n\n### Read (no write token required)\n\n| Tool | Endpoint | Returns |\n|---|---|---|\n| `sites_list` | `GET /api/sites/list` | All websites, 13 essential fields by default (compact mode) |\n| `site_get` | `GET /api/sites/{id}` | Full 40-field site object (cert, backend, backups, stats) |\n| `site_configuration_get` | `GET /api/sites/{id}/configuration` | Raw nginx (frontend), handler backend (PHP-FPM or Apache), php.ini |\n| `databases_list` | `GET /api/databases` | MySQL + PostgreSQL databases with owners and sizes |\n| `database_servers_list` | `GET /api/databases/servers` | Available DB servers — use ids in `database_create` |\n| `users_list` | `GET /api/users` | Panel users and site owners |\n| `dns_domains_list` | `GET /api/dns/domains` | DNS zones (empty if panel DNS is off) |\n| `dns_records_list` | `GET /api/dns/domain/{id}/records` | Records for one zone |\n| `certificates_list` | `GET /api/certificates` | Stored SSL certificates (LE + custom) |\n| `system_load` | `GET /api/loads/full` | CPU / memory / disk / load averages / top processes |\n| `queue_list` | `GET /api/queue/list` | Background tasks including completed |\n| `queue_active` | `GET /api/queue` | In-flight tasks only (filters finished) + `meta.all_done` for deterministic polling |\n| `site_logs` | `GET /api/sites/{id}/log/{lines}/{type}` | Tail nginx/apache access or error log (frontend_/backend_) without SSH |\n| `site_resources` | `GET /api/sites/{id}/resources` | Databases, sub-domains, DNS \u0026 email zones attached to a site |\n| `backup_plans_list` | `GET /api/v2/backup/plans` | Configured backup plans |\n| `me` | `GET /api/me` | Account behind the current read token (username, roles, ssh) |\n| `settings_get` | `GET /api/settings` | Panel-wide settings (OS, license, limits, notifications) |\n\n### Write (require `FASTPANEL_WRITE_TOKEN` + explicit `confirm: true`)\n\n| Tool | Endpoint | Purpose |\n|---|---|---|\n| `user_create` | `POST /api/users` | Create a new panel user (site owner) |\n| `database_create` | `POST /api/databases` | Create MySQL or PostgreSQL database with a dedicated DB user |\n| `site_create` | `POST /api/master/domain` + `PUT /api/master` | Create a site atomically, optionally with inline user / database / FTP |\n| `site_update` | `PUT /api/sites/{id}` | Change document root (`index_dir`) / directory index — e.g. point a Laravel site at `public/` (`framework: \"laravel\"` preset) |\n| `site_ssl_update` | `PUT /api/sites/{id}` | Attach / replace / detach an SSL certificate, toggle HTTPS / HTTP2 / HTTP3 / HSTS |\n| `site_backend_update` | `PUT /api/sites/backend/{backend_id}` | Change PHP version, handler, port, socket, env vars (pass site id — backend id resolved internally) |\n| `site_configuration_update` | `PUT /api/sites/{id}/configuration` | Replace raw nginx/apache/php.ini for the site. **Dangerous**: bad syntax can break the site |\n| `certificate_create_letsencrypt` | `POST /api/certificates` | Issue a new Let's Encrypt certificate (async — poll `queue_active`) |\n\n### SSH-backed (require `FASTPANEL_SSH_HOST`)\n\nThese do what the REST API can't — they run on the panel host itself. Opt-in and host-agnostic: set `FASTPANEL_SSH_HOST` (+ optional `FASTPANEL_SSH_USER`/`PORT`/`KEY`) to point at **any** FastPanel server. The server shells out to your own `ssh` client, so the host just needs to be reachable with key-based auth. `nginx_validate` and `site_doctor` are read-only; the rest are writes (`confirm: true` + `dry_run` preview).\n\n| Tool | Runs | Purpose |\n|---|---|---|\n| `nginx_validate` | `nginx -t` | Validate the live nginx config before/after `site_configuration_update` — catch syntax errors before they take nginx down |\n| `site_doctor` | `stat` / `systemctl` / `nginx -t` | Diagnose why a site errors: missing docroot, a parent dir without `o+x` (the 750 → 404 trap), missing FPM socket, dead backend, broken nginx config |\n| `database_dump` | `mysqldump` | Dump a database to a `.sql` file in the staging dir (local MySQL). Writes a root-owned file — needs `confirm: true` |\n| `database_import` | `mysql` | Load a `.sql` file (from the staging dir) into a database. **Destructive** — needs `confirm: true` |\n| `site_files_upload` | `rsync` (scp fallback) | Upload a local file/dir into a site's web root, then chown to the site user. `delete: true` mirrors (removes remote-only files) |\n| `site_files_deploy` | `git clone` / `curl` + `tar` | Fetch files on the host (https git repo or tarball) into a site's web root, then chown to the site user |\n| `site_file_put` | `cat` over ssh | Write one small inline file (placeholder/.htaccess/robots.txt) into a site's web root, then chown to the site user |\n\nDump/import paths are confined to a staging dir (default `/root/fastpanel-mcp-dumps`, override with `FASTPANEL_DUMP_DIR`); paths outside it or containing `..` are rejected. The three upload/deploy tools resolve the site's `index_dir` + owner via `site_get`, refuse destination subpaths that escape the web root or contain shell-unsafe characters, and `chown` everything to the site's system user so nginx/PHP-FPM can serve it (root-owned files would 403).\n\n## Cookbook\n\n**Provision a new test site under a wildcard cert (30 seconds, no DNS/LE wait):**\n\n```\nsite_create(domain=\"foo.example.com\", owner_id=2, php_version=\"84\")\n  → site_ssl_update(site_id=\u003cnew\u003e, certificate_id=\u003cwildcard\u003e, https_redirect=true, http2=true, http3=true)\n```\n\n**Provision a production site with a fresh Let's Encrypt cert:**\n\n```\nsite_create(domain=\"foo.com\", aliases=[\"www.foo.com\"], owner_id=\u003cid\u003e, php_version=\"84\", database={...})\n  → certificate_create_letsencrypt(site_id=\u003cnew\u003e, email, common_name=\"foo.com\")\n  → queue_active  # poll until LE job SUCCESS\n```\n\n**Harden default nginx (block `.git`, `.env`, `.htaccess`, composer.json, etc.):**\n\n```\nsite_configuration_get(site_id)\n  # LLM inserts security location blocks into frontend\nsite_configuration_update(site_id, frontend=\u003cedited\u003e, backend=\u003cunchanged\u003e, phpini=\u003cunchanged\u003e)\n```\n\n**Remove deprecated TLS versions:**\n\n```\nsite_configuration_get(site_id)\n  # LLM replaces \"ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3\" with \"ssl_protocols TLSv1.2 TLSv1.3\"\nsite_configuration_update(site_id, frontend=\u003cedited\u003e, backend=\u003cunchanged\u003e, phpini=\u003cunchanged\u003e)\n```\n\n## Safety model\n\n- **Dual tokens.** Read token always required. Write token is optional — if `FASTPANEL_WRITE_TOKEN` isn't set, every write tool errors out before touching the network with `FastPanelWriteDisabledError`.\n- **`confirm: true`** is a required argument on every write tool. Tools refuse to execute without it — this is your last line of defence against a confused LLM.\n- **`dry_run: true`** returns the exact JSON body that would be sent, passwords redacted as `***`, and skips the HTTP call entirely.\n- **stderr audit log** records every executed write with redacted payload. In Claude Code this surfaces in MCP logs.\n- **No delete tools** yet. Destructive operations are left to the UI until they're deliberately added.\n- **IP-lock tokens** (`fastpanel users tokens add -c \u003cip\u003e`) so a leaked token can't be used from elsewhere.\n\n## Known gotchas\n\n- **`filter[...]` params:** FastPanel list endpoints expect `filter[limit]=…\u0026filter[type]=…`. Bare `?limit=…` is silently ignored.\n- **Site creation is a wizard, not a REST create.** The panel does `POST /api/master/domain` (probe) then `PUT /api/master` (actual create), not `POST /api/sites`. `site_create` hides this.\n- **Async operations.** Cert issuance, site backend updates, and several other ops return `action: \"CREATING\"` / `\"UPDATING\"` immediately and run in the background. Use `queue_active` to poll.\n- **No official OpenAPI spec.** Endpoints were reverse-engineered. If a new FastPanel release breaks something, please file an issue with the new payload shape.\n- **Self-signed TLS.** Most panel installs use self-signed certs. Set `FASTPANEL_INSECURE_TLS=1` or put a proper cert in front.\n- **fail2ban / rate limiting.** FastPanel ships with fail2ban and panel-level rate limiting. Test scripts that hammer the API may get your IP blocked.\n\n## Roadmap\n\n- Delete tools (`user_delete`, `site_delete`, `database_delete`, `certificate_delete`)\n- DNS record CRUD\n- Backup plan management (list / run / restore)\n- Email domain + mailbox management\n- Bulk operations (e.g. \"apply this nginx hardening to every site\")\n- CLI-fallback tools over SSH for ops not in REST (`transfer`, `firewall save/restore`, `panel ip_match`)\n- Structured MCP `outputSchema` so clients can render typed results\n- Rate-limit aware retry with exponential backoff\n\n## Contributing\n\nIssues and PRs welcome. Especially useful:\n\n- Captured DevTools Network payloads for actions not yet covered\n- Compatibility fixes for newer FastPanel versions\n- Additional DB servers / runtime types in the enum schemas\n- Screenshots / recordings of typical flows for the README\n\n## Author\n\nBuilt and maintained by **Ihor Chyshkala** — [chyshkala.com](https://chyshkala.com) · [ihor@chyshkala.com](mailto:ihor@chyshkala.com).\n\n### Services\n\nAvailable for hire via [chyshkala.com](https://chyshkala.com):\n\n| Service | What it covers |\n|---|---|\n| **Web Development** | Full-stack web apps with React, Next.js \u0026 Node.js |\n| **Process Automation** | Workflows, integrations \u0026 data pipelines |\n| **API Development** | REST, GraphQL \u0026 third-party integrations |\n| **AI Integration** | ChatGPT, Claude \u0026 custom AI solutions |\n| **AI Chatbot** _(new)_ | Custom chatbots trained on your data |\n| **DevOps** | CI/CD, Docker \u0026 cloud infrastructure |\n| **CTO-as-a-Service** | Technical leadership for startups |\n| **Due Diligence** | Technical audits for investors |\n| **Legacy Modernization** | Migrate from legacy to modern stack |\n\n## License\n\nMIT — see [LICENSE](./LICENSE).\n\n## Disclaimer\n\nThis is a third-party, community project. \"FastPanel\" is a trademark of its respective owners. This project is not affiliated with, endorsed by, or sponsored by FastPanel. Test against a non-production FastPanel instance before pointing it at anything you care about.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimateo%2Ffastpanel-mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fimateo%2Ffastpanel-mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimateo%2Ffastpanel-mcp/lists"}