Skip to main content
ClaudeWave

Open-source, self-hostable AI executive assistant that places real outbound phone calls on your behalf

ToolsOfficial Registry2 stars1 forks● TypeScriptMITUpdated today
ClaudeWave Trust Score
87/100
✓ Trusted
Passed
  • ✓Open-source license (MIT)
  • ✓Actively maintained (<30d)
  • ✓Clear description
  • ✓Documented (README)
Last scanned: 10/10/2026
Get started
Method: Clone
Terminal
git clone https://github.com/shatch/banjo
1. Clone the repository.
2. Follow the README for installation and usage instructions.
Use cases

Tools 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.

[![Banjo runtime architecture](docs/architecture-diagram.png)](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 | $0

What 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.

Featured on ClaudeWave: shatch/banjo
[![Featured on ClaudeWave](https://claudewave.com/api/badge/shatch-banjo)](https://claudewave.com/repo/shatch-banjo)
<a href="https://claudewave.com/repo/shatch-banjo"><img src="https://claudewave.com/api/badge/shatch-banjo" alt="Featured on ClaudeWave: shatch/banjo" width="320" height="64" /></a>

More Tools

banjo alternatives