meepo
CLAUDE.md4 starsChanged 9 months agoMITView on GitHub
Rust workspace with 7 crates. Dependencies flow downward — meepo-cli depends on everything, leaf crates have no internal dependencies. Tool system: All tools implement ToolHandler trait (name(), description(), input_schema(), execute()). Registered in ToolRegistry at startup. API client runs a tool loop until Claude returns text or hits 10-iteration limit. Channel adapters: Implement MessageChannel trait (start(), send(), channel_type()). MessageBus splits into receiver + Arc<BusSender> for concurrent use. Platform abstraction: OS-specific code behind traits in meepo-core::platform (EmailProvider, CalendarProvider, BrowserProvider, etc.). Selected at…
- Reads credentials
In this repository2 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .github/workflows/CLAUDE.mdCLAUDE.md
The file
We split this CLAUDE.md into the rules it gives an agent
4 rules. About 0 are common, 1 is distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 30
Tool system: All tools implement ToolHandler trait (name(), description(), input_schema(), execute()).
- Very specific: line 72
Create struct in crates/meepo-core/src/tools/ (or appropriate submodule)
- Distinctive: line 75
Add tests in the same file
- Very specific: line 76
Use json_schema() helper for input schema, anyhow::Result<String> for return
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Meepo — Development Guide
Quick Reference
cargo build # Build all crates
cargo test --workspace # Run all 167+ tests
cargo test -p meepo-core # Test a single crate
cargo clippy --workspace # Lint
cargo run -- ask "Hello" # One-shot test (needs ANTHROPIC_API_KEY)
cargo run -- --debug start # Start daemon with debug loggingArchitecture
Rust workspace with 7 crates. Dependencies flow downward — meepo-cli depends on everything, leaf crates have no internal dependencies.
| Crate | Purpose |
meepo-cli | Binary entry point, CLI commands, daemon startup, event loop, config, templates |
meepo-core | Agent loop, Anthropic API client, 75+ tools, orchestrator, autonomy, platform abstraction |
meepo-channels | Message bus + channel adapters (Discord, Slack, iMessage, email, Alexa, etc.) |
meepo-knowledge | SQLite + Tantivy knowledge graph (entities, relationships, full-text search) |
meepo-scheduler | Watcher runner, 7 watcher types, persistence |
meepo-mcp | MCP server (STDIO JSON-RPC) and client for external MCP servers |
meepo-a2a | Google A2A protocol — HTTP server/client for agent-to-agent delegation |
Key Patterns
Tool system: All tools implement ToolHandler trait (name(), description(), input_schema(), execute()). Registered in ToolRegistry at startup. API client runs a tool loop until Claude returns text or hits 10-iteration limit.
Channel adapters: Implement MessageChannel trait (start(), send(), channel_type()). MessageBus splits into receiver + Arc<BusSender> for concurrent use.
Platform abstraction: OS-specific code behind traits in meepo-core::platform (EmailProvider, CalendarProvider, BrowserProvider, etc.). Selected at compile time via #[cfg(target_os)]. Factory functions return Box<dyn Trait>.
Secrets: API keys use ${ENV_VAR} syntax in TOML config, expanded at load time via an allowlist. Structs holding secrets get custom Debug impls (not #[derive(Debug)]). Never hardcode secrets.
Concurrency: Tokio async runtime. CancellationToken for graceful shutdown. mpsc channels between components. Semaphore for concurrency limits.
Autonomous loop: AutonomousLoop drives observe/think/act cycle. Drains inputs (user messages + watcher events), checks due goals, processes everything. Notify handle wakes the loop on new inputs.
File Layout
crates/
├── meepo-cli/src/
│ ├── main.rs # CLI commands, daemon startup, tool registration, event loop (~3000 lines)
│ ├── config.rs # Config structs, env var expansion, TOML loading
│ └── template.rs # Agent template system
├── meepo-core/src/
│ ├── agent.rs # Agent struct, message handling
│ ├── api.rs # LLM API client (multi-provider) with tool loop
│ ├── tools/ # All tool implementations
│ │ ├── mod.rs # ToolHandler trait, ToolRegistry, ToolExecutor
│ │ ├── macos.rs # Email, Calendar, Reminders, Notes, Contacts, Music, etc.
│ │ ├── browser.rs # 11 browser automation tools
│ │ ├── code.rs # write_code, make_pr, review_pr, spawn_coding_agent
│ │ ├── lifestyle/ # Email intelligence, calendar, research, SMS, tasks, news, finance, health, travel, social
│ │ └── ...
│ ├── autonomy/ # Autonomous loop, goals, planner, user model
│ ├── platform/ # OS abstraction (mod.rs traits, macos.rs, windows.rs)
│ └── skills/ # OpenClaw SKILL.md loader
├── meepo-channels/src/ # Discord, Slack, iMessage, email, Alexa, Reminders, Notes, Contacts adapters
├── meepo-knowledge/src/ # KnowledgeGraph (SQLite + Tantivy), KnowledgeDb
├── meepo-scheduler/src/ # WatcherRunner, 7 watcher types, persistence
├── meepo-mcp/src/ # MCP server/client, protocol types
└── meepo-a2a/src/ # A2A server/client, AgentCard, protocol typesAdding a New Tool
- Create struct in
crates/meepo-core/src/tools/(or appropriate submodule) - Implement
ToolHandlertrait withname(),description(),input_schema(),execute() - Register in
crates/meepo-cli/src/main.rsin bothcmd_start()andcmd_mcp_server() - Add tests in the same file
- Use
json_schema()helper for input schema,anyhow::Result<String>for return
Code Style
- Rust 2024 edition
anyhowfor error handling in applications,thiserrorfor library error typestracingfor logging (debug!,info!,warn!,error!)async_traitfor async trait methodsserdewith#[serde(default)]for optional config fields- Input validation: check lengths, sanitize paths, validate branch names
- Security: command allowlists, path traversal protection, SSRF blocking, 30s execution timeouts
- Platform-gated code uses
#[cfg(target_os = "macos")]/#[cfg(target_os = "windows")] - Tools that accept
Arc<KnowledgeDb>store it for DB operations; tools that don't need it use unit structs
Config
Main config: ~/.meepo/config.toml (see config/default.toml for template)
Runtime data: ~/.meepo/ (knowledge.db, tantivy_index/, workspace/SOUL.md, workspace/MEMORY.md)
Env var allowlist for expansion: ANTHROPIC_API_KEY, TAVILY_API_KEY, DISCORD_BOT_TOKEN, SLACK_BOT_TOKEN, A2A_AUTH_TOKEN, GITHUB_TOKEN, HOME, USER
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

