Skip to main content
Glama
ericmusa-ibm-public

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