Skip to content
dsh.fish
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

  • 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.
Source