Johnnyv0.1
self-hosted

// open-source meeting agent · local-first

Your AI in every meeting.
Johnny shows up so you don't.

Johnny joins your Google Meet calls on your behalf — listening, transcribing, and speaking only within the limits you set. Give it a personality, a voice, and a calendar. It runs entirely on your machine.

runs on-device free to self-host 24/7 daemon
meet · q3-ops-sync ● rec 18:42
PN
Panam · host on
JD
Judy on
VK
Viktor on
JAI
Johnny · bot on
CC Panam Let's lock the run on the Arasaka subnet before we wrap.

// behavior · server-enforced

Five ways to let it
in the room.

Pick one per meeting — from silent note-taker to fully autonomous. A non-speaking mode makes speaking physically impossible: the constraint lives in the backend, not a checkbox the UI can lie about.

01[ passive ]

Listen only

Transcribes the whole call into a searchable, persisted log. Never reasons about speaking. The pure note-taker.

→ transcript + pgvector
02[ silent ]

Suggest only

Routes every moment through the model and surfaces drafted replies in the UI — but the mouth stays closed. You decide what to say.

→ live suggestions
03[ gated ]

Approval required

Pushes a reply to your browser with Approve / Reject. No answer in 15 seconds, it stays quiet. Auto-rejected and logged.

→ web push · audited
04[ allow-list ]

Limited auto-speak

Speaks on its own — but only verbatim from your pre-approved phrase list. Rate-limited. No paraphrasing, no surprises.

→ allow-list only
05[ unleashed ]

Autonomous

Off the leash. It speaks for itself, freely — guided only by its personality and your standing instructions. Full presence in the room.

→ free generation

// nothing leaves the box

Local-first.
Free by default.

Run speech-to-text, the LLM, and text-to-speech entirely on your own hardware — faster-whisper, Ollama, Piper. No API keys, no per-minute billing, no audio handed to a third party. Reach for the cloud only when you choose to.

  • Audio never phones home. The full pipeline can run offline on a single machine.
  • Swap any layer without code. STT, LLM and TTS are adapters — change them from the UI.
  • Cloud when it's worth it. Drop in Claude, GPT-4o, Gemini, Deepgram or ElevenLabs per provider.
provider matrix
character.profile
handleJohnny // your_call_sign
personalitydry, fast, allergic to filler. interjects only when it adds signal.
instructionsdefend the deadline. surface capacity overflows. never agree to scope creep.
allow-list"noted." · "let's take it offline." · "that's a follow-up."
router conf≥ 0.85 to speak
Voice clone armed. ElevenLabs voice ID bound — it speaks in your own voice.

// build your own ghost

Give it a name.
A voice. A creed.

The name is a placeholder — make your own character. Write its personality, its standing instructions, the exact phrases it's allowed to say. Save them as reusable templates and apply them to any meeting in one click.

  • Templates, not prompts. "Listen-only standup", "approval-required client call" — reusable behavior presets.
  • Clone yourself with ElevenLabs. Bind a custom voice and it speaks as a digital copy of you.
  • Per-meeting overrides. Layer extra context, instructions and replies on top of any template.

// driven by your calendar

Mark the meeting.
It joins itself.

Johnny reads your Google Calendar and parses the Meet link straight from each event. Flag the calls it should attend, attach context, and it spins up an isolated browser session and walks in — as a dedicated bot account or as you.

  • Per-meeting context. Attach instructions and a profile template to each event you assign.
  • Auto join & leave. A scheduler joins within seconds of start and tears the session down at the end.
  • Isolated per session. Each call runs in its own throwaway container — one bad meeting can't touch another.
calendar · next 14 days
Tue · Jun 09
09:30–10:00 Q3 ops syncpanam@ · +4 attendees assigned
13:00–13:30 Vendor — ferry capacityjudy@ · +2 assign
Wed · Jun 10
11:00–12:00 Client call — Lapland tourexternal · +6 assigned
15:00–15:15 1:1 (no Meet link)in person

// built to stay up

One stack. Up 24/7.

The whole thing — API, worker, scheduler, Postgres + pgvector, Redis — comes up with one command. Run it on a homelab box or drop it into a Kubernetes cluster and leave it running.

~/johnny — bash
# clone & bring up the full stack
$ git clone https://github.com/mekedron/Johnny && cd Johnny
$ cp .env.example .env
$ docker compose up -d
⤷ api · worker · postgres+pgvector · redis · web
stack healthy — ui at localhost:5173
 
$ uv run johnny-smoke
PASS compose · migrations · oauth · models · ws
Docker Compose
Five services, healthchecks and named volumes. docker compose up and you're live — no manual wiring.
Kubernetes-readysoon
Built to run as a long-lived daemon. Park it in a cluster and let the scheduler spawn per-meeting workers on demand.
MCP & agent controlsoon
Hand tasks and per-meeting instructions to Johnny over an MCP server — wire it to OpenClaw, Hermes or any agent you run.

// clone · configure · forget about it

Send Johnny in.

Open source. Free to self-host. Yours to shape into any character you want.

// no corpo backing · one operator

Keep the operator caffeinated.

No VC. No corpo. No telemetry tax — just one person building and running this whole rig on synth-coffee and pure spite. If Johnny ever covered a meeting for you, slip a few eddies in the tin and keep the lights — and the late-night commits — on.

solo-maintained MIT · free forever 100% to ramen & rent
street-vendor // payout open
Buy the dev a coffee one cup → one more late-night patch
synth-espresso+1 commit
bowl of NiCola ramen1 bug, flatlined
tank of eddiesa weekend of features
Buy me a coffee
payout → @mekedron · buymeacoffee.com