{"id":51702374,"url":"https://github.com/reaatech/funcdock","last_synced_at":"2026-07-16T12:31:01.436Z","repository":{"id":302160076,"uuid":"1011438083","full_name":"reaatech/funcdock","owner":"reaatech","description":"Self-hosted Node.js FaaS platform — run dozens of functions in a single container with zero cold starts, hot reload, and automatic MCP tool exposure for AI agents. Built-in React dashboard, OpenTelemetry tracing, TypeScript native, shared layers, cron scheduling, and CI/CD deployments.","archived":false,"fork":false,"pushed_at":"2026-06-29T02:58:01.000Z","size":18726,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-29T04:18:25.995Z","etag":null,"topics":["ai-agents","cicd","cron-jobs","dashboard","developer-tools","devops","docker","express","faas","functions-as-a-service","hot-reload","llm-tools","mcp","microservices","model-context-protocol","nodejs","opentelemetry","self-hosted","serverless"],"latest_commit_sha":null,"homepage":"https://reaatech.com/products/deployment-runtime/funcdock","language":"JavaScript","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/reaatech.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/SECURITY_README.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-06-30T20:20:34.000Z","updated_at":"2026-06-29T02:58:05.000Z","dependencies_parsed_at":"2025-06-30T22:44:13.278Z","dependency_job_id":"3e1bc2e0-7b5c-407d-8b6a-888255c99da0","html_url":"https://github.com/reaatech/funcdock","commit_stats":null,"previous_names":["reaatech/funcdock"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/reaatech/funcdock","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reaatech%2Ffuncdock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reaatech%2Ffuncdock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reaatech%2Ffuncdock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reaatech%2Ffuncdock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reaatech","download_url":"https://codeload.github.com/reaatech/funcdock/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reaatech%2Ffuncdock/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35544514,"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-07-16T02:00:06.687Z","response_time":83,"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":["ai-agents","cicd","cron-jobs","dashboard","developer-tools","devops","docker","express","faas","functions-as-a-service","hot-reload","llm-tools","mcp","microservices","model-context-protocol","nodejs","opentelemetry","self-hosted","serverless"],"created_at":"2026-07-16T12:31:00.690Z","updated_at":"2026-07-16T12:31:01.426Z","avatar_url":"https://github.com/reaatech.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FuncDock\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eServerless Functions + MCP Tools in a Single Container\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/reaatech/funcdock/releases\"\u003e\u003cimg src=\"https://img.shields.io/badge/version-2.0.0-blue\" alt=\"Version 2.0.0\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/node-%3E%3D22.0.0-339933?logo=nodedotjs\" alt=\"Node.js 22+\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker\" alt=\"Docker\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/ESM-only-FFCA28\" alt=\"ESM Only\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Run dozens of Node.js functions with \u003cstrong\u003ezero cold starts\u003c/strong\u003e, \u003cstrong\u003ehot reload\u003c/strong\u003e, and \u003cstrong\u003eautomatic MCP tool exposure\u003c/strong\u003e.\n\u003c/p\u003e\n\n---\n\n## What is FuncDock?\n\nFuncDock is a self-hosted Function-as-a-Service (FaaS) platform that runs multiple Node.js functions inside a single Docker container. It gives you the ergonomics of serverless — per-function routing, environment isolation, and independent deployments — without the cold starts, vendor lock-in, or per-request billing of cloud functions.\n\nEvery function route is automatically exposed as an [MCP (Model Context Protocol)](https://modelcontextprotocol.io) tool, making FuncDock an ideal backend for AI agents and LLM-powered applications.\n\nBuilt for teams who want:\n\n- **Predictable infrastructure** — one container, many functions, no orchestration magic\n- **Developer velocity** — file-watch hot reload, TypeScript without a build step, a built-in React dashboard\n- **AI-ready APIs** — your functions become MCP tools that any compatible client can discover and invoke\n- **Observability out of the box** — OpenTelemetry tracing, structured logs, per-function metrics, and Slack alerts\n\n---\n\n## Features\n\n|     | Feature               | Description                                                                                  |\n| --- | --------------------- | -------------------------------------------------------------------------------------------- |\n| ⚡  | **Zero Cold Starts**  | All functions run in one Node.js process. No container spin-up, no latency spikes.           |\n| 🔥  | **Hot Reload**        | Edit a file. Save. The function reloads in milliseconds. No server restart.                  |\n| 🤖  | **MCP Server**        | Every route auto-exposes as an MCP tool. LLMs can discover and call your functions natively. |\n| 📊  | **React Dashboard**   | Real-time function monitoring, logs, metrics, env editing, and deployment UI.                |\n| 🧪  | **Built-in Testing**  | Jest with ESM support. Test locally or in a production-identical Docker container.           |\n| 🔐  | **Security First**    | httpOnly cookies, rate limiting, Helmet, input validation, and token blacklisting.           |\n| 📦  | **Shared Layers**     | Lambda-style code sharing. One symlinked layer, many functions. Change once, reload all.     |\n| 📝  | **TypeScript Native** | Write `.ts` handlers. `tsx` compiles on the fly. No build step required.                     |\n| 🔍  | **OpenTelemetry**     | Distributed tracing with automatic span wrapping on every function invocation.               |\n| 🚀  | **Multi-deployment**  | Deploy from Git, local path, dashboard upload, PR, or CI/CD with an API key.                 |\n\n---\n\n## Quick Start\n\n### 1. Clone \u0026 Configure\n\n```bash\ngit clone https://github.com/reaatech/funcdock.git\ncd funcdock\ncp .env.example .env\n# Edit .env and set JWT_SECRET, ADMIN_USERNAME, and ADMIN_PASSWORD\n```\n\n### 2. Install \u0026 Start\n\n```bash\nnpm install\nnpm run dev\n```\n\nThe dev server starts on `http://localhost:3000` with file watching enabled.\n\n### 3. Create a Function\n\n```bash\nnpx funcdock create my-api\n```\n\nThis scaffolds:\n\n```\nfunctions/my-api/\n├── handler.js\n├── handler.test.mjs\n├── route.config.json\n├── package.json\n└── README.md\n```\n\n### 4. Test It\n\n```bash\ncurl http://localhost:3000/my-api/\n# → { \"message\": \"Hello from my-api!\" }\n```\n\n### 5. Open the Dashboard\n\nVisit `http://localhost:3000/dashboard`, log in with your admin credentials, and manage functions in real time.\n\n---\n\n## Architecture\n\nFuncDock avoids Express router stack bloat by using a **custom Map-based dispatcher**. Instead of registering routes with `app.use()` (which leaks middleware on every hot reload), a single middleware looks up handlers in a `Map` keyed by `\"METHOD /path\"`.\n\n```\nHTTP Request\n    │\n    ▼\nExpress middleware (helmet, cors, json)\n    │\n    ▼\nfunctionDispatcherMiddleware ──→ Map lookup: \"GET /my-api/\"\n    │                              Inject: logger, env, functionName\n    ▼                           Wrap in OpenTelemetry span\nHandler executes\n    │\n    ▼\nResponse + structured access log\n```\n\nThis gives **O(1) route lookup** and **zero Express stack pollution** across unlimited reloads.\n\nFor the full design doc, see [`ARCHITECTURE.md`](ARCHITECTURE.md).\n\n---\n\n## Function Development\n\n### Handler Pattern\n\nFunctions are plain ES modules that export a default async handler:\n\n```javascript\n// functions/my-api/handler.js\nexport default async function handler(req, res) {\n  const { logger, env, method, query, body } = req;\n\n  logger.info(`Received ${method}`, { query });\n\n  res.json({\n    message: 'Hello from my-api',\n    envHasKey: !!env.API_KEY,\n  });\n}\n```\n\n### Route Configuration\n\n```json\n// functions/my-api/route.config.json\n{\n  \"base\": \"/my-api\",\n  \"handler\": \"handler.js\",\n  \"routes\": [\n    { \"path\": \"/\", \"methods\": [\"GET\", \"POST\"] },\n    { \"path\": \"/:id\", \"methods\": [\"GET\", \"PUT\", \"DELETE\"] }\n  ]\n}\n```\n\n### Environment Variables\n\nAdd a `.env` file inside your function directory:\n\n```bash\n# functions/my-api/.env\nAPI_KEY=sk-123456\nDATABASE_URL=postgres://localhost/mydb\n```\n\nAccess them via `req.env` in your handler.\n\n### Cron Jobs\n\n```json\n// functions/my-api/cron.json\n{\n  \"jobs\": [\n    {\n      \"name\": \"daily-report\",\n      \"schedule\": \"0 9 * * *\",\n      \"handler\": \"cron-handler.js\",\n      \"description\": \"Generate daily report at 9am\"\n    }\n  ]\n}\n```\n\n### Shared Layers\n\nCreate a layer in `layers/shared-utils/` with a `nodejs/` directory. Reference it from your function:\n\n```json\n// functions/my-api/layers.json\n\"shared-utils\"\n```\n\nThe layer is symlinked into `node_modules/shared-utils` automatically.\n\n### TypeScript\n\nWrite `.ts` handlers directly. No build step.\n\n```typescript\n// functions/my-api/handler.ts\nimport type { Request, Response } from 'express';\n\nexport default async function handler(req: Request, res: Response) {\n  res.json({ ok: true });\n}\n```\n\n---\n\n## MCP Server\n\nFuncDock ships with a built-in MCP server that exposes **every loaded function route as an MCP tool**.\n\n- **Enable it:** `MCP_ENABLED=true` (default)\n- **HTTP transport:** port `3001` (configurable via `MCP_HTTP_PORT`)\n- **Stdio transport:** supported for local MCP clients\n- **Tool naming:** `{functionName}__{route_path}__{method}`\n\nExample tool name: `hello-world__greet__get`\n\n### Securing MCP HTTP\n\nBy default, MCP HTTP binds to `127.0.0.1` only. To expose externally, set `MCP_API_KEY`:\n\n```bash\nMCP_HTTP_HOST=0.0.0.0\nMCP_API_KEY=your-strong-random-key\n```\n\nClients must send `Authorization: Bearer \u003cMCP_API_KEY\u003e`.\n\n---\n\n## Dashboard\n\nThe React 19 + Vite dashboard provides real-time management:\n\n- **Functions** — list, status, route counts, layer associations\n- **Logs** — per-function structured logs with filtering\n- **Metrics** — invocation counts, error rates, response times\n- **Deploy** — upload files, connect GitHub/Bitbucket repos, deploy from PRs\n- **Cron Jobs** — view schedules, last run status\n- **MCP Status** — connected transports, exposed tools\n- **Settings** — dark/light mode, environment editor\n\nReal-time updates are pushed via Socket.IO. Screenshots are in [`screenshots/`](screenshots/).\n\n---\n\n## CLI Reference\n\nThe `funcdock` CLI replaces Makefile-driven workflows:\n\n| Command                                        | Description                              |\n| ---------------------------------------------- | ---------------------------------------- |\n| `funcdock dev`                                 | Start development server with hot reload |\n| `funcdock start`                               | Start production server                  |\n| `funcdock create \u003cname\u003e`                       | Scaffold a new function                  |\n| `funcdock deploy --git \u003curl\u003e --name \u003cname\u003e`    | Deploy from Git                          |\n| `funcdock deploy --local \u003cpath\u003e --name \u003cname\u003e` | Deploy from local path                   |\n| `funcdock update \u003cname\u003e`                       | Update an existing function              |\n| `funcdock remove \u003cname\u003e`                       | Remove a function                        |\n| `funcdock list`                                | List all deployed functions              |\n| `funcdock test [function]`                     | Run Jest tests                           |\n| `funcdock logs`                                | View application logs                    |\n| `funcdock status`                              | Check platform health                    |\n| `funcdock reload`                              | Hot reload all functions                 |\n\nEvery command supports `--help`. See [`docs/CLI_README.md`](docs/CLI_README.md) for full details.\n\n---\n\n## Docker\n\n### Development\n\n```bash\ndocker-compose up\n```\n\nMounts `functions/` and `logs/` as volumes. Redis is bundled inside the container.\n\n### Production\n\n```bash\ndocker-compose --profile production up --build -d\n```\n\nIncludes a Caddy reverse proxy with automatic HTTPS.\n\n### Manual\n\n```bash\ndocker build -t funcdock .\ndocker run -p 3000:3000 -v $(pwd)/functions:/app/functions funcdock\n```\n\nThe image is based on `node:22-slim` and includes Git and Redis.\n\n---\n\n## Configuration\n\n### Required\n\n| Variable         | Description                                 |\n| ---------------- | ------------------------------------------- |\n| `JWT_SECRET`     | Min 16 chars. Used to sign session tokens.  |\n| `ADMIN_USERNAME` | Dashboard login username.                   |\n| `ADMIN_PASSWORD` | Min 8 chars. Hashed with bcrypt at startup. |\n\n### Optional\n\n| Variable                         | Default             | Description                                  |\n| -------------------------------- | ------------------- | -------------------------------------------- |\n| `PORT`                           | `3000`              | HTTP server port.                            |\n| `NODE_ENV`                       | `development`       | `development` or `production`.               |\n| `LOG_LEVEL`                      | `info`              | `debug`, `info`, `warn`, `error`, `alert`.   |\n| `MCP_ENABLED`                    | `true`              | Start the MCP server.                        |\n| `MCP_HTTP_PORT`                  | `3001`              | MCP HTTP transport port.                     |\n| `MCP_HTTP_HOST`                  | `127.0.0.1`         | Bind address for MCP HTTP.                   |\n| `MCP_API_KEY`                    | —                   | Bearer token required if exposed externally. |\n| `DEPLOY_API_KEY`                 | —                   | CI/CD key that bypasses JWT auth.            |\n| `GITHUB_CLIENT_ID` / `SECRET`    | —                   | OAuth for GitHub repo integration.           |\n| `BITBUCKET_CLIENT_ID` / `SECRET` | —                   | OAuth for Bitbucket repo integration.        |\n| `SLACK_WEBHOOK_URL`              | —                   | Alert notifications channel.                 |\n| `OTEL_EXPORTER_OTLP_ENDPOINT`    | —                   | OpenTelemetry collector URL.                 |\n| `CORS_ORIGIN`                    | `*`                 | Comma-separated allowed origins.             |\n| `REDIS_PASSWORD`                 | `funcdock_internal` | Redis auth (Docker).                         |\n\nSee [`.env.example`](.env.example) for the full template.\n\n---\n\n## Testing\n\n```bash\n# All tests\nnpm test\n\n# With coverage\nnpm run test:coverage\n\n# Single function\nnpm test -- functions/hello-world\n\n# Production-identical Docker test\nfuncdock test hello-world --docker\n```\n\nTests use Jest with `--experimental-vm-modules` and ESM. Helper utilities are in [`test/setup.mjs`](test/setup.mjs).\n\n---\n\n## Security\n\n- **Authentication:** JWT via httpOnly cookie (`funcdock-token`) or `Authorization: Bearer` header. Dual support for SPAs and API clients.\n- **Rate Limiting:** 100 requests per 15 minutes on `/api/`. Login endpoint limited to 5 attempts.\n- **Input Validation:** Strict regex validators for Git URLs, branch names, commit SHAs, function names, and file paths.\n- **Headers:** Helmet with CSP. CORS configured per environment. Compression enabled.\n- **Logout:** Token blacklist with automatic TTL cleanup. Ready for Redis-backed multi-instance deployments.\n- **Secrets:** Per-function `.env` files. No secrets in `localStorage`.\n\nSee [`docs/SECURITY_README.md`](docs/SECURITY_README.md) for hardening guides.\n\n---\n\n## Documentation\n\n| Doc                                                                | What you'll learn                               |\n| ------------------------------------------------------------------ | ----------------------------------------------- |\n| [`docs/SETUP_README.md`](docs/SETUP_README.md)                     | Full installation, Redis setup, first run       |\n| [`docs/DEPLOYMENT_README.md`](docs/DEPLOYMENT_README.md)           | Git, local, dashboard, PR, and CI/CD deployment |\n| [`docs/CLI_README.md`](docs/CLI_README.md)                         | Complete CLI command reference                  |\n| [`docs/DASHBOARDS_README.md`](docs/DASHBOARDS_README.md)           | Dashboard features and navigation               |\n| [`docs/CRONJOBS_README.md`](docs/CRONJOBS_README.md)               | Scheduled jobs and cron patterns                |\n| [`docs/LAYERS_README.md`](docs/LAYERS_README.md)                   | Creating and managing shared layers             |\n| [`docs/TESTING_README.md`](docs/TESTING_README.md)                 | Test patterns, coverage, Docker tests           |\n| [`docs/SECURITY_README.md`](docs/SECURITY_README.md)               | Auth, rate limiting, secrets management         |\n| [`docs/TROUBLESHOOTING_README.md`](docs/TROUBLESHOOTING_README.md) | Common issues and fixes                         |\n| [`ARCHITECTURE.md`](ARCHITECTURE.md)                               | System design, data flow, key decisions         |\n| [`CONTRIBUTING.md`](CONTRIBUTING.md)                               | How to contribute                               |\n\n---\n\n## Screenshots\n\n| Dashboard                               | Deploy                                           | Function Logs                          |\n| --------------------------------------- | ------------------------------------------------ | -------------------------------------- |\n| ![Dashboard](screenshots/dashboard.jpg) | ![Deploy](screenshots/deploy-connect-github.jpg) | ![Logs](screenshots/function-logs.jpg) |\n\n| Metrics                                      | Cron Jobs                              | Environment                          |\n| -------------------------------------------- | -------------------------------------- | ------------------------------------ |\n| ![Metrics](screenshots/function-metrics.jpg) | ![Cron](screenshots/function-cron.jpg) | ![Env](screenshots/function-env.jpg) |\n\nMore in [`screenshots/`](screenshots/).\n\n---\n\n## Changelog\n\nSee [`CHANGELOG.md`](CHANGELOG.md) for version history and migration notes.\n\n---\n\n## Contributing\n\nContributions are welcome. Please read [`CONTRIBUTING.md`](CONTRIBUTING.md) and run `npm test` before opening a PR.\n\n---\n\n## License\n\nMIT © [REAA Technologies](https://github.com/reaatech)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freaatech%2Ffuncdock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freaatech%2Ffuncdock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freaatech%2Ffuncdock/lists"}