A real-time intelligence system for the Bee wearable AI device. Monitors your Bee's event stream, captures conversations and notes, classifies content into categories, executes voice commands (send messages, set reminders), and feeds everything into OpenCLAW's memory for long-term recall.
Built for OpenCLAW but also works standalone with Claude Desktop or Claude Code.
You wear your Bee throughout the day. When you push the button, it records a conversation. When you hold the button, it captures a dictated note. This agent sits in the background, listens to the Bee's real-time event stream, and does five things with that data:
- Captures and stores every conversation transcript, journal note, and todo
- Classifies each piece of content into categories (work, personal, health, projects, etc.)
- Routes classified content to three places simultaneously: categorized JSON inbox, markdown knowledge base, and OpenCLAW's daily memory files
- Executes voice commands when you say "OpenCLAW" — send iMessages, Telegram messages, set reminders, take notes
- Generates daily digests with consolidated action items across all categories
bee-agent/
├── mcp_server/
│ ├── bee_mcp_server.py # Hybrid MCP server (26 tools, 6 resources)
│ └── pyproject.toml # Python package config
│
├── standalone_agent/
│ ├── bee_monitor.py # Always-on background monitor (main entry point)
│ ├── bee_classifier.py # Content classification and routing engine
│ ├── bee_actions.py # Voice command parser and executor
│ └── com.openclaw.bee-monitor.plist # macOS launchd service definition
│
├── skill/
│ └── SKILL.md # Claude Code / OpenCLAW skill file
│
├── install-openclaw.sh # One-command OpenCLAW installer
├── setup.sh # Manual setup script
├── claude_desktop_config.example.json
├── LICENSE # MIT
└── README.md
This is the heart of the system. It runs as a persistent background process (via macOS launchd) and connects to bee stream --json, which is the Bee's real-time Server-Sent Events (SSE) stream.
Startup flow:
- Locates the
beeCLI binary (checks~/.bun/bin/bee,/usr/local/bin/bee,/opt/homebrew/bin/bee) - Spawns
bee stream --jsonas a subprocess - Parses the SSE output line-by-line as JSON events
- Routes each event through the
EventHandlerclass
Event processing pipeline:
bee stream --json
│
▼
JSON line received
│
▼
infer_event_type(data) # Check data["type"] field first,
│ # fall back to payload structure inference
▼
EventHandler.handle_event()
│
├── log_event() # Append to ~/.bee-agent/event-log.jsonl
│
├── handler_map[type]() # Dispatch to specific handler:
│ ├── _on_connected # Stream connected notification
│ ├── _on_new_conversation # Track conversation start
│ ├── _on_utterance # Cache utterance, check for keyword trigger
│ ├── _on_update_conversation # Detect conversation end, write transcript
│ ├── _on_journal_created # Notification: recording started
│ ├── _on_journal_text # Write partial text, check for keyword trigger
│ ├── _on_journal_updated # Write final text, classify & route
│ ├── _on_todo_created # Notification
│ ├── _on_location_update # Cache location
│ └── ... (13 event types total + connected)
│
├── _check_command_capture() # Finalize any active voice command
├── _check_collation() # Generate thought digest every 5 min
└── _check_digest() # Generate daily digest every hour
Key classes in bee_monitor.py:
| Class | Purpose |
|---|---|
TriggerDetector |
Regex-based keyword matching. Looks for "openclaw", "open claw", "hey openclaw", "hey open claw" in transcribed text. Case-insensitive with word boundaries. |
CommandCapture |
State machine that activates after trigger detection. Captures utterances for 15 seconds, with a 5-second silence timeout. All captured text becomes a single command string. |
InboxWriter |
Writes JSON files to ~/.bee-agent/inbox/{commands,conversations,journals,thoughts}/. Each file is a self-contained event payload with timestamp and metadata. |
EventHandler |
The main orchestrator. Maintains in-memory state: active conversations, per-conversation utterance lists (deque(maxlen=200)), recent todos, and a rolling utterance buffer. |
Utterance handling detail:
When a new-utterance event arrives, the monitor:
- Extracts
utterance.text,utterance.speaker(defaults to"me"if absent), andutterance.spoken_at - Appends to the rolling
recent_utterancesdeque (max 200 entries) - Appends to
conversation_utterances[conv_uuid]for per-conversation tracking - Checks if a
CommandCaptureis active — if so, adds the text to it - If no capture is active, runs
TriggerDetector.detect(text)to check for the keyword
Conversation lifecycle:
new-conversation→ Creates entry inactive_conversationsdict, initializes empty utterance listnew-utterance→ Accumulates inconversation_utterances[conv_uuid]update-conversationwith statecompleted/ended/finalized→ Writes full transcript toinbox/conversations/, classifies combined text, routes to all destinations
A hybrid classification system that uses predefined categories with keyword/pattern matching for speed, plus structured metadata extraction for nuance.
Classification flow:
Input text
│
▼
Score each category (0.0 → 1.0)
├── Keyword matching: +0.1 per keyword found in text
├── Pattern matching: +0.15 per regex pattern match
└── Score capped at 1.0
│
▼
Rank categories by score
├── Primary: highest score
└── Secondary: next 3 with score > 0.1
│
▼
Extract metadata
├── Action items (regex: "I need to...", "remind me to...", "don't forget to...")
├── Priority (urgent/important/normal keywords)
├── Sentiment (positive/negative/neutral word counts)
└── Topics (which keywords matched)
│
▼
ClassificationResult
The 8 categories:
| Category | Trigger keywords (examples) | What goes here |
|---|---|---|
work |
meeting, deadline, sprint, client, PowerSchool, district | Meetings, work tasks, professional conversations |
personal |
family, friend, grocery, dog, dinner, pick up | Errands, family, social plans |
health |
doctor, appointment, exercise, gym, sleep, therapy | Medical, fitness, wellbeing |
projects |
build, code, github, deploy, app, MCP, bee agent | Active coding, creative builds |
ideas |
idea, what if, brainstorm, imagine, I wonder | Raw brainstorms, inspiration |
learning |
learn, research, article, tutorial, harmonica | Study, exploration, curiosity |
finance |
money, budget, payment, invest, retirement, Tesla | Purchases, budgets, investments |
meta |
bee, openclaw, agent, config, setup | System config, self-referential |
Each category has both keyword lists and compiled regex patterns. Keywords are matched as substrings (case-insensitive). Patterns use word boundaries for precision.
Action item extraction patterns:
The classifier pulls action items from natural language using these regex patterns:
"I need to / should / must / have to / gotta / gonna / will / want to [ACTION]""remind me to / don't forget to / remember to [ACTION]""todo / to do / action item / task: [ACTION]""let's / let me [ACTION]"
Priority detection:
- High: urgent, asap, immediately, emergency, critical, right now
- Medium: important, priority, must, crucial, don't forget, need to
Triple-destination routing (ContentRouter):
Every classified item gets written to three places:
-
Categorized inbox (
~/.bee-agent/inbox/{category}/) — Full JSON payload with classification metadata. Machine-readable. OpenCLAW agents can scan specific category folders. -
Markdown knowledge base (
~/.bee-agent/knowledge/{category}.md) — Append-only markdown file per category. Human-readable. Builds up over time as a personal wiki. Format:### 2026-03-16 14:30 — journal **Priority:** high Reminder to call Dr. Smith about the knee pain appointment next Tuesday. - [ ] call Dr. Smith about the knee pain appointment next Tuesday *Topics: doctor, appointment, pain* ---
-
OpenCLAW daily memory (
~/.openclaw/workspace/memory/YYYY-MM-DD.md) — Appended to OpenCLAW's existing daily memory files. These get indexed by OpenCLAW's embedding system (Gemini embeddings) and become searchable via semantic memory search. Format:### 📓 [Health] 14:30 *Source: journal | Priority: high* Reminder to call Dr. Smith about the knee pain appointment next Tuesday. - [ ] call Dr. Smith about the knee pain appointment next Tuesday *Topics: doctor, appointment, pain*
When the trigger keyword ("OpenCLAW") is detected and a command is captured, bee_actions.py parses the raw text into a structured ActionRequest and optionally executes it.
Parsing pipeline:
Raw command text (e.g., "send a message via telegram to John saying the build is green")
│
▼
CommandParser.parse()
│
├── _try_message() # 8 regex patterns for messaging commands
├── _try_reminder() # 5 patterns for reminders
├── _try_search() # 4 patterns for search queries
├── _try_note() # 3 patterns for notes
└── fallback → run_command (generic OpenCLAW command)
│
▼
ActionRequest {
action_type: "send_message",
channel: "telegram",
recipient: "John",
message_body: "the build is green",
confidence: 0.9,
...
}
Supported action types:
| Action | Trigger phrases | Fields extracted |
|---|---|---|
send_message |
"send a message via...", "text [name] saying...", "tell [name] via...", "message [name] on..." | channel, recipient, message_body |
set_reminder |
"remind me to...", "set a reminder for...", "don't forget to..." | reminder_text, reminder_time |
search |
"search for...", "look up...", "find out about...", "google..." | search_query |
note |
"save a note...", "add a note...", "note to self..." | note_text, note_category |
run_command |
(anything that doesn't match above) | openclaw_command |
Message channel resolution:
When you say a channel name, it gets normalized through CHANNEL_ALIASES:
| You say | Resolved channel |
|---|---|
| "text", "iMessage", "SMS", "message" | imessage |
| "telegram", "TG" | telegram |
| "WhatsApp", "WA" | whatsapp |
| "email", "mail" | email |
If no channel is specified, defaults to imessage.
Contact resolution:
The ContactResolver maps spoken names to phone numbers or email addresses using ~/.bee-agent/contacts.json:
{
"mom": "+15551234567",
"john": "+15559876543",
"sarah": "sarah@example.com",
"the team": "team-group-id"
}Matching is case-insensitive with partial matching (e.g., "john smith" matches the "john" entry). If no match is found, the raw name is passed through — imsg may resolve it from your macOS Contacts.
Execution flow for iMessage:
ActionRequest (channel=imessage, recipient="Mom", body="I'll be home for dinner")
│
▼
ContactResolver.resolve("Mom") → ("+15551234567", True)
│
▼
IMessageSender.send("+15551234567", "I'll be home for dinner")
│
▼
subprocess: imsg send --to +15551234567 --text "I'll be home for dinner"
│
▼
macOS notification: "Message Sent: iMessage to Mom (+15551234567)"
imsg is a macOS CLI tool installed at /opt/homebrew/bin/imsg that interfaces with Messages.app. It supports --to (phone/email), --text (message body), --service (imessage/sms/auto), and --file (attachments).
Execution flow for Telegram / WhatsApp:
These channels can't be executed directly by the monitor. Instead, the parsed action is written as a JSON file to ~/.bee-agent/inbox/actions/:
{
"action_type": "send_message",
"raw_command": "send a message via telegram to John saying the build is green",
"channel": "telegram",
"recipient": "John",
"message_body": "the build is green",
"confidence": 0.9,
"status": "pending",
"timestamp": "2026-03-16T14:30:00+00:00"
}OpenCLAW reads this file and dispatches the message through its configured Telegram bot (configured in openclaw.json under channels.telegram).
A Model Context Protocol server that gives Claude (via Claude Desktop or Claude Code) direct access to Bee data through 26 tools and 6 resources.
Hybrid architecture:
The server maintains two data pathways:
-
Live cache (instant, <1ms) — A background
asynciotask runsbee stream --jsonand feeds events into aLiveStreamCache:events: deque(maxlen=500)— rolling buffer of all eventsutterances: deque(maxlen=200)— recent utterance text with speaker/timestampactive_conversations: dict— currently open conversationsrecent_todos: list— recently created/modified todosrecent_journals: list— recently created journalslast_location: dict— most recent GPS update
-
On-demand CLI (2-5 seconds) — For historical queries, the server shells out to
bee-cliviaasyncio.create_subprocess_exec:proc = await asyncio.create_subprocess_exec( BEE_CLI, *args, "--json", stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await proc.communicate() return json.loads(stdout)
Server lifecycle (FastMCP lifespan pattern):
@asynccontextmanager
async def server_lifespan(server):
cache = LiveStreamCache()
task = asyncio.create_task(cache.start_stream())
try:
yield {"cache": cache}
finally:
task.cancel()The cache starts with the server and stops when the server shuts down. MCP tool handlers access it via the lifespan context.
All 26 tools:
| Tool | Source | Description |
|---|---|---|
bee_get_live_stream |
Cache | Snapshot of recent events from the live SSE stream |
bee_get_recent_utterances |
Cache | Last N utterances with speaker and timestamp |
bee_get_recent_events |
Cache | Last N events of any type |
bee_get_current_context |
CLI | bee now — all conversations from last 10 hours |
bee_get_today_brief |
CLI | bee today — today's calendar, emails, summary |
bee_list_conversations |
CLI | List conversations with date/limit filters |
bee_get_conversation |
CLI | Get a single conversation by ID with full transcript |
bee_search_conversations |
CLI | Keyword and neural search across conversations |
bee_list_facts |
CLI | List all confirmed facts about the owner |
bee_get_fact |
CLI | Get a specific fact by ID |
bee_create_fact |
CLI | Create a new fact |
bee_update_fact |
CLI | Update an existing fact |
bee_delete_fact |
CLI | Delete a fact |
bee_list_todos |
CLI | List all todos |
bee_get_todo |
CLI | Get a specific todo by ID |
bee_create_todo |
CLI | Create a new todo |
bee_update_todo |
CLI | Update a todo |
bee_complete_todo |
CLI | Mark a todo as completed |
bee_delete_todo |
CLI | Delete a todo |
bee_list_journals |
CLI | List journal entries |
bee_get_journal |
CLI | Get a specific journal entry |
bee_get_daily_summary |
CLI | Get summary for a specific date |
bee_get_changes |
CLI | Change feed with cursor pagination |
bee_get_profile |
CLI | Owner's profile information |
bee_get_status |
CLI | Authentication and connection status |
bee_sync_to_markdown |
CLI | Export Bee data as markdown files |
6 resources:
| URI | Description |
|---|---|
bee://status |
Authentication status |
bee://profile |
User profile |
bee://today |
Today's brief |
bee://now |
Current context (last 10 hours) |
bee://facts |
All facts |
bee://todos |
All todos |
A markdown file with YAML frontmatter that teaches Claude how to use bee-cli commands. When installed as an OpenCLAW skill (~/.openclaw/skills/bee-wearable/SKILL.md), OpenCLAW loads it into agent context automatically.
The skill covers:
- Core workflow (always start with
bee now, thenbee facts list, thenbee todos) - All
bee-clisubcommands with usage examples - The 14 SSE event types and their JSON payloads
- Tips for conversation processing (multi-speaker detection, summary patterns)
A self-contained bash script that installs everything for any OpenCLAW instance. Can be run from a fresh clone or piped from curl.
What it does (7 steps):
- Prerequisites check — Verifies OpenCLAW directory exists, Python 3.10+, bee-cli installed and authenticated
- Code install — Clones the repo to
~/.openclaw/bee-agent/(or updates if already present) - Python dependencies — Installs
mcp[cli]>=1.4.0andpydantic>=2.0.0 - Directory structure — Creates all inbox, knowledge, digest, and category directories; seeds
contacts.json; checks forimsgCLI - Skill registration — Copies
SKILL.mdto~/.openclaw/skills/bee-wearable/ - launchd service — Generates a macOS LaunchAgent plist with correct paths, Python binary, and
PYTHONPATHset sobee_classifierandbee_actionscan be imported - Summary — Prints next steps and directory layout
A launchd property list that keeps bee_monitor.py running at all times:
KeepAlive: true— Restarts if it crashesRunAtLoad: true— Starts on loginThrottleInterval: 10— Waits 10 seconds before restarting after crash- Logs to
/tmp/bee-monitor.logand/tmp/bee-monitor.err - Sets
PYTHONPATHto thestandalone_agent/directory so imports work
┌─────────────────────────────────────────────────────────────────────┐
│ Bee Wearable Device │
│ │
│ [Push button] [Hold button] [Ambient] │
│ → Conversation mode → Journal/dictation → Location, │
│ → Transcribes speech → Transcribes note todos, etc. │
│ → Identifies speakers → AI cleanup │
└─────────────────┬───────────────────────────────────────────────────┘
│
│ SSE stream via bee-cli (bee stream --json)
│ 14 event types, JSON payloads
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ bee_monitor.py (always-on) │
│ │
│ ┌──────────────┐ ┌───────────────┐ ┌──────────────────────┐ │
│ │ EventHandler │ │ TriggerDetect │ │ CommandCapture │ │
│ │ │ │ │ │ (15s window, │ │
│ │ Routes each │──│ Scans text │──│ 5s silence timeout) │ │
│ │ event type │ │ for "OpenCLAW"│ │ │ │
│ └──────┬───────┘ └───────────────┘ └──────────┬───────────┘ │
│ │ │ │
│ │ Every finalized journal │ Captured │
│ │ and conversation │ command text │
│ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ bee_classifier│ │ bee_actions │ │
│ │ │ │ │ │
│ │ Classify into│ │ Parse into │ │
│ │ 8 categories │ │ ActionRequest│ │
│ │ + extract │ │ │ │
│ │ action items │ │ Resolve │ │
│ │ + priority │ │ contacts │ │
│ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────┐ ┌──────────────────────────┐ │
│ │ ContentRouter (triple write) │ │ ActionExecutor │ │
│ │ │ │ │ │
│ │ 1. inbox/{category}/ (JSON) │ │ iMessage → imsg CLI │ │
│ │ 2. knowledge/{cat}.md │ │ Telegram → inbox/actions/ │ │
│ │ 3. openclaw/memory/date.md │ │ WhatsApp → inbox/actions/ │ │
│ └──────────────────────────────┘ └──────────────────────────┘ │
│ │
│ ┌─────────────────────┐ │
│ │ Periodic tasks │ │
│ │ • Thought digest (5m)│ │
│ │ • Daily digest (1h) │ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
│ │
▼ ▼
┌────────────────────────┐ ┌──────────────────────────────────┐
│ ~/.bee-agent/ │ │ ~/.openclaw/ │
│ │ │ │
│ inbox/ │ │ workspace/memory/ │
│ commands/ │ │ 2026-03-16.md ← Bee entries │
│ actions/ ──────────────────► │ appended here │
│ conversations/ │ │ skills/bee-wearable/ │
│ journals/ │ │ SKILL.md │
│ thoughts/ │ │ │
│ work/ │ │ Agents read inbox/actions/ and │
│ personal/ │ │ dispatch via Telegram/WhatsApp │
│ health/ │ │ channels configured in │
│ projects/ │ │ openclaw.json │
│ ideas/ │ └──────────────────────────────────┘
│ learning/ │
│ finance/ │
│ meta/ │
│ knowledge/ │
│ work.md │
│ personal.md │
│ health.md │
│ ... │
│ digests/ │
│ digest-20260316.md │
│ contacts.json │
│ event-log.jsonl │
└────────────────────────┘
The Bee developer API sends 14 event types via its SSE stream at /v1/stream:
| Event | JSON payload structure | Monitor handler |
|---|---|---|
connected |
{"timestamp": 1773681366424} (no type field) |
_on_connected |
new-conversation |
{"type": "new-conversation", "conversation": {"id": 123, "conversation_uuid": "abc...", "state": "IN_PROGRESS"}} |
_on_new_conversation |
new-utterance |
{"type": "new-utterance", "conversation_uuid": "abc...", "utterance": {"text": "...", "speaker": "me", "spoken_at": "..."}} |
_on_utterance |
update-conversation |
{"type": "update-conversation", "conversation": {"id": 123, "state": "completed", "title": "...", "short_summary": "..."}} |
_on_update_conversation |
update-conversation-summary |
{"type": "update-conversation-summary", "conversation_id": 123, "short_summary": "..."} |
_on_update_summary |
delete-conversation |
{"type": "delete-conversation", "conversation": {"id": 123}} |
_on_delete_conversation |
journal-created |
{"type": "journal-created", "journal": {"id": 456, "state": "PREPARING"}} |
_on_journal_created |
journal-text |
{"type": "journal-text", "journalId": 456, "text": "partial transcription..."} |
_on_journal_text |
journal-updated |
{"type": "journal-updated", "journal": {"id": 456, "state": "READY", "text": "final text..."}} |
_on_journal_updated |
journal-deleted |
{"type": "journal-deleted", "journalId": 456} |
— |
todo-created |
{"type": "todo-created", "todo": {"id": 789, "text": "...", "completed": false}} |
_on_todo_created |
todo-updated |
{"type": "todo-updated", "todo": {"id": 789, "completed": true}} |
_on_todo_updated |
todo-deleted |
{"type": "todo-deleted", "todo": {"id": 789}} |
_on_todo_deleted |
update-location |
{"type": "update-location", "location": {"latitude": 46.6, "longitude": -120.5, "name": "..."}} |
_on_location_update |
Important field notes discovered from live stream testing:
- The
typefield is present in the JSON payload itself (not just the SSEevent:line) - The
connectedevent has notypefield — it's just{"timestamp": <epoch_ms>} - Conversations use
conversation_uuid(notuuid) - The
speakerfield may be absent in single-person conversations (defaults to"me") - Utterances include a
spoken_attimestamp separate from the event timestamp
Maps spoken names to phone numbers or email addresses for iMessage sending:
{
"mom": "+15091234567",
"dad": "+15091234567",
"john": "john@example.com",
"the team": "+15091234568"
}Default triggers (configurable via --trigger flag):
- "openclaw"
- "open claw"
- "hey openclaw"
- "hey open claw"
The BeeClassifier accepts a custom_categories dict to add or override categories:
classifier = BeeClassifier(custom_categories={
"music": {
"keywords": ["harmonica", "blues", "guitar", "practice", "song"],
"patterns": [r"\b(harmonica|blues|guitar|music)\b"],
"description": "Music practice and learning",
}
})git clone https://github.com/macsiah/bee-agent.git
cd bee-agent
bash install-openclaw.sh1. Install dependencies:
pip3 install "mcp[cli]>=1.4.0" "pydantic>=2.0.0"2. Create directories:
mkdir -p ~/.bee-agent/inbox/{commands,actions,conversations,journals,thoughts}
mkdir -p ~/.bee-agent/inbox/{work,personal,health,projects,ideas,learning,finance,meta}
mkdir -p ~/.bee-agent/{knowledge,digests}3. Set up contacts:
echo '{"mom": "+15551234567"}' > ~/.bee-agent/contacts.json4. Start the monitor:
cd ~/.openclaw/bee-agent/standalone_agent
python3 bee_monitor.py5. Install as persistent service (macOS):
launchctl load ~/Library/LaunchAgents/com.openclaw.bee-monitor.plist6. Add MCP server to Claude Desktop (optional):
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"bee-wearable": {
"command": "python3",
"args": ["/Users/YOU/.openclaw/bee-agent/mcp_server/bee_mcp_server.py"]
}
}
}During a conversation (button push) or journal dictation (button hold), say "OpenCLAW" followed by:
| You say | Parsed action | Execution |
|---|---|---|
| "send a message via Telegram to John saying the build is green" | send_message → telegram → John |
Written to inbox/actions/ for OpenCLAW |
| "text Mom saying I'll be home for dinner" | send_message → imessage → Mom |
imsg send --to +1555... --text "..." |
| "tell Sarah via WhatsApp that the meeting is at 3" | send_message → whatsapp → Sarah |
Written to inbox/actions/ for OpenCLAW |
| "remind me to call the doctor at 3pm" | set_reminder → "call the doctor" @ 3pm |
Written to inbox/actions/ |
| "search for Python async best practices" | search → "Python async best practices" |
Written to inbox/actions/ |
| "note to self buy a new monitor" | note → "buy a new monitor" |
Written to inbox/actions/ |
| "don't forget to pick up groceries" | set_reminder → "pick up groceries" |
Written to inbox/actions/ |
Monitor won't connect:
bee status # Check authentication
bee stream --json # Test stream directly (Ctrl+C to stop)No events appearing:
- The Bee only sends events when you interact with it (push/hold button)
- There's no ambient audio transcription — the device handles that locally
- Check the log:
tail -f /tmp/bee-monitor.log
imsg not sending:
which imsg # Should be /opt/homebrew/bin/imsg
imsg send --help # Check available flags
imsg chats # List recent conversationsKeyword trigger not firing:
- Triggers only work during active conversation or journal dictation
- The Bee must be transcribing (button pressed) for text to appear in the stream
- Check that your trigger words are being spoken clearly enough for transcription
Check service status:
launchctl list | grep bee-monitor
tail -f /tmp/bee-monitor.log
tail -f /tmp/bee-monitor.err- bee-cli — Official Bee CLI (TypeScript)
- bee-skill — Official Bee agent skill
- beemcp — Community MCP server (uses older API)
- imsg — Terminal iMessage/SMS client
MIT — Copyright 2026 OpenCLAW