Skip to main content
Glama

Italian Bus Search

CI

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.

Related MCP server: soloway-mcp

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.

Requirements

  • Node.js 22.18 or newer

  • npm

Quick start

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.

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:

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.

MCP server

The simplest MCP configuration runs the published package directly with npx:

{
  "mcpServers": {
    "italian-bus-search": {
      "command": "npx",
      "args": ["-y", "italian-bus-search@latest"]
    }
  }
}

Alternatively, build and start the local stdio server:

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.

{
  "mcpServers": {
    "italian-bus-search": {
      "command": "node",
      "args": ["/absolute/path/to/italian-bus-search/dist/mcp/stdio.js"]
    }
  }
}

See MCP interface 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 for modules, seams, data flow, caches, and test strategy.

Development

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; 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 before placing it behind a reverse proxy or running multiple replicas.

Project documentation

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. Report vulnerabilities privately according to SECURITY.md, not through a public issue.

License

Source code is available under the MIT License. The license covers this repository's code, not third-party data, provider trademarks, or access rights to upstream systems.

Available Tools

3 tools
list_providersList Italian bus providersA
Read-onlyIdempotent

List configured journey providers and their status without contacting provider systems.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
providersYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent and non-destructive. The description adds the non-obvious point that no provider systems are contacted, which qualifies the openWorldHint and tells the agent this is fast and cannot fail on network or availability.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero filler; the behavioral caveat is packed into the same clause rather than padding the definition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the return shape ('providers and their status') need not be spelled out. For a no-parameter read-only tool the description covers everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes no parameters and the schema is trivially complete, so there is nothing for the description to clarify. Baseline 4 applies to zero-parameter tools.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List configured journey providers and their status'), and the title narrows it to Italian bus providers. It implicitly separates configuration introspection from the sibling search tools, though it never names them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'without contacting provider systems' implies this is a cheap local config read, useful for checking what is configured before a search. However, it never explicitly says when to call this versus search_journeys or search_locations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_journeysSearch Italian bus journeysA
Read-onlyIdempotent

Search one-way journeys. Use origin and destination IDs or exact names returned by search_locations. Results include official links for continuing manually on provider sites.

NameRequiredDescriptionDefault
dateYesReal future date in YYYY-MM-DD format
limitNo
adultsNo
originYesExact location name or ID returned by search_locations
childrenNo
providerNoProvider ID; omit to search every provider
destinationYesExact location name or ID returned by search_locations

Output Schema

NameRequiredDescription
totalYes
errorsYes
journeysYes
truncatedYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, open-world, non-destructive, so the safety profile is covered. The description adds genuinely useful context beyond that: results are informational and include official provider links for manual continuation, making clear the tool does not book or transact.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the action, followed by the prerequisite and the result shape. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description still notes the useful link payload. Combined with annotations and a 57%-covered schema, only minor gaps remain (passenger/limit semantics, date validity), which the schema largely carries.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 57%, with origin/destination/date already documented in the schema. The description reinforces the origin/destination format convention but says nothing about provider, adults, children, or limit, so it adds only marginal meaning over the structured fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Search one-way journeys") and the title narrows it to Italian bus journeys. It implicitly distinguishes itself from search_locations by naming that sibling as the source of valid origin/destination values, though it does not explicitly contrast with list_providers.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear prerequisite: origin/destination must be IDs or exact names returned by search_locations, which tells the agent to call that tool first. There are no explicit exclusions or when-not-to-use conditions, but the calling context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_locationsSearch Italian bus locationsA
Read-onlyIdempotent

Find provider location IDs and exact names. Call this before search_journeys, then reuse an ID or exact name from the result.

NameRequiredDescriptionDefault
limitNo
queryYesPartial city, stop, or location name
providerNoProvider ID; omit to search every provider

Output Schema

NameRequiredDescription
totalYes
errorsYes
locationsYes
truncatedYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive and open-world, so the safety profile is covered. The description adds genuinely new behavioral context: this is a prerequisite step whose results must be fed into search_journeys as an ID or exact name, which is the key constraint an agent needs. It does not mention partial-match semantics or result cap behavior, so it stops short of full transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler, with the purpose front-loaded and the workflow instruction second. Every clause carries actionable information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-format explanation is unnecessary, and the description covers purpose plus the chaining dependency. It could do slightly more for the provider/limit parameters, but nothing critical to a correct call is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67% — query and provider are documented inline, but limit is not. The description adds no parameter-level detail (no mention of limit, provider omission, or matching rules), so it does not compensate for the uncovered parameter. Baseline 3 applies when the schema carries most of the load.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (find location IDs and exact names), and the emphasis on IDs/exact names distinguishes it from search_journeys, which returns trips rather than locations. It never names list_providers as a related lookup, so sibling differentiation is partial rather than complete.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Call this before search_journeys' gives an explicit ordering constraint and tells the agent how to consume the output (reuse an ID or exact name). What's missing is guidance on the provider parameter — e.g., that list_providers supplies valid provider IDs — so one branch of usage is left implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.2
    • First observedlist_providers
    • First observedsearch_journeys
    • First observedsearch_locations

TDQS

A4.1/5.0

Scored across 3 tools

Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count4/5

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.

Completeness3/5

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.

Maintenance

ActivityNo data
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Live intercity bus-trip search across Ukraine and Europe — real-time prices, seats, carriers, cheapest-day-of-month calendar, and trip details with passenger discounts. Read-only, no API key; also available as a hosted remote endpoint at https://mcp.soloway.com.ua/mcp.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables searching for buses and trains, and when direct routes are unavailable, it provides the underlying data needed to assemble multi-leg itineraries with transfers.
    6 npm
    ISC
  • A
    license
    A
    quality
    B
    maintenance
    Enables MCP-compatible AI agents to search live Virail transport connections across trains, buses, flights, ferries, and carpooling, returning real prices, schedules, and booking links.
    1
    MIT