Skip to content

Keeeeeeeks/trenchcoat-mpp

Repository files navigation

Trenchcoat

On the internet, no one knows you're three raccoons in a trenchcoat.

Trenchcoat

Three raccoons. One trenchcoat. Unlimited Uber Eats.

Trenchcoat is an MCP tool server + browser automation that lets AI agents order food, buy things, deliver them, and coordinate with people — on behalf of their human.

What This Does

An AI agent can:

  • Order food from UberEats, DoorDash, or any delivery platform via browser automation
  • Pay for things with virtual Visa cards (Laso Finance) or saved payment methods
  • Deliver anything via Uber Direct courier
  • Call people with AI voice calls (StablePhone)
  • Send emails (StableEmail)
  • Find places via Google Maps geocoding and search
  • Send/receive SMS via Twilio

Architecture

Human: "Order me a bacon egg and cheese"
  │
  ▼
Three Raccoons in a Trenchcoat (any AI agent)
  │
  ├── MCP Server (31 tools)         ← API-based actions
  │   ├── pay    (Laso virtual cards, Venmo, PayPal)
  │   ├── browse (Browser Use cloud automation)
  │   ├── deliver (Uber Direct courier)
  │   ├── call   (StablePhone AI voice calls)
  │   ├── email  (StableEmail)
  │   ├── maps   (Google Maps geocoding/search)
  │   ├── sms    (Twilio + sms4sats)
  │   └── profile (encrypted user profile)
  │
  └── Playwright (local browser)    ← For sites that block bots
      └── Human logs in → Agent takes over → Places order

Quick Start

1. Install

git clone https://github.com/Keeeeeeeks/tempohack.git
cd tempohack
npm install
npx playwright install chromium

2. Set Up Environment

cp .env.example .env
# Fill in your credentials (see Environment Variables below)

3. Generate Encryption Key

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Paste the output as PROFILE_ENCRYPTION_KEY in .env

4. Set Up Tempo (for MPP services)

# Install Tempo CLI
curl -fsSL https://tempo.xyz/install | bash

# Log in (requires browser/passkey)
tempo wallet login

# Check balance
tempo wallet -t whoami

5. Connect to Your Agent

Add to your agent's MCP config:

{
  "mcpServers": {
    "tempohack": {
      "command": "npx",
      "args": ["tsx", "src/index.ts"],
      "cwd": "/path/to/tempohack",
      "env": {
        "PROFILE_ENCRYPTION_KEY": "your-key-here"
      }
    }
  }
}

Food Ordering (The Main Event)

Why Browser Automation?

Most food delivery platforms (UberEats, DoorDash, Grubhub, Seamless) do not expose public ordering APIs. The Uber Eats API is merchant-side only (for restaurants managing their store), not consumer-side. DoorDash, Grubhub — same story. There is no POST /orders endpoint for placing food orders as a customer.

This means the only way for an agent to order food is to drive a real browser, just like a human would.

Why Local Playwright (Not Cloud Browsers)?

We tried three browser approaches. Only one works:

Approach Result
Browser Use (cloud, via Tempo/MPP) Blocked by Cloudflare/Arkose CAPTCHAs on UberEats and DoorDash. Cloud browser fingerprints are detected.
Browserbase (cloud, stealth browsers) Same problem — major delivery platforms actively detect and block headless/cloud browsers.
Local Playwright (your machine, real Chrome) Works. Launches a real Chrome window the human can see and interact with. Uses Chrome DevTools Protocol (CDP) on port 9222 for agent control.

Local Playwright works because:

  • It runs a real Chrome binary on the user's machine — same fingerprint as normal browsing
  • The human logs in manually — handles 2FA, CAPTCHAs, and account verification
  • The agent connects via CDP after login — takes over an already-authenticated session
  • Session cookies persist in a local profile directory (/tmp/uber-profile)

The Auth Handoff Pattern

This is the core pattern for ordering from any site that doesn't have an API:

1. Agent launches visible Chrome    →  Human can see the browser
2. Human logs in                    →  Handles 2FA, CAPTCHAs, bot detection
3. Human says "I'm logged in"      →  Agent connects via CDP port 9222
4. Agent takes over                 →  Searches, selects, customizes, checks out
5. Agent confirms with human        →  "BEC from Brooklyn Bread, $11.70, 30 min. Place it?"
6. Human approves                   →  Agent clicks Place Order

Limitations

Things an agent cannot do on sites without ordering APIs:

  • Log in — 2FA, CAPTCHAs, and phone verification require a human
  • Create accounts — Same auth wall problem
  • Bypass bot detection — Cloud browsers get fingerprinted and blocked
  • Operate without a visible browser — Headless mode gets detected; the human needs to see and potentially interact with the browser
  • Handle payment 3D Secure challenges — Some card transactions trigger additional verification
  • Guarantee speed — DOM structures change, elements load asynchronously, modals pop up unexpectedly

Things an agent can do once the human is logged in:

  • Search for restaurants and food items
  • Navigate menus and extract item data from the DOM
  • Select items, customize orders, add to cart
  • Set delivery address and preferences
  • Review totals and place orders
  • Track order status

The Agent's Ordering Playbook

See AGENT_INSTRUCTIONS.md for the full step-by-step flow that agents should follow. The key principles:

  • Always present choices — don't silently pick restaurants or menu items
  • Check distance — use Maps to verify the restaurant is near the human
  • Ask about customizations in plain English — "toasted? what bread? extras?"
  • Batch Playwright actions — do multiple steps per script, don't reconnect every time
  • The whole flow should take 2-3 minutes, not 15

Launching the Browser

# From the project root:
npx tsx <<'EOF'
import { chromium } from 'playwright';
const context = await chromium.launchPersistentContext('/tmp/uber-profile', {
  headless: false,
  channel: 'chrome',
  viewport: { width: 1400, height: 900 },
  args: ['--remote-debugging-port=9222']
});
const page = context.pages()[0] || await context.newPage();
await page.goto('https://www.ubereats.com');
console.log('Browser open — log in, then tell your agent to take over');
await new Promise(r => setTimeout(r, 1800000)); // 30 min keepalive
EOF

Connecting After Login

import { chromium } from 'playwright';
const browser = await chromium.connectOverCDP('http://127.0.0.1:9222');
const page = browser.contexts()[0].pages()[0];
// Agent can now control the page

Environment Variables

Variable Required Description
PROFILE_ENCRYPTION_KEY Yes 32-byte hex string for AES-256-GCM encrypted profile storage
TWILIO_ACCOUNT_SID For SMS Twilio Account SID
TWILIO_AUTH_TOKEN For SMS Twilio Auth Token
TWILIO_PHONE_NUMBER For SMS Your Twilio phone number (local, not toll-free)
UBER_DIRECT_CLIENT_ID For delivery Uber Direct OAuth client ID
UBER_DIRECT_CLIENT_SECRET For delivery Uber Direct OAuth client secret
UBER_DIRECT_CUSTOMER_ID For delivery Uber Direct customer/org ID
SMS4SATS_API_KEY For disposable numbers sms4sats.com API key (Lightning-funded)

No env vars needed for Tempo-backed services — Maps, Email, Phone Calls, Browser Use, Pay, and image generation all work through the Tempo CLI which is authenticated separately.

MCP Tools (31 total)

Pay (Laso Finance via Tempo)

  • pay_create_card — Create virtual Visa ($5-$1000)
  • pay_card_status — Poll until card is ready
  • pay_balance — Check wallet balance
  • pay_venmo — Send money via Venmo
  • pay_paypal — Send money via PayPal

Browse (Browser Use via Tempo)

  • browse_website — AI browser automation (cloud browser)
  • browse_status — Check task status
  • browse_result — Get task output
  • browse_stop — Stop a running task

Maps (Google Maps via Tempo)

  • maps_geocode — Address to lat/lng
  • maps_places — Search for restaurants, stores, etc.
  • maps_directions — Get directions + distance

Email (StableEmail via Tempo)

  • send_email — Send email ($0.02)

Call (StablePhone via Tempo)

  • call_phone — AI voice call ($0.54)
  • call_status — Get transcript + summary
  • lookup_imessage — Check iMessage availability

SMS (Twilio + sms4sats)

  • sms_send — Send SMS via Twilio
  • sms_inbox — Read inbound SMS
  • sms_list — List sent messages
  • sms_buy_number — Buy a phone number
  • sms_list_numbers — List your numbers
  • sms_disposable_receive — Disposable anonymous number (sms4sats)
  • sms_disposable_status — Poll for received code
  • sms_disposable_cancel — Cancel order
  • sms_disposable_services — List available services

Profile (Local encrypted storage)

  • profile_set — Save name, phone, address, delivery prefs
  • profile_get — Read saved profile

Deliver (Uber Direct)

  • deliver_quote — Get delivery quote
  • deliver_create — Dispatch courier
  • deliver_status — Track delivery
  • deliver_cancel — Cancel delivery

Project Structure

src/
├── index.ts              # MCP server entrypoint (31 tools)
├── tools/
│   ├── pay.ts            # Laso Finance virtual cards
│   ├── browse.ts         # Browser Use cloud automation
│   ├── maps.ts           # Google Maps geocoding/search
│   ├── email.ts          # StableEmail
│   ├── call.ts           # StablePhone AI voice calls
│   ├── sms.ts            # Twilio + sms4sats SMS
│   ├── profile.ts        # Encrypted user profile
│   └── deliver.ts        # Uber Direct courier
├── lib/
│   ├── tempo.ts          # Shared Tempo CLI wrapper
│   ├── crypto.ts         # AES-256-GCM encrypt/decrypt
│   └── types.ts          # TypeScript interfaces
└── webhook/              # (Phase 2) Uber Direct webhooks

stable-sms/               # StableSMS MPP service
├── src/
│   ├── index.ts          # Express + mppx payment middleware
│   ├── twilio.ts         # Twilio API client
│   └── sms4sats.ts       # sms4sats API client

Key Learnings

Browser Automation

  1. No food delivery platform has a consumer ordering API. UberEats, DoorDash, Grubhub — all merchant-side only. Browser automation is the only path.
  2. Cloud browsers get CAPTCHA'd. UberEats and DoorDash detect Browser Use / Browserbase. Local Playwright with a real Chrome binary is the only thing that works.
  3. The auth handoff pattern is the killer workflow. Human logs in (handles 2FA/CAPTCHA) → Agent takes over via CDP. This generalizes to any authenticated web app.
  4. Every food delivery platform requires phone-verified accounts. No way around it today without a human in the loop for initial auth.

Agent UX

  1. Agents should be conversational, not autonomous. Present 3-5 options at every decision point. Ask about customizations in plain English. Confirm before placing orders.
  2. Check distance before presenting restaurants. Use Maps to avoid suggesting places that are far away.
  3. Extract data from the DOM, not screenshots. page.evaluate() is 10x faster than screenshot → image analysis loops.

Infrastructure

  1. Tempo/MPP services work instantly. Maps, Email, Phone, Pay all work out of the box with just a funded Tempo wallet. No API keys needed.
  2. Toll-free Twilio numbers can't send SMS on trial. Buy a local number, or upgrade to paid.
  3. Email-to-SMS gateways are unreliable. Carriers silently drop emails from unknown senders.

About

tell your agent to order you UberEats, using MPP

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors