Bundle
@ottotheagent/otto-dsh
Book real flights, hotels, and cars with Otto from DeepSeek Harness (dsh). Self-contained: a stdio MCP proxy that runs Otto's device-grant OAuth and fronts Otto's remote /mcp — flight, hotel, car, trip planning, itinerary.
- Source
- ottotheagent
- stars
- 2 stars
- License
- Apache-2.0
- Updated
- Updated 11 days ago
Readme
# Otto Travel — DeepSeek Harness (dsh) plugin
**Created**: 2026-08-14 · **Last Updated**: 2026-08-14
Book real flights, hotels, and cars with Otto from inside [DeepSeek Harness
(`dsh`)](https://github.com/deepseek-ai/deepseek-harness). Bookings execute
inside Otto (real Spotnana PNR, the authenticated user's stored payment method).
This repo is **self-contained**: it ships a small stdio MCP proxy that runs
Otto's **device-grant OAuth** and fronts Otto's OAuth-protected `/mcp` endpoint.
`dsh` launches it via `npx`, so there's nothing else to install and no API key.
(It shares the same OAuth approach as Otto's OpenClaw and Claude connectors; each
integration keeps its own copy of the small auth core.)
## What you get
Otto's tools land in the model namespace as **`mcp__otto__<tool>`**:
`otto_setup` · `search_flights` · `query_flights` · **`book_flight`** ·
`search_hotels` · `get_hotel_rooms` · `book_hotel` · `get_bookings` ·
`cancel_booking` · `read_skill` · `read_preferences` / `write_preference` ·
`read_loyalty_programs` / `write_loyalty_program` · `task_status`
## Setup
Zero to a booked trip, in five steps.
### 1. Prerequisites
- [DeepSeek Harness (`dsh`)](https://github.com/deepseek-ai/deepseek-harness)
installed and working.
- Node / `npx` on your `PATH` (already there — dsh is Node-based).
- An Otto account you can sign into (or create one during step 4). Booking
requires an **enabled** Otto user with a traveler profile + payment method —
see [Who can actually book](#who-can-actually-book-gates).
### 2. Add Otto to your dsh composition
Add this entry to your `cordis.yml` (or a profile patch) — the full file is
[`cordis.otto.patch.yml`](./cordis.otto.patch.yml):
```yaml
- id: mcp-otto
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: otto
transport: stdio
command: npx
args: ['-y', 'github:ottotheagent/otto-dsh']
```
If your dsh build supports bundle install, this does the same:
```bash
dsh plugin add github:ottotheagent/otto-dsh
```
`npx` builds and runs the bundled proxy on first launch — nothing else to
install, no API key.
> After this package is published to npm, replace `github:ottotheagent/otto-dsh`
> with `@ottotheagent/otto-dsh`.
### 3. Start dsh
Boot your dsh profile as usual. Otto's tools now appear in the model namespace as
`mcp__otto__*` — including `mcp__otto__otto_setup`.
### 4. Authorize Otto (one time)
Ask the agent to do anything travel-related, e.g.:
> Plan a trip: SFO to JFK next Tuesday, cheapest nonstop.
On the first call the agent runs `otto_setup`, which **opens the approval page in
your browser automatically** (and prints the URL as a fallback). If you're
already signed into Otto, it's one click — **Approve**. Tokens then cache at
`~/.otto/mcp-tokens.json` and refresh automatically, so you won't be asked again.
(Auth is OAuth device grant; there is no key or token to paste. Set
`OTTO_NO_BROWSER=1` for headless environments.)
> **Tip:** to have the dsh agent drive the mechanical setup (add the cordis entry,
> then prompt you to reload + approve), see [`AGENTS.md`](./AGENTS.md) — it tells
> the agent to do the config and relay the approval, but never approve for you.
### 5. Search & book
Continue the conversation. The agent uses `search_flights` / `query_flights` /
`book_flight` (and the hotel/car tools) to find options and book. **Bookings are
real** — a live PNR on your Otto account, charged to your stored payment method.
> **Non-prod endpoint:** `export OTTO_MCP_URL="https://<stg-host>/mcp"` before
> booting dsh to point at a non-production Otto.
## Who can actually book (gates)
- The authenticated user must be a **provisioned, enabled Otto user** (a real Otto
account with a Spotnana traveler profile + payment method). Sign-up /
provisioning happen in Otto's hosted authorize flow — the same onboarding path
as the Claude and OpenClaw connectors. The connector authenticates; it does not
create accounts or capture payment on its own.
- **Single traveler per PNR** — `book_flight` books one traveler. To book for
someone who granted you delegate access, use `list_managed_travelers` (books
*as* them, not N pax on one ticket).
## Build / run from source
```bash
npm install
npm run build
node dist/index.js # speaks MCP over stdio; arg or $OTTO_MCP_URL sets the endpoint
```
## Smoke test
[`smoke/`](./smoke) drives one real booking turn through dsh using the
`deepseek-harness-sdk`. See [`smoke/README.md`](./smoke/README.md).
## Notes
- **dsh is developer-preview (rc)** — the `dsh-mcp-client` config schema can shift
between releases. This mount matches the current docs (`transport: stdio` +
`command`/`args`); re-verify with `dsh --dump-config` after upgrading dsh.
- The bundled proxy (`src/`) is a per-repo copy of Otto's small OAuth + MCP core;
the authoritative copy lives with Otto's other connectors.
## License
Apache-2.0. See [LICENSE](./LICENSE) and [NOTICE](./NOTICE).
Install
dsh plugin --profile web add github:ottotheagent/otto-dsh
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install ottotheagent-otto-dsh from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.