A TypeScript MCP (Model Context Protocol) server that serves coffee data. Originally based on the Medium article A Quick Step-by-Step Guide to Writing an MCP Server in TypeScript by Perry George. Supports both Streamable HTTP and stdio transports.
- Node.js 24+
- npm
- Docker (optional, for containerized deployment)
npm install
npm run buildMulti-stage build: builder stage compiles TypeScript, runner stage copies only production dependencies and compiled output. Non-root app user. HEALTHCHECK via wget against /health.
docker build -t coffee-mate-mcp .
docker run -p 3001:3001 coffee-mate-mcpOverride environment variables at runtime:
docker run -p 8080:8080 -e PORT=8080 -e ACTIVE_TOOLS="get-coffees" coffee-mate-mcpHTTP mode (default) — starts a raw Node.js Streamable HTTP server:
node build/app/main.js
# MCP Server running on http://0.0.0.0:3001Set the PORT environment variable to change the port (default 3001).
stdio mode — for local VS Code integration:
node build/app/main.js --stdio
# MCP Server running on stdio| Variable | Type | Default | Description |
|---|---|---|---|
PORT |
number | 3001 |
HTTP server port |
TRANSPORT_MODE |
string | "http" |
"http" or "stdio" |
SERVER_NAME |
string | "coffee-mate" |
MCP server identity |
SERVER_VERSION |
string | "1.0.0" |
Semver version |
ACTIVE_TOOLS |
string | "" |
Comma-separated tool names to register (empty = all) |
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Healthcheck — returns { "status": "ok" } |
/mcp |
POST | MCP JSON-RPC message handler (initialize creates a session) |
/mcp |
GET | SSE backward-compatibility stream |
/mcp |
DELETE | Explicit session termination |
| Tool | Description | Parameters |
|---|---|---|
get-coffees |
Returns a list of all coffees | None |
get-a-coffee |
Retrieves data for a specific coffee by name | name (string) |
The project includes a .vscode/mcp.json config that uses stdio mode. Open the workspace in VS Code, start the MCP server from the config file, and use the tools via GitHub Copilot in Agent mode.
When running inside the first-n8n Docker Compose stack, this server is available to other containers at http://coffee-mate-mcp:3001/mcp on the demo network. See the first-n8n project for the full stack setup.
GitHub Actions workflow (.github/workflows/deploy.yml):
cijob: Runsbuild→lint:ts→teston all branches and pull requests targetingmaindeployjob: Builds Docker image, pushes to Azure Container Registry, deploys to Azure Container Apps. Gated tomainpush only
TypeScript API docs are generated as Markdown in docs/api/ using TypeDoc with typedoc-plugin-markdown and typedoc-plugin-remark. Generated files are committed and enforced in CI.
npm run docs # Generate + remark-format docs (commit the result)
npm run docs:lint # Lint committed docs/api with remark- Make source changes
- Run
npm run docsto regenerate API docs - Commit the updated
docs/api/alongside your code changes
CI runs npm run docs then git diff --exit-code docs/api — the build fails if committed docs are out of sync with the source.