Skip to main content
Glama
harshil1712

Berlin Transport MCP Server

by harshil1712
README.md
# Berlin Transport MCP Server

An MCP server that provides access to Berlin's public transport data through the VBB (Verkehrsverbund Berlin-Brandenburg) API. This server wraps the [v6.vbb.transport.rest](https://v6.vbb.transport.rest/) API.

This server uses [Code Mode](https://developers.cloudflare.com/agents/tools/codemode/): instead of exposing one MCP tool per API operation, the VBB API is described as an OpenAPI spec and the server exposes exactly two tools, `search` and `execute`. The model reads the spec, then writes and runs a short JavaScript snippet in a sandboxed [Dynamic Worker](https://developers.cloudflare.com/dynamic-workers/) to call the API — which scales far better than dumping every tool schema into the model's context window, and lets it chain multiple calls (e.g. search a stop, then fetch its departures) in a single sandbox run.

## Get started

```bash
npm install
npm run dev
```

This starts a local server at `http://localhost:8787/mcp`.

```bash
npm run deploy
```

This deploys the Worker to a URL like: `berlin-transport-mcp.<your-account>.workers.dev/mcp`.

## Available Tools

- **`search`** — Search the OpenAPI spec (`codemode.spec()`) to discover available operations, parameters, and response shapes before calling the API.
- **`execute`** — Run a short async JavaScript snippet that calls `codemode.request({ method, path, query })` against the VBB API. The host proxies the actual HTTP request; the sandbox has no direct network access.

### Underlying API operations

The OpenAPI spec exposed to the model covers:

- **`getLocations`** (`GET /locations`) — search for stops, stations, addresses, and points of interest.
- **`getDepartures`** (`GET /stops/{id}/departures`) — upcoming departures for a stop.
- **`getJourneys`** (`GET /journeys`) — journey options between an origin and a destination.

For more details about the underlying API, visit [v6.vbb.transport.rest/getting-started.html](https://v6.vbb.transport.rest/getting-started.html).

## Customizing your MCP Server

The OpenAPI spec passed to `openApiMcpServer` and the `request` proxy function both live in `src/index.ts`. To wrap a different API:

1. Update `API_ORIGIN` and `openApiSpec` with the new API's paths/operations.
2. Adjust the `request` function if the upstream API needs different methods, auth headers, or response handling.

## Connect to Cloudflare AI Playground

You can connect to your MCP server from the Cloudflare AI Playground, which is a remote MCP client:

1. Go to https://playground.ai.cloudflare.com/
2. Enter your deployed MCP server URL (`berlin-transport-mcp.<your-account>.workers.dev/mcp`)
3. You can now use the `search` and `execute` tools directly from the playground!

## Connect Claude Desktop to your MCP server

You can also connect to your remote MCP server from local MCP clients, by using the [mcp-remote proxy](https://www.npmjs.com/package/mcp-remote).

To connect to your MCP server from Claude Desktop, follow [Anthropic's Quickstart](https://modelcontextprotocol.io/quickstart/user) and within Claude Desktop go to Settings > Developer > Edit Config.

Update with this configuration:

```json
{
  "mcpServers": {
    "berlin-transport": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://berlin-transport.mcp-tools.app/mcp"  // or if local http://localhost:8787/mcp
      ]
    }
  }
}
```

Restart Claude and you should see the `search` and `execute` tools become available.

TDQS

D1.8/5.0

Scored across 3 tools

Disambiguation4/5

The three tools have distinct purposes: get_departures likely retrieves departure times, get_journeys handles route planning, and search_stops finds stops or stations. While there is some potential overlap between get_departures and get_journeys (both involve travel information), the names suggest clear enough separation for an agent to differentiate them effectively.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern with snake_case: get_departures, get_journeys, and search_stops. This uniformity makes the tool set predictable and easy to understand, with no deviations in naming style.

Tool Count3/5

With only 3 tools, the server feels thin for a transport domain that typically requires more operations like route details, fare information, or service alerts. While it covers basic functions, the count is borderline low for comprehensive transport-related tasks.

Completeness2/5

The tool set has significant gaps for a transport server. It lacks essential operations such as getting route details, checking fares, accessing service status or alerts, and managing user preferences. This incomplete coverage will likely cause agent failures when handling common transport queries beyond basic departure and journey lookups.

Maintenance

ActivitySlowing
ResponsivenessNo issues