Open-source, self-hostable AI executive assistant that places real outbound phone calls on your behalf
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Documented (README)
git clone https://github.com/shatch/banjoTools overview
<img src="assets/logo.png" alt="Banjo logo" width="160" align="right">
# Banjo
**Banjo makes the phone calls you've been putting off.** Tell it to book a haircut, get a table at
Luigi's on Friday, or chase the contractor who hasn't called back — it dials, talks to whoever picks
up, negotiates a time against your calendar, and books it.
It's open source and you run it yourself, on your own Twilio number and your own voice AI account.
Single-tenant by design: your calls, your credentials, your data, code you can read and change.
Banjo is the phone half of a pair. The other half is a Claude Code skill
([`skills/schedule-appointment/`](skills/schedule-appointment/SKILL.md)) that decides whether an errand can
be done online — and only picks up the phone when it can't.
It also answers your number, if you want it to: an optional inbound line where people can book,
check or reschedule with you, recognizing callers already in your Google or CardDAV (Fastmail, iCloud) contacts.
## Hear it
https://github.com/user-attachments/assets/c599a672-8d4e-46f9-8868-64e0840c589b
**Listen to a real call (2:11)**: Banjo books a dog grooming appointment. The
call and the calendar are real; the groomer is role-played. Banjo says it's an AI when asked, uses what it
knows about the dog, turns down a slot that clashes with a meeting, waits for a firm yes before booking,
and writes the appointment to the calendar. This was an early call. Since then, Banjo reads the booking back
before hanging up ([#47](https://github.com/shatch/banjo/issues/47)) and opens every call by saying it's an
AI rather than waiting to be asked ([#8](https://github.com/shatch/banjo/issues/8)).
<details>
<summary>Transcript (auto-transcribed, lightly tidied)</summary>
> **Banjo:** Hi, I'm calling on behalf of Steve about booking a grooming appointment for his dog, Banjo. Is this Claudia's Fabulous Dog Grooming?
>
> **Claudia:** Yes, sorry about that. Claudia's Fabulous Dog Grooming, this call may be recorded. This is Claudia, how can I help?
>
> **Banjo:** Hi Claudia, thanks for taking this. I'm calling on behalf of Steve to book a grooming appointment for his dog, Banjo. A full groom is preferred. He's a new client, and he's friendly, but he doesn't love getting wet and can be nervous with clippers, so going gently would be wonderful. What availability do you have?
>
> **Claudia:** Sorry, am I talking to a real person?
>
> **Banjo:** I'm an AI assistant calling on behalf of Steve. I can help set this up if you're okay proceeding. Could you share what times you have available for a full groom for Banjo?
>
> **Claudia:** Wait, what's the dog's name?
>
> **Banjo:** His name is Banjo. He's Steve's dog.
>
> **Claudia:** What breed, and roughly how big?
>
> **Banjo:** Banjo is a small terrier mix, likely a Cairn Terrier. He's small, friendly, and this would be his first time there.
>
> **Claudia:** A full groom, or just a bath?
>
> **Banjo:** A full groom is preferred, please. If you need to adjust based on what's best for him, that's fine. We'd just like him cleaned up and trimmed.
>
> **Claudia:** I can fit him in Thursday the 24th at 3:30.
>
> **Banjo:** One moment. … Thanks, that time won't work on Steve's side. Could we try another option? If it helps, a start time earlier in the day would be better.
>
> **Claudia:** Friday, I might be able to squeeze him in at 10 in the morning. Let me look.
>
> **Banjo:** Sure, just a second. … Friday at 10 AM should work for Steve. Would you like to book that for Banjo's full groom?
>
> **Claudia:** Yeah, that could probably work.
>
> **Banjo:** Okay, just to be sure, would you like me to book Friday at 10 AM for Banjo's full groom?
>
> **Claudia:** Okay, yes. Friday the 25th at 10 a.m., full groom, 90 minutes. Let's book it.
>
> **Banjo:** One moment. … Great, thanks for confirming. Let me wrap this up.
</details>
## What it does
**On the phone**
- **Books appointments.** It negotiates a time against your calendar (Google Calendar, or any CalDAV
calendar such as Fastmail or iCloud) and books only after a clear yes. Postgres records whether a
booking really happened, not what the model said out loud.
- **Has conversations.** `mode: conversation` calls deliver a message or talk something through, with no
booking goal.
- **Calls later.** `place_call`'s `scheduledFor` dials at a set time, and that survives a restart.
- **Handles voicemail and phone menus.** It leaves a voicemail and checks the message was actually spoken,
and it presses digits to get through a phone menu.
- **Hands a call to you.** Optional cold transfer when the other party asks for a person, with your leg
screened so only pressing 1 connects (`TRANSFER_ENABLED`).
- **Answers your number.** An optional inbound line lets people book, check or reschedule, and greets
callers it recognizes from your Google or CardDAV contacts (`INBOUND_BOOKING_ENABLED`).
**Safeguards**
- **Says it's an AI.** Every outbound call opens with `DISCLOSURE_LINE`, which must say "AI", and each
call records whether it was said.
- **Records only with notice.** Recording is optional (`RECORD_CALLS`), and starts only after Banjo has
said the recording notice.
- **Won't pester anyone.** At most 3 calls to any number in a rolling 24 hours, with no override.
- **Keeps what you choose.** Transcripts are saved only if you turn them on (`PERSIST_TRANSCRIPTS`),
and both transcripts and recordings are deleted after 30 days by default. Logs mask phone numbers
and call content.
**Working with it**
- **11 MCP tools for Claude Code:** place, check, cancel and stop calls, read transcripts, and manage
contacts.
- **Tells you how it went:** an outcome summary after every call, by SMS or [Pushover](https://pushover.net).
- **Tells your agent too:** set `TASK_WEBHOOK_URL` and every finished call is POSTed as a signed JSON
event, so an agent such as OpenClaw or Hermes Agent hears back without polling.
- **Knows your preferences:** an owner profile of standing notes is added to every call (see
[below](#making-it-yours-the-owner-profile)).
- **Easy to run:** `npm run setup` writes a checked `.env`, and `docker compose up` runs the published
amd64/arm64 image. To keep it running when your laptop sleeps, see
[Running Banjo on an always-on Linux host](docs/RUNBOOKS.md#running-banjo-on-an-always-on-linux-host).
See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the full design, [`docs/ROADMAP.md`](docs/ROADMAP.md)
for what's coming next, [`docs/AGENT_SETUP.md`](docs/AGENT_SETUP.md) for connecting Claude Code, Hermes Agent or
OpenClaw, [`docs/RUNBOOKS.md`](docs/RUNBOOKS.md) for operational procedures, and
[`docs/COMPETITIVE_LANDSCAPE.md`](docs/COMPETITIVE_LANDSCAPE.md) for how it compares to other
open-source projects in this space.
[](docs/ARCHITECTURE.md)
## Known limitations
Banjo places real calls and books real appointments, and has done so reliably. It is also a young,
small project. Things worth knowing before you build on it:
- **One voice provider is actually proven.** OpenAI Realtime is the only adapter carrying live
traffic. `openai-live` (GPT-Live) has been tested on real calls but isn't the default. **Gemini
Live and ElevenLabs are scaffolded and unverified** — Gemini additionally emits no caller-side
transcripts at all.
- **AI disclosure is a prompt rule, checked after the call, not enforced.** Banjo is told to open every
call with `DISCLOSURE_LINE` (default: *"Hi, I'm an AI assistant calling on behalf of {name}."*), and
its first line is checked afterwards. A miss is recorded on the call attempt and noted in your
notification, but it isn't prevented.
**If you're in a jurisdiction with AI-disclosure or two-party-consent rules (TCPA/FCC, California
AB 2905), check your own calls.** ([#8](https://github.com/shatch/banjo/issues/8))
- **Recording and transcripts cover outbound calls only.** Recordings live in your Twilio account
(two-track), transcripts in Postgres. Both are off by default. Inbound calls are never recorded.
([#6](https://github.com/shatch/banjo/issues/6))
- **Call transfer is cold, to one fixed number.** Banjo transfers only after the other party says yes,
and the model never chooses who to connect. You get no summary of the call before you're connected,
and Banjo can't stay on the line. If you don't answer, the caller hears `TRANSFER_FALLBACK_MESSAGE`
and the call ends. On the inbound line, only callers already in your contacts can be put through;
anyone else who asks for you is flagged for you to call back, so a robocall can't ring your phone.
([#7](https://github.com/shatch/banjo/issues/7), [#66](https://github.com/shatch/banjo/issues/66))
- **SMS to US numbers needs carrier registration.** Without A2P 10DLC registration, outcome texts are
blocked by the carrier. Pushover needs no registration. See `docs/RUNBOOKS.md`, "SMS notifications
aren't arriving".
- **Logs are redacted, not access-controlled.** Phone numbers are logged with only the last 4 digits,
and voicemail text and raw tool arguments as a length. Error messages from vendors can still quote a
number, and `LOG_TRANSCRIPTS=true` deliberately logs full call text. Treat logs as sensitive.
- **One call at a time.** The inbound line declines anything arriving while another call is live.
- **It needs a publicly reachable hostname**, because Twilio dials back into it over HTTPS and a
WebSocket. See the Quickstart, and
[`docs/spikes/2026-09-21-outbound-registration-worker.md`](docs/spikes/2026-09-21-outbound-registration-worker.md)
for why this is hard to remove.
- **Single-tenant, permanently.** One instance serves one person. See
[`CONTRIBUTING.md`](CONTRIBUTING.md) for what else Banjo deliberately isn't.
## What a call costs
You pay vendors directly. Per-unit prices, checked 2026-09-21:
| What | Price | Source |
| --- | --- | --- |
| Twilio outbound voice, US local number | $0What people ask about banjo
What is shatch/banjo?
+
shatch/banjo is tools for the Claude AI ecosystem. Open-source, self-hostable AI executive assistant that places real outbound phone calls on your behalf It has 2 GitHub stars and its last recorded update is dated 2026-10-10.
How do I install banjo?
+
You can install banjo by cloning the repository (https://github.com/shatch/banjo) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is shatch/banjo safe to use?
+
Our security agent has analyzed shatch/banjo and assigned a Trust Score of 87/100 (tier: Trusted). See the full breakdown of passed checks and flags on this page.
Who maintains shatch/banjo?
+
shatch/banjo is maintained by shatch. The last recorded GitHub activity is dated 2026-10-10, with 16 open issues.
Are there alternatives to banjo?
+
Yes. On ClaudeWave you can browse similar tools at /categories/tools, sorted by popularity or recent activity.
Deploy banjo to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
More Tools
A single CLAUDE.md file to improve Claude Code behavior, derived from Andrej Karpathy's observations on LLM coding pitfalls.
An AI skill that provides design intelligence for building professional UI/UX across multiple platforms.
🪨 why use many token when few token do trick. Viral skill + proxy for coding agents that cuts 65% of tokens by talking like a caveman.
CLI proxy that reduces LLM token consumption by 60-90% on common dev commands. Single Rust binary, zero dependencies
The fastest, litest AI Gateway. Rust core with Python SDK. Call 100+ LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]
Use Claude Code, Codex, VSCode, Pi, and OpenCode (and 6 other harnesses) for free (1.3B+ free tokens) from your terminal, app, IDE, or phone, and now from the browser with native browser sessions (multi-harness + multi-model) like OpenClaw (voice supported + ToS friendly)