erm-github-mcp
README.md
# erm-github-mcp
A barebones [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server written in TypeScript. Designed to be built from source, containerized with Docker, and deployed to [IBM Code Engine](https://www.ibm.com/products/code-engine).
---
## Table of Contents
- [Overview](#overview)
- [Project Structure](#project-structure)
- [Tools](#tools)
- [Local Development](#local-development)
- [Running with Docker](#running-with-docker)
- [GitHub Actions CI/CD](#github-actions-cicd)
- [Deploying to IBM Code Engine](#deploying-to-ibm-code-engine)
- [Connecting to Bob (IBM Bob Desktop)](#connecting-to-bob-ibm-bob-desktop)
- [Extending the Server](#extending-the-server)
---
## Overview
This server supports two transports:
| Transport | When it's used | How to activate |
|-----------|---------------|-----------------|
| **stdio** | Local development / Bob desktop | Default (no env var needed) |
| **HTTP Streamable** | Docker / Code Engine | `MCP_TRANSPORT=http` |
The HTTP transport exposes a `/health` endpoint at `GET /health` for liveness probes.
---
## Project Structure
```
.
├── src/
│ └── index.ts # Server entry point — add tools here
├── build/ # Compiled output (git-ignored)
├── .github/
│ └── workflows/
│ └── build-push.yml # CI: typecheck → build → push to GHCR
├── Dockerfile # Multi-stage build (builder + runtime)
├── docker-compose.yml # Local container testing
├── tsconfig.json
└── package.json
```
---
## Tools
| Tool | Description |
|------|-------------|
| `ping` | Health-check — returns `pong` and echoes an optional message |
| `get_server_info` | Returns server name, version, transport, Node version, and uptime |
---
## Local Development
### Prerequisites
- Node.js 20+
- npm 10+
### Install and build
```bash
npm install
npm run build
```
### Run in stdio mode (for use with Bob desktop)
```bash
node build/index.js
```
### Run in HTTP mode locally
```bash
MCP_TRANSPORT=http PORT=3000 node build/index.js
```
Test the health endpoint:
```bash
curl http://localhost:3000/health
```
---
## Running with Docker
### Build the image
```bash
docker build -t erm-github-mcp .
```
### Run the container
```bash
docker run -p 3000:3000 erm-github-mcp
```
### Using Docker Compose
```bash
docker compose up --build
```
---
## GitHub Actions CI/CD
The workflow at [`.github/workflows/build-push.yml`](.github/workflows/build-push.yml) runs on every push to `main` and on version tags (`v*`):
1. **TypeScript build** — `npm ci` + `tsc` (fails fast on type errors)
2. **Docker build & push** — multi-platform image (`linux/amd64`, `linux/arm64`) pushed to the [GitHub Container Registry (GHCR)](https://ghcr.io)
The image is published as:
```
ghcr.io/<your-github-username>/erm-github-mcp:<tag>
```
No secrets need to be configured — the workflow uses the built-in `GITHUB_TOKEN`.
### Making the package public
After the first push, go to **GitHub → Packages → erm-github-mcp → Package settings** and set visibility to **Public** so Code Engine can pull it without credentials.
---
## Deploying to IBM Code Engine
### Prerequisites
- [IBM Cloud CLI](https://cloud.ibm.com/docs/cli) with the Code Engine plugin:
```bash
ibmcloud plugin install code-engine
```
- An IBM Cloud account and a Code Engine project
### Steps
#### 1 — Target your project
```bash
ibmcloud ce project select --name <your-project-name>
```
#### 2 — Deploy the application
Replace `<tag>` with the image tag you want to deploy (e.g. `main` or `v0.1.0`):
```bash
ibmcloud ce application create \
--name erm-github-mcp \
--image ghcr.io/<your-github-username>/erm-github-mcp:<tag> \
--port 3000 \
--min-scale 0 \
--max-scale 5 \
--env MCP_TRANSPORT=http \
--env PORT=3000
```
#### 3 — Get the public URL
```bash
ibmcloud ce application get --name erm-github-mcp --output url
```
#### 4 — Update after a new image push
```bash
ibmcloud ce application update \
--name erm-github-mcp \
--image ghcr.io/<your-github-username>/erm-github-mcp:<new-tag>
```
### Environment variables
| Variable | Default | Description |
|----------|---------|-------------|
| `MCP_TRANSPORT` | `stdio` | Set to `http` in containers |
| `PORT` | `3000` | HTTP port the server listens on |
---
## Connecting to Bob (IBM Bob Desktop)
### HTTP (remote — after deploying to Code Engine)
Add the following to your Bob `mcp.json`:
```json
{
"mcpServers": {
"erm-github-mcp": {
"url": "https://<your-code-engine-url>"
}
}
}
```
### stdio (local — for development)
```json
{
"mcpServers": {
"erm-github-mcp": {
"command": "node",
"args": ["/absolute/path/to/erm-github-mcp/build/index.js"]
}
}
}
```
---
## Extending the Server
Add new tools in [`src/index.ts`](src/index.ts) using `server.tool()`:
```typescript
server.tool(
"my_tool",
"Description shown to the AI",
{
input_field: z.string().describe("What this field does"),
},
async ({ input_field }) => ({
content: [{ type: "text", text: `Result: ${input_field}` }],
})
);
```
Then rebuild:
```bash
npm run build
```
---
## License
[Apache 2.0](LICENSE)
TDQS
A3.5/5.0
Scored across 2 tools
Disambiguation5/5
The two tools serve clearly distinct purposes: ping is a health check, while get_server_info provides instance metadata. There is zero overlap between them.
Naming Consistency5/5
Both tools follow a consistent verb_noun naming pattern (ping, get_server_info) with snake_case, matching the expected convention.
Tool Count1/5
With only two generic tools and a server name indicating GitHub integration, the count is severely inadequate. The tools are trivial and unrelated to the apparent domain, representing an extreme mismatch.
Completeness1/5
The server name implies GitHub functionality, but the tool surface offers only health check and server info. No GitHub operations exist, leaving obvious and critical gaps.
Maintenance
ActivityMaintained
ResponsivenessNo issues