docs: add pre-rendered diagram PNGs and update AGENTS.md with architecture overview

Add 32 rendered PNG diagram images alongside existing Mermaid source
blocks (wrapped in collapsible details) across documentation pages.
Update AGENTS.md with architecture overview section and single-test
command. Update README hero banner to use rendered diagram.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Davendra Patel 2026-01-29 16:00:59 +05:30
parent d9851627b2
commit 2e3e12f38b
58 changed files with 228 additions and 2 deletions

View File

@ -1,7 +1,25 @@
# Repository Guidelines
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
- Repo: https://github.com/moltbot/moltbot
- GitHub issues/comments/PR comments: use literal multiline strings or `-F - <<'EOF'` (or $'...') for real newlines; never embed "\\n".
## Architecture Overview
Moltbot is a local-first personal AI assistant that bridges messaging channels to AI agents.
**Message flow:** Inbound message (WhatsApp, Telegram, Slack, etc.) → Gateway WebSocket server (`src/gateway/server.ts`) → Channel plugin routes message → Pi agent runtime (`src/agents/pi-embedded-runner.ts`) executes tools (browser, bash, canvas, etc.) via gateway RPC → Final reply sent back through channel's outbound adapter.
**Key subsystems:**
- **Gateway** (`src/gateway/`): WebSocket control plane. Hosts sessions, routes messages, serves the Control UI, and exposes RPC methods for agent tool calls. Config is YAML-based (`~/.clawdbot/config.yaml`), hot-reloaded via chokidar.
- **Agents** (`src/agents/`): Pi agent runtime. Manages LLM provider config, auth profiles, tool definitions, sandbox execution, and skill loading. Sessions are isolated per-agent/group as JSONL files under `~/.clawdbot/sessions/`.
- **Channel plugins** (`src/channels/plugins/`): Unified `ChannelPlugin` interface with `inbound` (receive) and `outbound` (send) adapters. Core channels live in `src/` (discord, telegram, slack, signal, imessage, web/WhatsApp). Extension channels live in `extensions/*` as workspace packages.
- **Dependency injection** (`src/cli/deps.ts`): `createDefaultDeps()` wires all channel send functions and services. Used throughout for testability.
- **Plugin registry** (`src/plugins/runtime.ts`): Channels and extensions are runtime-registered (not statically imported). Access via `getActivePluginRegistry()`.
**Apps:** macOS menu bar (SwiftUI, `apps/macos/`), iOS (`apps/ios/`), Android (Kotlin, `apps/android/`), shared Swift code in `apps/shared/MoltbotKit/`.
## Project Structure & Module Organization
- Source code: `src/` (CLI wiring in `src/cli`, commands in `src/commands`, web provider in `src/provider-web.ts`, infra in `src/infra`, media pipeline in `src/media`).
- Tests: colocated `*.test.ts`.
@ -47,6 +65,7 @@
- Type-check/build: `pnpm build` (tsc)
- Lint/format: `pnpm lint` (oxlint), `pnpm format` (oxfmt)
- Tests: `pnpm test` (vitest); coverage: `pnpm test:coverage`
- Run a single test file: `pnpm test -- src/path/to/file.test.ts`
## Coding Style & Naming Conventions
- Language: TypeScript (ESM). Prefer strict typing; avoid `any`.

View File

@ -1,7 +1,7 @@
# 🦞 Moltbot — Personal AI Assistant
<p align="center">
<img src="https://raw.githubusercontent.com/moltbot/moltbot/main/docs/whatsapp-clawd.jpg" alt="Clawdbot" width="400">
<img src="/images/diagrams/30-hero-banner.png" alt="Moltbot — Your AI Agent, Everywhere You Message" width="800">
</p>
<p align="center">
@ -52,6 +52,11 @@ moltbot onboard --install-daemon
The wizard installs the Gateway daemon (launchd/systemd user service) so it stays running.
Legacy note: `clawdbot` remains available as a compatibility shim.
![Moltbot Architecture Overview](/images/diagrams/27-readme-architecture.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
graph LR
subgraph Channels [Messaging Channels]
@ -87,6 +92,8 @@ graph LR
GW -->|outbound| Channels
```
</details>
## Quick start (TL;DR)
Runtime: **Node ≥22**.

View File

@ -15,6 +15,11 @@ the right time, and can optionally deliver output back to a chat.
If you want *“run this every morning”* or *“poke the agent in 20 minutes”*,
cron is the mechanism.
![Cron Job Execution Paths](/images/diagrams/09-cron-jobs.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
subgraph MainSession [Main Session Job]
@ -36,6 +41,8 @@ flowchart TD
end
```
</details>
## TL;DR
- Cron runs **inside the Gateway** (not inside the model).
- Jobs persist under `~/.clawdbot/cron/` so restarts dont lose schedules.

View File

@ -9,6 +9,11 @@ read_when:
Gateway can expose a small HTTP webhook endpoint for external triggers.
![Webhook Processing Flow](/images/diagrams/10-webhook.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
sequenceDiagram
participant EXT as External System
@ -38,6 +43,8 @@ sequenceDiagram
end
```
</details>
## Enable
```json5

View File

@ -17,6 +17,11 @@ Broadcast Groups enable multiple agents to process and respond to the same messa
Current scope: **WhatsApp only** (web channel).
![Broadcast Group Flow](/images/diagrams/14-broadcast.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
MSG[Incoming Message] --> ALLOW{Channel Allowlist\n+ Group Activation?}
@ -36,6 +41,8 @@ flowchart TD
ISO1 & ISO2 & ISO3 --> DELIVER[Deliver Replies\nto Same Chat]
```
</details>
Broadcast groups are evaluated after channel allowlists and group activation rules. In WhatsApp groups, this means broadcasts happen when Moltbot would normally reply (for example: on mention, depending on your group settings).
## Use Cases

View File

@ -13,6 +13,11 @@ In Moltbot, a loop is a single, serialized run per session that emits lifecycle
as the model thinks, calls tools, and streams output. This doc explains how that authentic loop is
wired end-to-end.
![Agent Loop Lifecycle](/images/diagrams/02-agent-loop.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
stateDiagram-v2
[*] --> Intake: Inbound message / RPC
@ -29,6 +34,8 @@ stateDiagram-v2
Compaction --> ModelInference: Retry with compacted context
```
</details>
## Entry points
- Gateway RPC: `agent` and `agent.wait`.
- CLI: `agent` command.
@ -96,6 +103,11 @@ These run inside the agent loop or gateway pipeline:
See [Plugins](/plugin#plugin-hooks) for the hook API and registration details.
![Plugin Hooks Lifecycle](/images/diagrams/20-plugin-hooks.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
sequenceDiagram
participant GW as Gateway
@ -131,6 +143,8 @@ sequenceDiagram
GW->>HOOK: session_end
```
</details>
## Streaming + partial replies
- Assistant deltas are streamed from pi-agent-core and emitted as `assistant` events.
- Block streaming can emit partial replies either on `text_end` or `message_end`.

View File

@ -9,6 +9,11 @@ read_when:
The workspace is the agent's home. It is the only working directory used for
file tools and for workspace context. Keep it private and treat it as memory.
![Agent Workspace Structure](/images/diagrams/26-workspace.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
graph TD
subgraph Workspace ["Agent Workspace (~/clawd)"]
@ -44,6 +49,8 @@ graph TD
end
```
</details>
This is separate from `~/.clawdbot/`, which stores config, credentials, and
sessions.

View File

@ -21,6 +21,11 @@ Last updated: 2026-01-22
## Components and flows
![Architecture Overview](/images/diagrams/01-architecture.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
graph TD
subgraph Channels
@ -60,6 +65,8 @@ graph TD
GW -.-> CANVAS
```
</details>
### Gateway (daemon)
- Maintains provider connections.
- Exposes a typed WS API (requests, responses, serverpush events).

View File

@ -51,6 +51,11 @@ Routing picks **one agent** for each inbound message:
The matched agent determines which workspace and session store are used.
![Channel Routing Priority Cascade](/images/diagrams/05-channel-routing.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
MSG[Inbound Message] --> P1{Exact Peer Match?}
@ -68,6 +73,8 @@ flowchart TD
FOUND --> WS[Workspace + Session Store]
```
</details>
## Broadcast groups (run multiple agents)
Broadcast groups let you run **multiple agents** for the same peer **when Moltbot would normally reply** (for example: in WhatsApp groups, after mention/activation gating).
@ -86,6 +93,11 @@ Config:
See: [Broadcast Groups](/broadcast-groups).
![Broadcast vs Normal Routing](/images/diagrams/29-broadcast-vs-normal.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
MSG[Inbound Message\nfrom peer] --> BC{Peer in\nBroadcast Config?}
@ -99,6 +111,8 @@ flowchart TD
DEFAULT --> REPLY_S
```
</details>
## Config overview
- `agents.list`: named agent definitions (workspace, model, etc.).

View File

@ -8,6 +8,11 @@ read_when:
Every model has a **context window** (max tokens it can see). Long-running chats accumulate messages and tool results; once the window is tight, Moltbot **compacts** older history to stay within limits.
![Context Compaction Flow](/images/diagrams/11-compaction.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
A[Session Messages Accumulate] --> B{Near Context Limit?}
@ -24,6 +29,8 @@ flowchart TD
K --> C
```
</details>
## What compaction is
Compaction **summarizes older conversation** into a compact summary entry and keeps recent messages intact. The summary is stored in the session history, so future requests use:
- The compaction summary

View File

@ -9,6 +9,11 @@ read_when:
Moltbot memory is **plain Markdown in the agent workspace**. The files are the
source of truth; the model only "remembers" what gets written to disk.
![Memory Organization](/images/diagrams/12-memory.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
subgraph WorkspaceFiles [Workspace Memory Files]
@ -37,6 +42,8 @@ flowchart TD
DAILY --> READ
```
</details>
Memory search tools are provided by the active memory plugin (default:
`memory-core`). Disable memory plugins with `plugins.slots.memory = "none"`.

View File

@ -20,6 +20,11 @@ Inbound message
-> outbound replies (channel limits + chunking)
```
![Message Processing Flow](/images/diagrams/03-message-flow.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
A[Inbound Message] --> B{Dedupe Cache}
@ -44,6 +49,8 @@ flowchart TD
O --> P[Delivered]
```
</details>
Key knobs live in configuration:
- `messages.*` for prefixes, queueing, and group behavior.
- `agents.defaults.*` for block streaming and chunking defaults.

View File

@ -13,6 +13,11 @@ Moltbot handles failures in two stages:
This doc explains the runtime rules and the data that backs them.
![Model Failover Decision Tree](/images/diagrams/17-model-failover.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
REQ[Agent Run Request] --> PROF[Select Auth Profile\nSession-pinned or round-robin]
@ -32,6 +37,8 @@ flowchart TD
SWITCH --> PROF
```
</details>
## Auth storage (keys + OAuth)
Moltbot uses **auth profiles** for both API keys and OAuth tokens.

View File

@ -9,6 +9,11 @@ status: active
Goal: multiple *isolated* agents (separate workspace + `agentDir` + sessions), plus multiple channel accounts (e.g. two WhatsApps) in one running Gateway. Inbound is routed to an agent via bindings.
![Multi-Agent Isolation](/images/diagrams/06-multi-agent.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
graph TD
GW[Gateway Process] --> A1[Agent: home]
@ -33,6 +38,8 @@ graph TD
B3[Binding: Telegram] --> A2
```
</details>
## What is "one agent"?
An **agent** is a fully scoped brain with its own:

View File

@ -7,6 +7,11 @@ read_when:
We serialize inbound auto-reply runs (all channels) through a tiny in-process queue to prevent multiple agent runs from colliding, while still allowing safe parallelism across sessions.
![Lane-Aware FIFO Queue](/images/diagrams/07-queue-lanes.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart LR
subgraph SessionLanes [Session Lanes\none run per session]
@ -28,6 +33,8 @@ flowchart LR
CL -.->|parallel| ML
```
</details>
## Why
- Auto-reply runs can be expensive (LLM calls) and can collide when multiple inbound messages arrive close together.
- Serializing avoids competing for shared resources (session files, logs, CLI stdin) and reduces the chance of upstream rate limits.
@ -48,6 +55,11 @@ Inbound messages can steer the current run, wait for a followup turn, or do both
- `interrupt` (legacy): abort the active run for that session, then run the newest message.
- `queue` (legacy alias): same as `steer`.
![Queue Modes State Machine](/images/diagrams/08-queue-modes.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
stateDiagram-v2
[*] --> Idle: No active run
@ -69,6 +81,8 @@ stateDiagram-v2
SteerBacklog --> Running: Steer now + preserve for followup
```
</details>
Steer-backlog means you can get a followup response after the steered run, so
streaming surfaces can look like duplicates. Prefer `collect`/`steer` if you want
one response per inbound message.

View File

@ -7,6 +7,11 @@ read_when:
Moltbot treats **one direct-chat session per agent** as primary. Direct chats collapse to `agent:<agentId>:<mainKey>` (default `main`), while group/channel chats get their own keys. `session.mainKey` is honored.
![Session Lifecycle](/images/diagrams/28-session-lifecycle.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
CREATE[Session Created\nNew inbound message] --> LOAD[Load Session\nfrom sessions.json + JSONL]
@ -22,6 +27,8 @@ flowchart TD
ARCHIVE --> CREATE
```
</details>
Use `session.dmScope` to control how **direct messages** are grouped:
- `main` (default): all DMs share the main session for continuity.
- `per-peer`: isolate by sender id across channels.

View File

@ -13,6 +13,11 @@ Moltbot has two separate “streaming” layers:
There is **no real token streaming** to external channel messages today. Telegram draft streaming is the only partial-stream surface.
![Streaming Delivery Paths](/images/diagrams/13-streaming.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
MODEL[Model Output\ntext_delta events] --> BS{Block Streaming\nEnabled?}
@ -36,6 +41,8 @@ flowchart TD
TG -->|No| BS
```
</details>
## Block streaming (channel messages)
Block streaming sends assistant output in coarse chunks as it becomes available.

View File

@ -10,6 +10,11 @@ Last updated: 2025-12-09
## What it is
- The always-on process that owns the single Baileys/Telegram connection and the control/event plane.
![Gateway Lifecycle States](/images/diagrams/23-gateway-lifecycle.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
stateDiagram-v2
[*] --> NotInstalled
@ -23,6 +28,8 @@ stateDiagram-v2
Error --> Running: Supervisor auto-restart\nRestartSec=5
```
</details>
- Replaces the legacy `gateway` command. CLI entry point: `moltbot gateway`.
- Runs until stopped; exits non-zero on fatal errors so the supervisor restarts it.
@ -36,6 +43,11 @@ moltbot gateway --force
# dev loop (auto-reload on TS changes):
pnpm gateway:watch
```
![Config Hot-Reload](/images/diagrams/24-hot-reload.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart LR
WATCH[File Watcher\n~/.clawdbot/moltbot.json] --> DEBOUNCE[Debounce]
@ -45,6 +57,8 @@ flowchart LR
ANALYZE -->|reload.mode=off| IGNORE[Ignored]
```
</details>
- Config hot reload watches `~/.clawdbot/moltbot.json` (or `CLAWDBOT_CONFIG_PATH`).
- Default mode: `gateway.reload.mode="hybrid"` (hot-apply safe changes, restart on critical).
- Hot reload uses in-process restart via **SIGUSR1** when needed.

View File

@ -18,6 +18,11 @@ handshake time.
- WebSocket, text frames with JSON payloads.
- First frame **must** be a `connect` request.
![Gateway WebSocket Protocol](/images/diagrams/04-ws-protocol.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
sequenceDiagram
participant C as Client
@ -43,6 +48,8 @@ sequenceDiagram
end
```
</details>
## Handshake (connect)
Gateway → Client (pre-connect challenge):

View File

@ -5,6 +5,8 @@ read_when:
---
# Security 🔒
![Security Trust Hierarchy](/images/diagrams/31-security-threat-model.png)
## Quick check: `moltbot security audit` (formerly `clawdbot security audit`)
See also: [Formal Verification (Security Models)](/security/formal-verification/)
@ -35,6 +37,11 @@ Moltbot is both a product and an experiment: youre wiring frontier-model beha
Start with the smallest access that still works, then widen it as you gain confidence.
![Three-Layer Security Model](/images/diagrams/15-security.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
graph TD
subgraph Layer1 [Layer 1: Inbound Access Control]
@ -63,6 +70,8 @@ graph TD
Layer3 --> AGENT[Agent Executes]
```
</details>
### What the audit checks (high level)
- **Inbound access** (DM policies, group policies, allowlists): can strangers trigger the bot?

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 KiB

View File

@ -9,6 +9,11 @@ read_when:
Use the installer unless you have a reason not to. It sets up the CLI and runs onboarding.
![Installation Decision Tree](/images/diagrams/25-install.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
START[Install Moltbot] --> OS{Operating System?}
@ -28,6 +33,8 @@ flowchart TD
GIT --> ONBOARD
```
</details>
## Quick install (recommended)
```bash

View File

@ -112,6 +112,11 @@ manifest.
If multiple plugins resolve to the same id, the first match in the order above
wins and lower-precedence copies are ignored.
![Plugin Discovery Precedence](/images/diagrams/19-plugin-discovery.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
A[Plugin Discovery] --> B[1. Config Paths\nplugins.load.paths]
@ -135,6 +140,8 @@ flowchart TD
K --> Q[Plugin Hooks]
```
</details>
### Package packs
A plugin directory may include a `package.json` with `moltbot.extensions`:

View File

@ -7,8 +7,15 @@ read_when:
# Getting Started
![5 Minutes to First Message](/images/diagrams/32-getting-started-timeline.png)
Goal: go from **zero****first working chat** (with sane defaults) as quickly as possible.
![Getting Started: Onboarding Wizard](/images/diagrams/22-onboarding.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
A[Install Moltbot\nnpm install -g moltbot] --> B[Run Onboarding Wizard\nmoltbot onboard --install-daemon]
@ -22,6 +29,8 @@ flowchart TD
I --> J[Send First Message\nmoltbot agent --message 'Hello']
```
</details>
Fastest chat: open the Control UI (no channel setup needed). Run `moltbot dashboard`
and chat in the browser, or open `http://127.0.0.1:18789/` on the gateway host.
Docs: [Dashboard](/web/dashboard) and [Control UI](/web/control-ui).

View File

@ -14,6 +14,11 @@ It is used in two places:
1) **DM pairing** (who is allowed to talk to the bot)
2) **Node pairing** (which devices/nodes are allowed to join the gateway network)
![Pairing Flows](/images/diagrams/16-pairing.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
sequenceDiagram
participant S as Sender / Device
@ -37,6 +42,8 @@ sequenceDiagram
S->>GW: Future connects use device token
```
</details>
Security context: [Security](/gateway/security)
## 1) DM pairing (inbound chat access)

View File

@ -321,6 +321,11 @@ High-level flow:
This design keeps the agent on a stable, deterministic interface while letting
you swap local/remote browsers and profiles.
![Browser Automation Flow](/images/diagrams/21-browser.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
flowchart TD
AGENT[Agent Tool Call\nbrowser action] --> TARGET{Target?}
@ -339,6 +344,8 @@ flowchart TD
SB --> RESULT
```
</details>
## CLI quick reference
All commands accept `--browser-profile <name>` to target a specific profile.

View File

@ -11,6 +11,11 @@ Moltbot exposes **first-class agent tools** for browser, canvas, nodes, and cron
These replace the old `moltbot-*` skills: the tools are typed, no shelling,
and the agent should rely on them directly.
![Tool Groups](/images/diagrams/18-tool-groups.png)
<details>
<summary>Diagram source (Mermaid)</summary>
```mermaid
graph LR
subgraph Runtime [group:runtime]
@ -60,6 +65,8 @@ graph LR
end
```
</details>
## Disabling tools
You can globally allow/deny tools via `tools.allow` / `tools.deny` in `moltbot.json`