Skip to main content
Glama
francisschmaltz

DoorDash CLI MCP Server

DoorDash CLI MCP server

Local Streamable HTTP MCP wrapper for DoorDash CLI. It lets an MCP client use DoorDash through the macOS CLI and the credentials in the user's Keychain.

The server exposes every authenticated service command in DoorDash CLI v0.2.1. login, help, and version remain local CLI operations.

Setup

Requirements:

  • macOS on Apple Silicon

  • Node.js 22 or newer

  • DoorDash CLI v0.2.1 for Darwin ARM64

The DoorDash release is local vendor material and is not committed. Copy the extracted release into ./doordash-cli/, then point the tracked root shim at its executable:

mkdir -p ./doordash-cli
cp -R /path/to/extracted/doordash-cli-release/. ./doordash-cli/
ln -sfn doordash-cli/dd-cli-v0.2.1-darwin-arm64 ./dd-cli
chmod +x ./doordash-cli/dd-cli-v0.2.1-darwin-arm64

The executable must now be:

./doordash-cli/dd-cli-v0.2.1-darwin-arm64

Sign in locally and install dependencies:

./dd-cli login
npm install
cp .env.example .env

Generate a secret with openssl rand -hex 32, paste it into ADMIN_ACCESS_TOKEN in .env, then start the server:

npm start

Open http://127.0.0.1:8787/ and enter the admin secret. Generate an MCP bearer token, copy it immediately, and put it in the MCP client's Authorization/Bearer-token setting. Only the MCP token's SHA-256 hash is stored.

The MCP endpoint is:

http://127.0.0.1:8787/mcp

All MCP requests require a valid bearer token.

Open WebUI in Docker

Listen on the Mac's network interface:

HOST=0.0.0.0

In Open WebUI configure:

  • Type: MCP (Streamable HTTP)

  • URL: http://host.docker.internal:8787/mcp

  • Authentication: Bearer token generated by the local UI

The admin UI, token APIs, and raw activity log require the admin secret. A successful web login receives an HttpOnly session cookie. Scripts can instead send Authorization: Bearer <ADMIN_ACCESS_TOKEN>. The /mcp endpoint keeps its separate MCP bearer tokens.

Related MCP server: local-mcp

Token permissions

Each token has its own Checkout & card details checkbox.

Unchecked tokens receive the complete non-purchase tool set. Checked tokens also receive:

  • list_payment_methods

  • order_submit

Changing the checkbox changes that token immediately. There is no global purchase switch. Revoking a token invalidates it immediately.

Payment output contains only card brand, last four digits, expiry, and default status. DoorDash CLI cannot return a full card number or CVC, and the wrapper does not expose provider/payment IDs.

order_submit is deliberately obnoxious:

  • It requires the previously confirmed total and delivery address.

  • It requires an explicit tip, including an explicit zero.

  • It requires the confirmed default card, account default, or work budget.

  • It re-previews immediately before submission and stops on drift.

  • It records the cart before spawning the purchase command.

  • It never retries a cart with any recorded submission attempt.

  • It polls order_status after DoorDash accepts the submission.

A bearer token authenticates a caller. It is not purchase consent; the tool's confirmation contract is still mandatory.

MCP tools

Every typed tool advertises an MCP outputSchema. Calls return a readable result plus the same machine payload through both client-compatible channels:

  • content[0].text is a short readable summary.

  • content[1].text is minified JSON, exactly equal to JSON.stringify(structuredContent).

  • structuredContent is the stable, versioned machine result.

Errors also return the JSON text copy and isError: true. This keeps recovery details visible to MCP clients that ignore structuredContent. Cart preflight errors put missing choices in the readable text and tell callers not to repeat unchanged input.

Tool-to-tool handoffs use the response field names directly. Snake-case fields such as address_id, store_id, menu_id, item_id, cart_uuid, cart_item_id, order_uuid, budget_id, and promotion IDs are the preferred inputs everywhere they are consumed. Existing camel-case inputs remain aliases. If both forms are sent, they must match.

The contract stays compact. Money is a floating-point dollar number rounded to two decimals. An ETA is one delivery_time string, including a range such as "25-35 min". Distance is one display string, preferring miles when DoorDash provides them. Unavailable optional fields are omitted. Checkout, tracking, and group-cart links appear only when DoorDash supplied them.

Typed tools discard unknown CLI fields instead of leaking the upstream payload. See MCP response examples for complete wire examples. run remains a generic raw_cli escape hatch; its result is not a stable typed contract.

Addresses

  • list_addresses

  • set_default_address

Address changes are account-wide. DoorDash CLI has no per-cart address override, and checkout URLs do not pin an address. Delivery carts, previews, and submissions use the account-wide default address.

Discovery and catalogs

  • search_restaurants

  • find_nearby_stores

  • get_store_details

  • get_menu

  • get_restaurant_item_details

  • find_items

  • get_item_details

  • build_grocery_list

search_restaurants and find_nearby_stores always call list_addresses and use the coordinates of the account-wide default address. They do not accept a location override. The wrapper returns an error instead of guessing when DoorDash has no marked default or the default has no coordinates.

get_item_details automatically routes i_-prefixed menu IDs through the restaurant modifier endpoint and can resolve an omitted menu_id. Other item IDs continue to use grocery or retail details.

Carts

  • list_carts

  • show_cart

  • add_cart_items

  • remove_cart_item

  • delete_cart

The add operation is additive and non-idempotent. Send all requested lines in one call. Before making one DoorDash cart write, the wrapper fetches current details for every i_-prefixed restaurant item and validates the full batch. If a required choice is unresolved, it returns every modifier group and makes no cart changes. A required group with only one available choice is selected automatically; preferences with multiple choices are never guessed.

Plain-language choices may be sent per line in requested_options, such as ["Rotisserie Chicken", "Sweet Corn", "Utensils"]. They are resolved against the current modifier tree, and any unmatched choice blocks the entire batch. A customized name such as Spicy TanTan with Sweet Corn is also recognized for compatibility, then normalized back to the real menu name. Prefer requested_options; name itself does not customize an item.

Exact choices may instead be copied into nested_options as {"option_id":"o_...","name":"Chosen option"}; optionId and legacy id remain accepted aliases. Do not pass modifier group IDs such as e_.... Ordinary selections stay flat, while options is only for choices that expose another nested modifier group.

After a successful add, add_cart_items automatically creates and returns a browser checkout_url. If DoorDash adds the items but link creation fails, the tool preserves the cart result and tells the caller to use create_checkout_link.

When cart_uuid is omitted, the wrapper checks for an active cart at that store before adding. An empty cart left by an earlier failed add is reused automatically. A nonempty cart returns ACTIVE_CART_EXISTS with recovery_tool: show_cart instead of silently duplicating items. Inspect it, then return its checkout link when it already matches, explicitly extend it using its cart_uuid, or delete and replace it.

Orders

  • list_orders

  • reorder

  • preview_order

  • create_checkout_link

  • get_receipt

  • order_status

  • order_submit — permission-gated

Preview supports scheduled orders, delivery/pickup, Priority delivery, credit opt-out, and work-benefit budgets.

Payments and promotions

  • list_payment_methods — permission-gated

  • list_promos

  • apply_promo

  • remove_promo

Server utilities

  • activity

  • run

run is a compatibility escape hatch for future safe CLI commands. It permanently blocks login, help, version, payment methods, and order submission. Sensitive operations must use their typed tools.

Every CLI invocation automatically uses root --json-output and appends:

--intent cli-usage

CLI limitations

DoorDash CLI v0.2.1 does not support:

  • Adding or changing saved payment methods

  • Per-cart delivery addresses

  • Creating or deleting saved addresses

  • Setting an existing cart line to an absolute quantity

  • Merchant tips for pickup

  • Agent checkout for restricted or age-gated items

Browser checkout is the fallback for those cases.

Storage and activity

SQLite is used only for bearer-token hashes and the duplicate-submission ledger:

./.data/doordash-mcp.sqlite

The directory is ignored by Git. DoorDash owns carts and orders; the macOS Keychain owns CLI credentials.

The dashboard and activity keep the last 100 MCP-routed CLI calls in memory. Commands and CLI results are stored raw and completely unredacted, including coordinates, addresses, URLs, payment metadata, and error details. Anyone with dashboard or MCP activity access can read them. The log resets on restart. Direct terminal calls do not appear.

Authenticated raw activity JSON:

http://127.0.0.1:8787/activity

Configuration

Variable

Default

Purpose

HOST

127.0.0.1

Listen address

PORT

8787

Listen port

ADMIN_ACCESS_TOKEN

required

Admin UI and API secret; minimum 16 characters

DD_CLI_PATH

./dd-cli

DoorDash executable

DD_CLI_TIMEOUT_MS

120000

Per-command timeout

DD_MCP_DB_PATH

./.data/doordash-mcp.sqlite

Token and submission SQLite database

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    B
    quality
    D
    maintenance
    Enables AI agents to search restaurants, browse menus, manage carts, and place orders on DoorDash programmatically. It utilizes a headless browser to interact with DoorDash's GraphQL API and bypass anti-bot protections for the full delivery lifecycle.
    Last updated
    22
    2
  • A
    license
    -
    quality
    D
    maintenance
    Enables running MCP tools against local MLX models on your Mac, with hardware-aware configuration, CLI streaming, and a dashboard for routing and monitoring.
    Last updated
    6,603
    Sleepycat
  • A
    license
    -
    quality
    A
    maintenance
    Provides programmatic access to Grubhub's food delivery platform, enabling restaurant search, menu browsing, cart management, order placement, and delivery tracking through MCP tools.
    Last updated
    MIT

View all related MCP servers

Related MCP Connectors

  • A paid remote MCP for CLI tool MCP, built to return verdicts, receipts, usage logs, and audit-ready

  • Monday.com MCP — wraps the Monday.com GraphQL API (BYO API key)

  • Product Hunt MCP — wraps the Product Hunt GraphQL API v2 (api.producthunt.com)

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/francisschmaltz/doordash-cli-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server