Skip to main content
Glama

Ferry VN SDK · CLI · MCP

CI License: Apache-2.0

Official TypeScript SDK, command-line tool and MCP server for the Ferry VN partner API. Travel agencies, OTAs, internal staff and AI agents use them to search voyages across Vietnam's ferry operators, read seat maps and prices, and create and manage bookings.

Package

Install

What it is

@ferryvn/sdk

npm i @ferryvn/sdk

Zero-dependency fetch client (Node ≥ 20, Bun, Deno, edge runtimes; ESM + CJS), typed from the real API, with a booking builder and webhook helpers

@ferryvn/cli

npm i -g @ferryvn/cli

ferry: voyages, prices, seat maps, bookings from a spreadsheet, customers, cancellations; table / JSON / CSV output

@ferryvn/mcp

npx -y @ferryvn/mcp

ferry-mcp: MCP server for Claude and other AI agents; read-only by default, writes are opt-in and confirmed

Status: v1.0.0 is on GitHub Releases. The npm packages are not published yet. Until they are, use the self-contained Claude Desktop bundle (ferry-mcp.mcpb) from the release, or build from source with npm ci && npm run build.

Documentation: docs.ferry.vn/developers (integration guide, in Vietnamese) · api.ferry.vn/docs (API reference) · package references: SDK · CLI · MCP

Before you start

  • API key. An organization admin creates it in the Ferry VN dashboard. It is shown once, never expires, and carries organization-admin power: keep it server-side. The SDK refuses to run with a key in a browser unless you opt in.

  • Environments. production (https://api.ferry.vn, the default) and uat for integration testing. UAT is not a sandbox: issuing tickets there reaches the real operator and spends your organization's real balance.

Related MCP server: Campspot MCP

Quick start

SDK

import { FerryClient } from '@ferryvn/sdk';

const ferry = new FerryClient({ apiKey: process.env.FERRY_API_KEY }); // environment: 'uat' while integrating

const [from] = await ferry.locations.find('Rạch Giá');
const [to] = await ferry.locations.find('phu quoc');
const { data: voyages } = await ferry.voyages.search({ date: '2026-10-20', departureId: from.id, destinationId: to.id });

const [customer] = await ferry.customers.search('0901234567');
const { booking } = await ferry.bookingDrafts.create({
  customerId: customer.id,
  ordererName: 'Nguyễn Văn A',
  contactEmail: 'a@example.com',
  depart: {
    voyageId: voyages[0].voyage.id,
    seats: ['A1'],
    passengers: [{ name: 'Nguyen Van A', dateOfBirth: '1990-05-01', socialId: '079090000001', homeTown: 'Cần Thơ' }],
  },
});

The booking builder takes a voyage, seat names and passengers. It picks each passenger's ticket type by age with the operator's rules, matches prices, and checks free seats and duplicate ID numbers before anything is sent.

CLI

ferry login                       # paste the key (hidden); verified and stored 0600
ferry voyages search --from "Rạch Giá" --to "Phú Quốc" --date tomorrow
ferry seats <voyageId>
ferry booking draft --customer 1001 --orderer-name "Nguyễn Văn A" --email a@example.com \
  --voyage <voyageId> --seats A1,A2 --passengers passengers.csv --out booking.json
ferry booking create --file booking.json

Passenger lists come from CSV (Excel: Save As → "CSV UTF-8") or JSON; see examples/. Profiles keep production and UAT keys apart.

MCP

claude mcp add ferryvn -e FERRY_API_KEY=<key> -- npx -y @ferryvn/mcp

Claude Desktop: open ferry-mcp.mcpb from the release and enter your key. Other clients, Streamable HTTP mode and Docker: see the MCP README.

What moves money

Action

Effect

Create a booking

Charges nothing and holds no seats. The booking starts unpaid, with a payment deadline.

Issue tickets (confirmToIssue)

Charges your organization's balance and credit (a customer shortfall is recorded as debt), then orders from the operator; automated operators can take minutes. The CLI asks for confirmation. The MCP server never exposes it.

Retries

The API has no idempotency keys, so the SDK never retries a POST. After a network error, check booking list before sending again.

Webhooks

Not signed and delivered once, with no retries. Put a secret token in the URL (safeEqual) and reconcile through the API.

MCP write tools (create_customer, create_booking, request_cancellation) are off unless FERRY_MCP_ENABLE_WRITES=true; each call is confirmed by the user, counted against a write budget and written to an audit log. Payments, ticket issuance, balances and organization administration are never available over MCP.

API coverage

Area

SDK

CLI

MCP

Locations, routes, operators

locations, routes, operators

ferry locations, routes, operators

search_locations, list_routes

Voyages, calendar

voyages, voyageCounts

ferry voyages search, calendar

search_voyages, get_voyage_calendar

Route prices

prices.forRoute

ferry prices

get_route_prices

Seat maps, prices

boatLayouts + flattenSeatMap

ferry seats

get_seat_map

Customers

customers

ferry customers

find_customers, create_customer*

Bookings

bookings, bookingDrafts

ferry booking …

quote_booking, get_booking, list_bookings, create_booking*

Issue tickets (moves money)

bookings.confirmToIssue

ferry booking issue (confirmed)

never

Orders

orders

ferry orders

via get_booking

Cancellations

cancelTicketRequests

ferry cancel … (confirmed)

list_cancel_requests, request_cancellation*

Organization, transactions, debts

organization, transactions, debtLedger

ferry account, transactions, debts

get_account

Vouchers

vouchers

ferry vouchers

list_vouchers

Disruptions

disruptions

ferry disruptions

get_disruptions

Webhooks

parseWebhook, safeEqual

—

—

Anything else

ferry.request()

ferry api

—

* only with FERRY_MCP_ENABLE_WRITES=true (over --http, also FERRY_MCP_HTTP_ALLOW_WRITES=true); every call is confirmed by the user.

How the types stay correct

  • openapi/partner.json is extracted from the backend source, not written by hand.

  • scripts/filter-openapi.ts keeps only what an API key can call and corrects responses whose Swagger metadata is wrong; each correction is verified in the backend code and marked x-ferry-sdk-patch. The result is openapi/sdk.json.

  • Types are generated from openapi/sdk.json with openapi-typescript; CI fails when they are stale.

  • A nightly read-only contract suite (contract/) runs against UAT to catch backend drift.

Tiếng Việt

Bộ công cụ chính thức để đại lý, OTA, nhân viên nội bộ và AI agent làm việc với API đối tác của Ferry VN: tra cứu chuyến tàu cao tốc của các hãng, sơ đồ ghế, giá vé, tạo và quản lý đơn.

  • SDK (@ferryvn/sdk): client TypeScript cho API đối tác (/api/v1/...), xác thực bằng header Authorization: Bearer <key>. Có timeout, chỉ tự retry GET, lỗi có kiểu kèm mã nghiệp vụ (FerryErrorCode) và x-request-id để tra log. Booking builder: chỉ cần mã chuyến, tên ghế và thông tin hành khách; SDK tự chọn loại vé theo tuổi (theo luật từng hãng), khớp giá, kiểm ghế trống và CCCD trùng trước khi gửi.

  • CLI (ferry): ferry voyages search --from "Rạch Giá" --to "Phú Quốc" --date tomorrow, ferry seats <voyageId>, ferry customers --search 0901234567. ferry booking draft ... --passengers khach.csv đọc danh sách hành khách từ CSV (Excel: Save As → "CSV UTF-8") hoặc JSON; ferry booking list --output csv > don.csv xuất cho kế toán. Hỗ trợ nhiều profile (production / UAT).

  • MCP (ferry-mcp): cho Claude Desktop / Claude Code tra cứu tuyến, chuyến, lịch chuyến, sơ đồ ghế, khách hàng, đơn hàng, sự cố thời tiết. Công cụ ghi chỉ bật khi FERRY_MCP_ENABLE_WRITES=true và lần ghi nào cũng phải được người dùng xác nhận. Không bao giờ có xuất vé, thanh toán, điều chỉnh số dư hay quản trị tổ chức.

Lưu ý:

  • API key do quản trị viên đại lý tạo trên Dashboard, chỉ hiển thị một lần và có quyền quản trị tổ chức: chỉ dùng phía server.

  • UAT không phải sandbox: xuất vé trên UAT kết nối thẳng tới hãng tàu và trừ tiền thật của tài khoản đại lý.

  • Tạo booking không trừ tiền, không giữ ghế. Xuất vé (confirmToIssue) trừ số dư và hạn mức của tổ chức (phần khách thiếu ghi nợ, PaidWithDebt); CLI hỏi xác nhận, MCP không hỗ trợ.

  • Không có idempotency key ⇒ SDK không bao giờ tự retry POST. Lỗi mạng thì kiểm tra booking list trước khi gửi lại.

  • Webhook không ký và chỉ gửi một lần: đặt token bí mật trong URL và đối soát định kỳ qua API.

Tài liệu tích hợp: docs.ferry.vn/developers.

Contributing, security, support

  • Development setup, the type-generation pipeline and the release process: CONTRIBUTING.md. Changes: CHANGELOG.md.

  • Maintainer docs (architecture, code standards, codebase summary, deployment, roadmap): docs/.

  • Vulnerabilities: report privately as described in SECURITY.md, never in a public issue.

  • Bugs in these packages: GitHub issues. Account, API key or booking questions: hi@ferry.vn.

License

Apache-2.0. Copyright © 2026 Ferry VN JSC. See NOTICE.

Related MCP Connectors

Related MCP Servers