Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ contact_links:
about: For anything that isn't a clear bug or feature request — please use Discussions so the answer helps everyone else too.
- name: 📚 Documentation & Guides
url: https://anythingmcp.com
about: Setup guides for all 188 adapters and every AI client, in seven languages.
about: Setup guides for all 189 adapters and every AI client, in seven languages.
- name: 🔐 Security vulnerabilities
url: https://github.com/HelpCode-ai/anythingmcp/blob/main/SECURITY.md
about: Please do NOT open a public issue. Follow the security disclosure policy.
Expand Down
9 changes: 9 additions & 0 deletions .github/codeql/codeql-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: AnythingMCP CodeQL config

paths-ignore:
# Calls one real tool of every keyless adapter, with the URL taken from the
# adapter JSON in this repo. CodeQL reads that as "file data flows into an
# outbound request" (js/file-access-to-http), which is precisely the job of
# the script: the file is our own catalog, not user input, and the script
# runs only in CI and from an operator's shell.
- scripts/probe-keyless.mjs
1 change: 1 addition & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ jobs:
with:
languages: ${{ matrix.language }}
queries: security-and-quality
config-file: ./.github/codeql/codeql-config.yml

- name: Autobuild
uses: github/codeql-action/autobuild@v4
Expand Down
16 changes: 9 additions & 7 deletions .github/workflows/deploy-cloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
host: ${{ secrets.CLOUD_HOST }}
username: root
key: ${{ secrets.CLOUD_SSH_KEY }}
source: "docker-compose.cloud.yml,deploy/cloud/Caddyfile,deploy/cloud/db-rest/Dockerfile"
source: "docker-compose.cloud.yml,deploy/cloud/Caddyfile,deploy/motis/Dockerfile,deploy/motis/config.yml,deploy/motis/entrypoint.sh"
target: /tmp/anythingmcp-deploy
overwrite: true

Expand All @@ -46,14 +46,16 @@ jobs:
docker pull helpcodeai/anythingmcp:${{ inputs.tag }}
docker pull helpcodeai/anythingmcp:latest

# Update compose, Caddyfile and the custom db-rest Dockerfile from
# checkout. The Dockerfile is the build context for the db-rest
# Update compose, Caddyfile and the MOTIS build context from
# checkout. deploy/motis is the build context for the motis
# service; `docker compose up` builds it if the pinned image tag is
# missing (fresh droplet), otherwise the existing image is reused.
# missing (fresh droplet or a bumped tag), otherwise the existing
# image is reused.
cp /tmp/anythingmcp-deploy/docker-compose.cloud.yml ./docker-compose.cloud.yml
cp /tmp/anythingmcp-deploy/deploy/cloud/Caddyfile ./Caddyfile
mkdir -p ./deploy/cloud/db-rest
cp /tmp/anythingmcp-deploy/deploy/cloud/db-rest/Dockerfile ./deploy/cloud/db-rest/Dockerfile
mkdir -p ./deploy/motis
cp /tmp/anythingmcp-deploy/deploy/motis/* ./deploy/motis/
rm -rf ./deploy/cloud/db-rest
rm -rf /tmp/anythingmcp-deploy

# Keep CRON_SECRET in the server .env in sync with the repo
Expand All @@ -67,7 +69,7 @@ jobs:
fi

# Recreate ONLY the app to pick up the new image/config (postgres,
# redis and db-rest keep running — no data churn, no needless
# redis and motis keep running — no data churn, no needless
# downtime), and wait until it reports healthy. The old command
# force-recreated the whole stack with no health gate, so a
# crash-on-start went unnoticed and could take the DB down with it.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
readme-filepath: ./README.md
# Docker Hub caps this at 100 characters and shows it in search
# results; the repo's was left at the truncated default.
short-description: "188 connectors + any REST/SOAP/GraphQL/SQL as MCP tools for Claude & ChatGPT. Self-hosted, AGPL."
short-description: "189 connectors + any REST/SOAP/GraphQL/SQL as MCP tools for Claude & ChatGPT. Self-hosted, AGPL."

- name: Set Docker Hub categories
env:
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/keyless-probe.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Keyless adapter probe

# Calls one real tool of every adapter that claims to need no API key, from a
# GitHub runner — a datacenter address, like the cloud. The README and the
# banner quote that number; this is what keeps it true. An adapter that only
# works from residential IPs must be marked `selfHostOnly` (hidden from the
# cloud catalog, excluded from the count) rather than advertised.
#
# The Deutsche Bahn adapter needs a MOTIS instance, so the job builds the one
# in deploy/motis and probes through it — which also proves that image still
# boots, downloads the feeds and imports them.

on:
schedule:
- cron: "0 6 * * 1"
workflow_dispatch:
pull_request:
paths:
- "deploy/motis/**"
- "scripts/probe-keyless.mjs"
- "packages/backend/src/adapters/de/deutsche-bahn.json"

jobs:
probe:
name: Probe keyless adapters from a datacenter IP
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v6

- uses: actions/setup-node@v4
with:
node-version: 22

- name: Build and start MOTIS
run: |
docker build -t anythingmcp-motis:ci deploy/motis
docker run -d --name motis -p 8080:8080 anythingmcp-motis:ci
for i in $(seq 1 60); do
if curl -fsS "http://localhost:8080/api/v1/geocode?text=Berlin&type=STOP" > /dev/null 2>&1; then
echo "MOTIS up after ${i} checks"; break
fi
if [ "$i" = "60" ]; then
echo "::error::MOTIS did not come up"; docker logs motis; exit 1
fi
sleep 5
done

- name: Probe
env:
PROBE_MOTIS_URL: http://localhost:8080
run: node scripts/probe-keyless.mjs --check --all

- name: MOTIS logs
if: always()
run: docker logs motis 2>&1 | grep -v "\[debug\]" | tail -40
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ abstract: >
server that exposes REST, SOAP/WSDL and GraphQL APIs, SQL/NoSQL databases
and other MCP servers as tools for AI clients such as Claude, ChatGPT,
Google Gemini, GitHub Copilot and Cursor, without writing code. It ships
188 pre-built adapters (Deutsche Bahn, DATEV, weclapp, DHL, Shopware,
189 pre-built adapters (Deutsche Bahn, DATEV, weclapp, DHL, Shopware,
Personio, Handelsregister, etc.), a per-workspace knowledge graph served
over MCP, per-tool response mapping, OAuth2/RBAC/SSO/SCIM governance, an
audit log and a visual tool editor.
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<p align="center">
<img src="docs/assets/banner.png" alt="AnythingMCP — 188 connectors, 26 of them with no API key. Your REST, SOAP/WSDL, GraphQL, SQL and MCP systems become tools for Claude, ChatGPT, Copilot and Gemini." width="100%" />
<img src="docs/assets/banner.png" alt="AnythingMCP — 189 connectors, 20 of them with no API key. Your REST, SOAP/WSDL, GraphQL, SQL and MCP systems become tools for Claude, ChatGPT, Copilot and Gemini." width="100%" />
</p>

<h1 align="center">AnythingMCP</h1>

<p align="center">
<strong>Give Claude, ChatGPT and Copilot safe access to the software your company already runs.</strong><br/>
188 ready adapters, any REST/SOAP/GraphQL/SQL system without code, on your own infrastructure — and it learns how your systems connect.
189 ready adapters, any REST/SOAP/GraphQL/SQL system without code, on your own infrastructure — and it learns how your systems connect.
</p>

<p align="center">
Expand Down Expand Up @@ -36,7 +36,7 @@ docker compose up -d # → http://localhost:3000

Three words appear throughout and mean three different things:

- an **adapter** is one of the 188 JSON definitions that ship in this repo — DATEV, weclapp, DHL, Deutsche Bahn, Shopware, Personio, Handelsregister and the rest. 26 of them need no API key at all; the others ask for your credentials at import.
- an **adapter** is one of the 189 JSON definitions that ship in this repo — DATEV, weclapp, DHL, Deutsche Bahn, Shopware, Personio, Handelsregister and the rest. 20 of them need no API key at all; the others ask for your credentials at import.
- a **connector** is an adapter, or your own OpenAPI spec / Postman collection / WSDL / GraphQL endpoint / database, once you have configured it in your workspace. Anything you can point at, in minutes, without writing an MCP server.
- an **MCP server** is the URL you hand to Claude. It exposes the connectors you assign to it, and nothing else.

Expand Down Expand Up @@ -260,7 +260,7 @@ AI clients speak MCP, but your systems speak REST, SOAP, GraphQL and SQL. Writin

## The adapter catalog

188 adapters, exposing 1,800+ tools. **26 need no API key**; the rest ask for your credentials at import and the tools are available immediately. Every one has a setup guide on [anythingmcp.com/guides](https://anythingmcp.com/guides), in seven languages.
189 adapters, exposing 1,800+ tools. **20 need no API key**; the rest ask for your credentials at import and the tools are available immediately. Every one has a setup guide on [anythingmcp.com/guides](https://anythingmcp.com/guides), in seven languages.

| Category | Examples |
|---|---|
Expand Down
17 changes: 0 additions & 17 deletions deploy/cloud/db-rest/Dockerfile

This file was deleted.

32 changes: 32 additions & 0 deletions deploy/motis/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# MOTIS routing engine for the Deutsche Bahn connector.
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
#
# The connector used to go through db-rest / db-vendo-client, which scrapes
# bahn.de. Deutsche Bahn blocks datacenter IPs and the library's own README now
# calls those endpoints "very unreliable" and recommends a self-hosted MOTIS.
# This image is that: the official MOTIS binary plus an entrypoint that pulls
# the open GTFS timetable for Germany's trains from gtfs.de (CC BY 4.0), runs
# the import, keeps a GTFS-RT feed polled for live delays and cancellations,
# and re-imports the static feed once a week so it never runs off the end of
# the 30-day window the free feeds cover.
#
# Trains only (long-distance + regional/S-Bahn, ~12 MB of GTFS): the import
# takes about a second and peaks under 400 MB. The full Germany feed with every
# bus and tram is 280 MB and peaks at 7 GB on import, which would not fit next
# to the app on an 8 GB host. See README.md for the feed URLs and how to swap
# them.
FROM ghcr.io/motis-project/motis:2.11.3

USER root
COPY config.yml /motis-config/config.yml
COPY entrypoint.sh /entrypoint.sh
RUN chmod 0755 /entrypoint.sh && mkdir -p /data && chown motis:motis /data

USER motis
WORKDIR /data
EXPOSE 8080
# The first boot downloads and imports the feeds before the server listens;
# the compose healthchecks give that a longer start_period.
HEALTHCHECK --interval=30s --timeout=5s --start-period=180s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost:8080/ || exit 1
ENTRYPOINT ["/entrypoint.sh"]
CMD []
75 changes: 75 additions & 0 deletions deploy/motis/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# MOTIS for the Deutsche Bahn connector

The `deutsche-bahn` adapter talks to a [MOTIS](https://github.com/motis-project/motis)
instance (MIT) instead of scraping bahn.de. This directory builds one that is
ready to run: the official MOTIS binary plus an entrypoint that downloads the
open German train timetable, imports it, polls a GTFS-RT feed for live delays
and cancellations, and re-imports the static feed once a week.

## Why not db-rest / bahn.de

Until v0.8.1 the connector went through `db-rest` (db-vendo-client), which
calls Deutsche Bahn's undocumented web and app endpoints. Deutsche Bahn blocks
datacenter IP ranges, so from a hosted server every call failed (HTTP 500 /
`OPS_BLOCKED`), and the library's own README now describes those endpoints
as very unreliable and recommends a self-hosted MOTIS. Open data does not get
blocked.

## What it serves

| piece | source | licence |
|---|---|---|
| Long-distance trains (ICE, IC, EC, ECE, EN, railjet, night trains) | [gtfs.de `de_fv`](https://gtfs.de/en/feeds/de_fv/) | CC BY 4.0 |
| Regional trains and S-Bahn | [gtfs.de `de_rv`](https://gtfs.de/en/feeds/de_rv/) | CC BY 4.0 |
| Live delays, platform changes, cancellations, service alerts | [gtfs.de GTFS-RT](https://gtfs.de/en/realtime/) `realtime-free.pb` | CC BY-SA 4.0 |

The free static feeds cover the next 30 days and are re-downloaded every
`MOTIS_REFRESH_DAYS` (default 7). Buses, trams and ferries are deliberately
left out: adding them (`de_full`, 280 MB) takes the import from one second and
under 400 MB of RAM to about 7 GB.

Attribution: gtfs.de asks that data users name **DELFI e.V.** as the source;
the connector's instructions and the adapter's `docsUrl` do.

## Running it

Cloud (`docker-compose.cloud.yml`) runs it as the `motis` service and points
the app at it with `MOTIS_INTERNAL_URL=http://motis:8080`. Self-host:

```bash
# in .env
COMPOSE_PROFILES=motis
MOTIS_INTERNAL_URL=http://motis:8080
SSRF_ALLOWED_HOSTS=motis
docker compose up -d
```

When `MOTIS_INTERNAL_URL` is set the adapter's `MOTIS_URL` is filled in
automatically at import and hidden from the install form. Without it, the
install form asks for the URL of a MOTIS instance you run elsewhere.

`http://localhost:8080/` serves the MOTIS UI once the import is done; the
connector uses `/api/v1/geocode`, `/api/v1/stoptimes` and `/api/v1/plan`.

## Environment

| variable | default | meaning |
|---|---|---|
| `MOTIS_REFRESH_DAYS` | `7` | re-download and re-import the static feeds after this many days |
| `MOTIS_REFRESH_CHECK_SECONDS` | `3600` | how often the running container checks whether a refresh is due |
| `MOTIS_GTFS_FV_URL` | gtfs.de `fv_free/latest.zip` | long-distance feed |
| `MOTIS_GTFS_RV_URL` | gtfs.de `rv_free/latest.zip` | regional feed |
| `MOTIS_GTFS_RT_URL` | gtfs.de `realtime-free.pb` | GTFS-RT feed polled every 120 s |
| `MOTIS_DATA_DIR` | `/data` | volume with feeds, imported data and the refresh stamp |

gtfs.de also sells complete feeds with extended route types (so an ICE reports
`HIGHSPEED_RAIL` rather than `REGIONAL_RAIL`) and no 30-day limit; point the
URL variables at those and nothing else changes.

## Not Transitous

[Transitous](https://transitous.org) runs the same stack as a public service
and is a good way to try the API, but its policy forbids commercial use and
asks for a User-Agent naming the app and a contact. The adapter therefore
never defaults to it; if you qualify, entering `https://api.transitous.org` as
`MOTIS_URL` works.
42 changes: 42 additions & 0 deletions deploy/motis/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# MOTIS import/server configuration, templated by entrypoint.sh:
# __FEEDS__ directory holding the downloaded GTFS zips
# __RT_URL__ GTFS-RT feed (TripUpdates + ServiceAlerts)
#
# Two datasets rather than gtfs.de's single "full" feed: fv (long-distance:
# ICE, IC, EC, ECE, EN, railjet, night trains) and rv (regional rail and
# S-Bahn). Together they are every train in Germany and about 12 MB; the full
# feed adds every bus and tram and needs 7 GB of RAM to import.
#
# No OpenStreetMap file on purpose. MOTIS only needs OSM for street routing,
# map tiles and address geocoding; station-name geocoding works from the
# timetable alone (adr_extend), and that is all the connector asks for.
timetable:
first_day: TODAY
# The free feeds cover the next 30 days; anything beyond that is simply
# absent, so a large window costs nothing and never truncates a feed.
num_days: 365
railviz: false
with_shapes: false
# The GTFS-RT feed is ~55 MB (it carries every bus in the country); the
# default 30 s download timeout truncated it and MOTIS logged parser errors.
http_timeout: 180
# Seconds between GTFS-RT polls. The upstream file updates every 10 s, but
# each poll is a 55 MB download, so this is a bandwidth courtesy to gtfs.de
# more than a freshness choice.
update_interval: 120
datasets:
fv:
path: __FEEDS__/fv.zip
rt:
- url: __RT_URL__
protocol: gtfsrt
rv:
path: __FEEDS__/rv.zip
rt:
- url: __RT_URL__
protocol: gtfsrt
geocoding: true
reverse_geocoding: false
street_routing: false
osr_footpath: false
elevators: false
Loading
Loading