github Python re-analysis due

malkreide/swiss-transport-mcp

github

MCP Server for Swiss public transport – OJP journey planner, real-time departures, disruptions, occupancy, ticket prices, train formations and open data from opentransportdata.swiss

maintainer
malkreide
license
MIT
first seen
2026-06-04
last seen
2026-08-24
releases · 30d
1
short id

Drift inferred · capture-to-capture

No drift recorded — single capability capture; advisories appear once its surface changes.

capabilities 8 tools
transport stdio · streamable-http · http · sse verified reported listed in the official MCP registry counts 8 tools · 0 res · 0 prompts permission surface via code analysis

tools

  • check_transport_api_status
  • get_train_composition
  • get_train_occupancy
  • transport_departures
  • transport_get_dataset
  • transport_nearby_stops
  • transport_search_datasets
  • transport_search_stop
skills & danger signals github-tarball
prompt-surface shipped agent-instruction files + hidden-content / dangerous-code findings — quoted from the analyzed source

analyzed commit 1f9b5e9 · analyzer v33 · 1w ago

skills & prompt files 1

danger signals1

code evidence vv0.4.0 · github-tarball
evidence-backed findings quoted directly from the published source artifact — not inferred

code files: 38

filesystem 11

  • fs malkreide-swiss-transport-mcp-1f9b5e9/audits/2026-06-03T064903-Z-swiss-transport-mcp/findings/_generator.py :5 RUN = pathlib.Path(sys.argv[1])
  • fs (weak) malkreide-swiss-transport-mcp-1f9b5e9/scripts/check_version_sync.py :35 from pathlib import Path
  • fs (weak) malkreide-swiss-transport-mcp-1f9b5e9/scripts/classify_live_run.py :55 from pathlib import Path
  • fs (weak) malkreide-swiss-transport-mcp-1f9b5e9/scripts/record_fixtures.py :47 from pathlib import Path
  • fs malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/ojp_client.py :13 from pathlib import Path
  • fs malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/tool_integrity.py :22 from pathlib import Path
  • fs (weak) malkreide-swiss-transport-mcp-1f9b5e9/tests/fixture_data.py :14 from pathlib import Path
  • fs (weak) malkreide-swiss-transport-mcp-1f9b5e9/tests/test_classify_live_run.py :21 from pathlib import Path
  • fs (weak) malkreide-swiss-transport-mcp-1f9b5e9/tests/test_ojp_contract.py :277 source = (ojp_client.__file__ and open(ojp_client.__file__, encoding="utf-8").read()) or ""
  • fs (weak) malkreide-swiss-transport-mcp-1f9b5e9/tests/test_response_shape.py :207 from pathlib import Path
  • fs (weak) malkreide-swiss-transport-mcp-1f9b5e9/tests/test_server_config.py :5 from pathlib import Path

network 15

  • net malkreide-swiss-transport-mcp-1f9b5e9/audits/2026-06-03T064903-Z-swiss-transport-mcp/findings/_generator.py :49 "Einen `@asynccontextmanager`-Lifespan mit `AsyncExitStack` einrichten, der EINEN gepoolten `httpx.AsyncClient` erstellt und beim Shutdown sauber schliesst. `api_client.py` von Per-Request-Clients auf
  • net (weak) malkreide-swiss-transport-mcp-1f9b5e9/scripts/record_fixtures.py :50 import httpx
  • net malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/api_client.py :16 import httpx
  • net malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/api_infrastructure.py :21 import httpx
  • net malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/net_security.py :26 from urllib.parse import urlparse
  • net malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/occupancy.py :260 import httpx
  • net malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/retry.py :25 import httpx
  • net malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/server.py :31 import httpx
  • net (weak) malkreide-swiss-transport-mcp-1f9b5e9/tests/test_api_client.py :8 import httpx
  • net (weak) malkreide-swiss-transport-mcp-1f9b5e9/tests/test_lifespan.py :3 import httpx
  • net (weak) malkreide-swiss-transport-mcp-1f9b5e9/tests/test_observability.py :9 import httpx
  • net (weak) malkreide-swiss-transport-mcp-1f9b5e9/tests/test_place_resolution.py :21 import httpx
  • net (weak) malkreide-swiss-transport-mcp-1f9b5e9/tests/test_response_shape.py :21 import httpx
  • net (weak) malkreide-swiss-transport-mcp-1f9b5e9/tests/test_retry_policy.py :14 import httpx
  • net (weak) malkreide-swiss-transport-mcp-1f9b5e9/tests/test_tool_outputs.py :15 import httpx

secrets 2

  • secrets malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/server.py :69 siri_sx_key=os.environ.get("SIRI_SX_API_KEY"),
  • secrets (weak) malkreide-swiss-transport-mcp-1f9b5e9/tests/test_server.py :23 _HAS_KEY = bool(os.environ.get("TRANSPORT_API_KEY") or os.environ.get("TRANSPORT_OJP_API_KEY"))

tool registrations 8

  • transport_search_stop malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/server.py :396
  • transport_nearby_stops malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/server.py :451
  • transport_departures malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/server.py :578
  • transport_search_datasets malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/server.py :732
  • transport_get_dataset malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/server.py :794
  • get_train_occupancy malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/server.py :908
  • get_train_composition malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/server.py :1042
  • check_transport_api_status malkreide-swiss-transport-mcp-1f9b5e9/src/swiss_transport_mcp/server.py :1105

declared dependencies 11

  • mcp@>=2.0.0,<3
  • modern@*
  • httpx@>=0.27.0,<1.0.0
  • pydantic@>=2.0.0,<3.0.0
  • pytest@>=8.0.0
  • pytest-asyncio@>=0.23.0
  • pytest-cov@>=5.0.0
  • respx@>=0.21.0
  • .@*
  • ruff@==0.16.1
  • opentelemetry-sdk@>=1.20.0,<2.0.0

transport_posture 2

  • network-listening, binds all interfaces, no auth detected malkreide-swiss-transport-mcp-1f9b5e9/tests/test_cors.py :150 host="0.0.0.0", # noqa: S104
  • network-listening, binds all interfaces, no auth detected malkreide-swiss-transport-mcp-1f9b5e9/tests/test_transport_security.py :124 app = server._build_http_app("streamable-http", _ORIGINS, host="0.0.0.0", port=8080)