Skip to content

Connecting your assistant

Sergii Mavrov edited this page Oct 4, 2026 · 2 revisions

Connecting your assistant

One URL, no key. Most clients need nothing but the address; the npm package exists only for clients that cannot speak HTTP.

ViaFrei is a hosted MCP server. There is nothing to deploy, no key to request and no quota to negotiate.

transport address when
Streamable HTTP https://mcp.viafrei.de/mcp the default — use this
HTTP+SSE (legacy) https://mcp.viafrei.de/sse your client speaks only the older HTTP transport
stdio npx -y viafrei your client speaks neither, only stdio

Protocol version 2025-06-18. The server identifies itself as viafrei, with the current release as its version, and advertises tools, resources (with subscribe), prompts and logging.

Do I need the npm package?

Probably not. Decide like this:

  1. Can your client add a remote MCP server by URL (Streamable HTTP)? → use https://mcp.viafrei.de/mcp and stop reading.
  2. Can it add a remote server, but only over the older HTTP+SSE transport? → use https://mcp.viafrei.de/sse.
  3. Can it only launch a local process that speaks MCP over stdin/stdout? → then you need the bridge, npx -y viafrei.

The bridge is a transport shim and nothing more: it holds no data and no credentials, makes no decision about any answer, and sends no telemetry. It relays stdio to the hosted endpoint. It needs Node 22 or newer, and npx fetches it when your client starts it — there is nothing to install by hand.

Claude Code

claude mcp add --transport http viafrei https://mcp.viafrei.de/mcp

If your Claude Code build only offers the older transport:

claude mcp add --transport sse viafrei https://mcp.viafrei.de/sse

Claude Desktop

Edit claude_desktop_config.json and add the bridge, then restart Claude Desktop:

{
  "mcpServers": {
    "viafrei": {
      "command": "npx",
      "args": ["-y", "viafrei"]
    }
  }
}

The same three lines fit any client that takes an stdio MCP server, including the .mcp.json an IDE reads.

Any client that speaks Streamable HTTP

Give it the URL. That is the whole configuration:

https://mcp.viafrei.de/mcp

There is no Authorization header to set, no client id, no OAuth dance. If your client insists on a secret, leave it blank.

A client that only speaks HTTP+SSE

The older transport is served as well, so nobody meets a locked door:

https://mcp.viafrei.de/sse

It is deprecated in the MCP specification. Prefer /mcp when your client grows support for it.

The stdio bridge, with options

Everything the bridge accepts has an environment variable too, because many MCP clients can pass an env block but not arguments.

option variable what it does
--url <url> VIAFREI_MCP_URL endpoint to relay to; default https://mcp.viafrei.de/mcp
--header "Name: value" VIAFREI_MCP_HEADER extra HTTP header on every request, repeatable (the variable separates several with a newline)
--timeout <ms> VIAFREI_MCP_TIMEOUT_MS per-request timeout, default 30000; the event stream is never timed out
--version, --help — print and exit

A flag wins over the variable; the variable wins over the default.

There is no self-hosted ViaFrei. --url is not a way to run your own server — it is there for a proxy or gateway in front of the service. Leave it unset.

The bridge does not follow a redirect off the origin you pointed it at: your headers go to that origin and nowhere else, so a server cannot forward a header somewhere you did not choose.

Check that it worked

Two things to look at.

1. The catalogue appeared. Ask your client to list the server's tools. You should see 18, including check_autobahn_traffic, get_train_departures and find_place. The running server is the only source of truth for the catalogue — see Tools at a glance for what to expect.

2. A real answer comes back, with its attribution line. Ask something concrete:

Gibt es gerade Stau auf der A8?

What are the next departures from Hamburg Hbf?

Funktioniert der Aufzug am Bahnhof Köln Messe/Deutz?

Brauche ich in Deutschland eine Umweltplakette?

Wo kann ich in Leipzig mit Typ 2 laden?

A good answer ends with a line naming its sources, for example Fahrplandaten: Deutsche Bahn AG, DB API Marketplace, CC BY 4.0, bearbeitet (…). If you see the answer but not the line, your client is swallowing it — fix that before you ship, because showing the line is a licence condition and not a nicety.

You can also read the server's own registers as MCP resources: viafrei://attribution (every licence and attribution line), viafrei://coverage (what it can answer for right now) and viafrei://status/feeds (which feeds are arriving).

If it does not work

The bridge prints one line to stderr and exits with a code that says what happened — no stack traces:

exit meaning
0 clean shutdown
1 something else went wrong; the line says what
2 bad usage — a flag or value the bridge does not accept
3 the endpoint could not be reached, stopped answering, or never answered in time
4 the endpoint answered and this cannot continue (refused with an HTTP status, forgot the session, answered with something that is not MCP, or redirected to another origin)
5 protocol version mismatch; the line names the version the server speaks

The same text goes back to the client as a JSON-RPC error, so an assistant can say what went wrong instead of going quiet.

A 429, 502, 503 or 504 is retried once, after the delay the server asked for in Retry-After or 250 ms when it asked for none. Your timeout bounds each request, not the whole call: two attempts plus a delay makes a worst case of roughly three times what you set. If you need a hard ceiling, enforce it on your side.

An established session is allowed to wobble — a dropped event stream is a warning and the bridge reconnects — but it is not allowed to be dead in silence: several failures in a row with nothing succeeding in between end the process, so the client that started it finds out.

Next

Clone this wiki locally