italian-bus-search
# Italian Bus Search
<!-- mcp-name: io.github.Alexxanddr/italian-bus-search -->
[](https://github.com/Alexxanddr/italian-bus-search/actions/workflows/ci.yml)
An unofficial, read-only TypeScript service that searches multiple Italian coach operators through HTTP and Model Context Protocol interfaces.
The project hides provider-specific station catalogs, request formats, fare structures, and multi-leg responses behind one shared application core. It never performs login, booking, seat selection, or payment operations.
> [!IMPORTANT]
> This project is not affiliated with or endorsed by Itabus, Autoservizi Salemi, Autolinee Federico, or MarinoBus. Provider names and trademarks belong to their owners. Before enabling a live adapter, confirm that your use complies with the provider's terms, applicable law, and any required authorization. This repository does not grant data-extraction or redistribution rights.
## Features
- One response model for locations and journeys across different booking platforms.
- Live adapters for four operators.
- Partial results when one provider fails and another succeeds.
- A local stdio MCP server with structured, read-only tools.
- Official links for continuing a search manually on provider sites.
- Structured, provider-scoped errors instead of leaked upstream responses.
- Five-second upstream timeouts.
- One-hour location caches and 60-second journey caches.
- Per-client in-memory rate limiting at 60 requests per minute.
- Offline tests with synthetic fixtures; the test suite never contacts provider sites.
- A small runtime dependency surface: the official MCP SDK and Zod.
## Supported providers
| Provider ID | Operator | Integration | Locations | Journeys |
|---|---|---|---|---|
| `itabus` | Itabus | Demandware endpoints | Live | Live |
| `salemi` | Autoservizi Salemi | Albatross tenant | Live | Live |
| `federico` | Autolinee Federico | Albatross tenant | Live | Live |
| `marinobus` | MarinoBus | Albatross tenant | Live | Live |
Provider behavior and the evidence behind each integration are recorded in [Provider research](docs/research.md).
## Requirements
- Node.js 22.18 or newer
- npm
## Quick start
```sh
git clone https://github.com/Alexxanddr/italian-bus-search.git
cd italian-bus-search
npm install
cp .env.example .env
npm start
```
The server listens on `http://127.0.0.1:3000` by default.
```sh
curl http://127.0.0.1:3000/health
curl http://127.0.0.1:3000/providers
curl 'http://127.0.0.1:3000/locations?query=Roma&provider=marinobus'
```
For journey searches, use a real future date:
```sh
curl 'http://127.0.0.1:3000/journeys?origin=Roma&destination=Milano&date=YYYY-MM-DD&adults=1&children=0&provider=marinobus'
```
`YYYY-MM-DD` is a placeholder and must be replaced before running the command.
## HTTP interface
| Method | Path | Purpose |
|---|---|---|
| `GET` | `/health` | Process liveness |
| `GET` | `/providers` | Adapter status and operational reason |
| `GET` | `/locations` | Provider location search |
| `GET` | `/journeys` | Normalized one-way journey search |
`/locations` and `/journeys` accept an optional `provider` parameter. Without it, all providers are queried independently and successful data is preserved alongside provider-scoped errors.
The complete parameter, response, status, and error contract is in [HTTP interface](docs/api.md).
## MCP server
The simplest MCP configuration runs the published package directly with `npx`:
```json
{
"mcpServers": {
"italian-bus-search": {
"command": "npx",
"args": ["-y", "italian-bus-search@latest"]
}
}
}
```
Alternatively, build and start the local stdio server:
```sh
npm run build
npm run mcp:built
```
It exposes `list_providers`, `search_locations`, and `search_journeys`. A host model can turn “find buses from Rome to Milan on 15 November” into the location and journey tool calls, then show normalized options with official links for manual purchase.
```json
{
"mcpServers": {
"italian-bus-search": {
"command": "node",
"args": ["/absolute/path/to/italian-bus-search/dist/mcp/stdio.js"]
}
}
}
```
See [MCP interface](docs/mcp.md) for the authoritative tool contract, limits, errors, and development command.
## Architecture
The application has four layers:
1. HTTP and MCP adapters validate their transport-specific requests;
2. shared validation and `SearchService` orchestrate searches and partial results;
3. each provider adapter translates a remote protocol into domain types;
4. the domain module owns normalized data and error contracts.
Provider adapters implement one shared interface, so callers do not know whether a result came from Itabus Demandware or an Albatross tenant. See [Architecture](docs/architecture.md) for modules, seams, data flow, caches, and test strategy.
## Development
```sh
npm run dev
npm run mcp
npm run check
```
`npm run check` runs the complete offline test suite, TypeScript type checking, and the configured lint check. To add an operator, follow [Adding a provider](docs/adding-provider.md); do not infer a new integration from HTML alone or copy credentials into fixtures.
## Deployment
The default server deliberately binds to loopback and keeps rate-limit and cache state in process memory. Read [Operations](docs/operations.md) before placing it behind a reverse proxy or running multiple replicas.
## Project documentation
- [HTTP interface](docs/api.md) — authoritative endpoint and error contract.
- [MCP interface](docs/mcp.md) — authoritative tools, results, limits, and stdio contract.
- [Architecture](docs/architecture.md) — modules, seams, flows, and design decisions.
- [Adding a provider](docs/adding-provider.md) — research, implementation, and verification checklist.
- [Operations](docs/operations.md) — configuration, deployment constraints, and failure handling.
- [Provider research](docs/research.md) — primary-source evidence and known limitations.
- [Glossary](GLOSSARY.md) — stable project terminology.
- [Contributing](CONTRIBUTING.md) — local workflow and pull-request expectations.
- [Security policy](SECURITY.md) — private vulnerability reporting and supported versions.
- [Agent instructions](AGENTS.md) — compact routing instructions for coding agents.
## Scope and limitations
- Searches are one-way only.
- Availability is a provider-reported signal, not a seat or price guarantee.
- Prices and schedules can change between search and purchase.
- Caches and rate limits reset when the process restarts and are not shared across replicas.
- Upstream interfaces are unofficial and can change without notice.
- Both interfaces intentionally exclude accounts, bookings, payments, and CAPTCHA handling.
Always complete and confirm a purchase on the official provider site linked by `bookingUrl`.
## Contributing and security
Contributions are welcome; start with [CONTRIBUTING.md](CONTRIBUTING.md). Report vulnerabilities privately according to [SECURITY.md](SECURITY.md), not through a public issue.
## License
Source code is available under the [MIT License](LICENSE). The license covers this repository's code, not third-party data, provider trademarks, or access rights to upstream systems.
TDQS
Scored across 3 tools
Each tool covers a distinct step: listing providers (configuration), resolving locations to IDs, and searching journeys. The descriptions explicitly state the ordering dependency (call search_locations before search_journeys), leaving no room for misselection.
All three tools follow a strict verb_noun pattern (list_providers, search_locations, search_journeys) in consistent snake_case. The 'search_' prefix is used coherently for the two query tools and 'list_' for enumeration.
Three tools is minimal but each occupies a necessary stage of the search pipeline, with no filler. It sits at the thin edge of the range, but the narrow single-purpose domain justifies it.
The surface covers provider discovery, location resolution, and one-way journey search, forming a coherent lifecycle, but only one-way trips are supported — no round-trip or return-date search, and no way to fetch details for a specific journey beyond the search result.