zubo 0.1.6 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/migrations/017_oauth_tokens.sql +11 -0
- package/migrations/018_cron_once.sql +1 -0
- package/package.json +1 -1
- package/site/docs/agents.html +82 -1
- package/site/docs/api.html +300 -4
- package/site/docs/channels.html +70 -3
- package/site/docs/cli.html +39 -8
- package/site/docs/config.html +165 -16
- package/site/docs/index.html +175 -10
- package/site/docs/integrations.html +203 -12
- package/site/docs/memory.html +53 -1
- package/site/docs/security.html +1 -0
- package/site/docs/skills.html +14 -3
- package/site/index.html +54 -20
- package/site/script.js +191 -64
- package/site/style.css +512 -207
- package/src/agent/delegate.ts +16 -7
- package/src/agent/prompts.ts +78 -71
- package/src/channels/dashboard.html.ts +1683 -471
- package/src/channels/email.ts +11 -6
- package/src/channels/lifecycle.ts +161 -0
- package/src/channels/router.ts +24 -3
- package/src/channels/webchat.ts +745 -28
- package/src/channels/whatsapp.ts +8 -3
- package/src/config/schema.ts +30 -0
- package/src/db/export.ts +6 -3
- package/src/index.ts +27 -0
- package/src/llm/claude-code.ts +133 -0
- package/src/llm/codex.ts +116 -0
- package/src/llm/factory.ts +15 -0
- package/src/llm/openai-compat.ts +2 -1
- package/src/llm/smart-router.ts +0 -10
- package/src/scheduler/cron.ts +26 -11
- package/src/scheduler/natural-cron.ts +55 -2
- package/src/secrets/store.ts +8 -14
- package/src/setup.ts +351 -113
- package/src/start.ts +60 -107
- package/src/tools/builtin/config-update.ts +148 -0
- package/src/tools/builtin/cron.ts +76 -7
- package/src/tools/builtin/delegate-task.ts +14 -3
- package/src/tools/builtin/delegate.ts +3 -1
- package/src/tools/builtin/manage-agents.ts +17 -0
- package/src/tools/builtin-integrations/claude-code/claude_code_task/SKILL.md +38 -0
- package/src/tools/builtin-integrations/claude-code/claude_code_task/handler.ts +100 -0
- package/src/tools/builtin-integrations/codex/codex_task/SKILL.md +33 -0
- package/src/tools/builtin-integrations/codex/codex_task/handler.ts +73 -0
- package/src/tools/builtin-integrations/github/github_issues/handler.ts +10 -2
- package/src/tools/builtin-integrations/github/github_prs/handler.ts +10 -2
- package/src/tools/builtin-integrations/github/github_repos/handler.ts +10 -2
- package/src/tools/builtin-integrations/google/gmail/handler.ts +7 -0
- package/src/tools/builtin-integrations/google/google_calendar/handler.ts +7 -0
- package/src/tools/builtin-integrations/google/google_docs/handler.ts +7 -0
- package/src/tools/builtin-integrations/google/google_drive/handler.ts +7 -0
- package/src/tools/builtin-integrations/google/google_sheets/handler.ts +7 -0
- package/src/tools/builtin-integrations/linear/linear_issues/handler.ts +10 -2
- package/src/tools/builtin-integrations/linear/linear_projects/handler.ts +10 -2
- package/src/tools/builtin-integrations/notion/notion_databases/handler.ts +10 -2
- package/src/tools/builtin-integrations/notion/notion_pages/handler.ts +10 -2
- package/src/tools/builtin-integrations/notion/notion_search/handler.ts +10 -2
- package/src/tools/builtin-integrations/slack/slack_messages/handler.ts +10 -2
- package/src/tools/builtin-skills/oauth-manage/SKILL.md +15 -0
- package/src/tools/builtin-skills/oauth-manage/handler.ts +156 -0
- package/src/tools/executor.ts +11 -23
- package/src/tools/integration-installer.ts +2 -0
- package/src/tools/mcp-client.ts +48 -7
- package/src/tools/mcp-server.ts +176 -0
- package/src/tools/oauth.ts +648 -0
- package/src/tools/permissions.ts +29 -12
- package/src/util/auth.ts +9 -2
- package/src/util/costs.ts +4 -0
- package/src/util/logger.ts +2 -2
- package/src/util/mask.ts +10 -0
- package/tests/code-interpreter.test.ts +229 -0
- package/tests/config-schema.test.ts +557 -0
- package/tests/email.test.ts +122 -0
- package/tests/image-generate.test.ts +156 -0
- package/tests/knowledge-graph.test.ts +553 -0
- package/tests/mcp-client.test.ts +428 -0
- package/tests/webhook-manage.test.ts +234 -0
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<strong>Your AI agent that never forgets.</strong><br>
|
|
9
|
-
Persistent memory,
|
|
9
|
+
Persistent memory, 25+ tools, 7 channels, 11+ LLM providers — runs entirely on your machine.
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
## Features
|
|
28
28
|
|
|
29
29
|
- **11+ LLM providers** — Anthropic, OpenAI, Google Gemini, Ollama, Groq, Together, OpenRouter, DeepSeek, xAI, Fireworks, LM Studio, and any OpenAI-compatible endpoint. Smart routing sends simple queries to fast models automatically.
|
|
30
|
-
- **
|
|
30
|
+
- **7 channels** — Telegram, Discord, Slack, WhatsApp, Signal, Email, Web Chat
|
|
31
31
|
- **Persistent memory** — Vector + full-text hybrid search with ONNX embeddings and FTS5. Remembers every conversation, preference, and fact — forever.
|
|
32
|
-
- **
|
|
32
|
+
- **25+ built-in tools** — Web search, file ops, code execution, APIs, sub-agent delegation, knowledge graph, reminders, and automatic failover between providers.
|
|
33
33
|
- **Extensible skills** — Build custom skills in TypeScript. Share them on the registry. Install community skills with one command.
|
|
34
|
-
- **
|
|
34
|
+
- **9 integrations** — GitHub, Google (Gmail, Calendar, Docs, Drive, Sheets), Notion, Linear, Jira, Slack, Twitter + Claude Code and MCP
|
|
35
35
|
- **Workflows** — Multi-agent pipelines with delegation
|
|
36
36
|
- **Natural language scheduling** — "Every weekday at 9am" just works. Cron jobs, heartbeat, proactive tasks.
|
|
37
37
|
- **Voice** — Speech-to-text (Whisper) and text-to-speech (OpenAI, ElevenLabs)
|
|
@@ -98,6 +98,7 @@ See the full [configuration reference](https://zubo.bot/docs/config.html) for al
|
|
|
98
98
|
| **Discord** | Add `channels.discord.botToken` from [Developer Portal](https://discord.com/developers) |
|
|
99
99
|
| **Slack** | Add `channels.slack.botToken` + `appToken` (Socket Mode) |
|
|
100
100
|
| **WhatsApp** | Add `channels.whatsapp`, authenticate via QR |
|
|
101
|
+
| **Email** | Add `channels.email` with IMAP/SMTP settings |
|
|
101
102
|
| **Signal** | Install signal-cli, add `channels.signal.phoneNumber` |
|
|
102
103
|
|
|
103
104
|
## Integrations
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS oauth_tokens (
|
|
2
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
3
|
+
provider TEXT NOT NULL UNIQUE,
|
|
4
|
+
access_token TEXT NOT NULL,
|
|
5
|
+
refresh_token TEXT,
|
|
6
|
+
token_type TEXT DEFAULT 'Bearer',
|
|
7
|
+
expires_at TEXT,
|
|
8
|
+
scope TEXT,
|
|
9
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
10
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
11
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE cron_jobs ADD COLUMN once INTEGER NOT NULL DEFAULT 0;
|
package/package.json
CHANGED
package/site/docs/agents.html
CHANGED
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
<div class="docs-sidebar-links">
|
|
67
67
|
<a href="channels.html">Channel Setup</a>
|
|
68
68
|
<a href="integrations.html">Integrations</a>
|
|
69
|
+
<a href="integrations.html#oauth">OAuth</a>
|
|
69
70
|
<a href="security.html">Security & Auth</a>
|
|
70
71
|
</div>
|
|
71
72
|
</div>
|
|
@@ -115,6 +116,65 @@ You are Zubo, a personal AI assistant for Thomas.
|
|
|
115
116
|
- He prefers metric units and Markdown formatting.</code></pre>
|
|
116
117
|
<p>The system prompt is loaded fresh on every message, so changes take effect immediately without restarting Zubo.</p>
|
|
117
118
|
|
|
119
|
+
<h2>Self-Configuration</h2>
|
|
120
|
+
<p>Zubo can modify its own configuration at runtime through the built-in <code>config_update</code> tool. You do not need to edit <code>config.json</code> by hand — just tell Zubo what you want to change in plain language and it will update the configuration file for you.</p>
|
|
121
|
+
|
|
122
|
+
<h3>What Zubo Can Change</h3>
|
|
123
|
+
<ul>
|
|
124
|
+
<li><strong>Switch LLM providers</strong> — "Use GPT-4o" updates <code>activeProvider</code> to <code>openai</code>.</li>
|
|
125
|
+
<li><strong>Set budgets</strong> — "Limit my daily spending to $5" updates <code>budget.dailyLimitUsd</code>.</li>
|
|
126
|
+
<li><strong>Enable smart routing</strong> — "Enable smart routing with Groq" updates <code>smartRouting.enabled</code> and <code>smartRouting.fastProvider</code>.</li>
|
|
127
|
+
<li><strong>Change its name</strong> — "Call yourself Jarvis" updates <code>agentName</code>.</li>
|
|
128
|
+
<li><strong>Toggle features</strong> — Enable or disable channels, change the heartbeat interval, adjust max turns, and more.</li>
|
|
129
|
+
</ul>
|
|
130
|
+
|
|
131
|
+
<h3>What It Cannot Change</h3>
|
|
132
|
+
<ul>
|
|
133
|
+
<li><strong>API keys and tokens</strong> — For security, secrets are never stored through <code>config_update</code>. Zubo uses the separate <code>secret_set</code> tool to securely store API keys, passwords, and tokens.</li>
|
|
134
|
+
<li><strong>Channel restarts</strong> — Channel configuration changes (enabling Telegram, changing a bot token) require a restart to take effect.</li>
|
|
135
|
+
</ul>
|
|
136
|
+
|
|
137
|
+
<h3>Example</h3>
|
|
138
|
+
<pre><code>You: I want to switch to Claude Opus for complex tasks but use Groq for simple ones
|
|
139
|
+
|
|
140
|
+
Zubo: Done! I've set your active provider to Anthropic and enabled smart
|
|
141
|
+
routing with Groq as the fast provider. Simple queries like greetings
|
|
142
|
+
will use Groq (fast, inexpensive), while complex tasks like code
|
|
143
|
+
generation and multi-step reasoning use Claude.
|
|
144
|
+
|
|
145
|
+
# Under the hood, Zubo called config_update three times:
|
|
146
|
+
# set activeProvider = "anthropic"
|
|
147
|
+
# set smartRouting.enabled = true
|
|
148
|
+
# set smartRouting.fastProvider = "groq"</code></pre>
|
|
149
|
+
|
|
150
|
+
<h2>How Zubo Learns</h2>
|
|
151
|
+
<p>Zubo's memory is organized into three complementary layers, each serving a different purpose. Together, they give the agent persistent, searchable, and structured knowledge that improves over time.</p>
|
|
152
|
+
|
|
153
|
+
<h3>1. Conversational Memory</h3>
|
|
154
|
+
<p>Every conversation session is automatically persisted. Recent messages are always included in the LLM context, so Zubo remembers what you discussed earlier in the same session without any explicit action on your part.</p>
|
|
155
|
+
|
|
156
|
+
<h3>2. Semantic Memory</h3>
|
|
157
|
+
<p>Facts, notes, and documents saved via the <code>memory_write</code> tool are chunked, embedded as 384-dimensional vectors, and indexed for full-text search. When you send a message, Zubo automatically runs a hybrid search (60% vector similarity + 40% keyword matching) to find relevant memories and inject them into the context. See the <a href="memory.html">Memory System</a> page for full details.</p>
|
|
158
|
+
|
|
159
|
+
<h3>3. Knowledge Graph</h3>
|
|
160
|
+
<p>Structured entity-relationship memory captures discrete facts in a queryable format. Entities (people, projects, organizations, concepts) are linked by labeled relationships (works_on, manages, uses). When you mention a known entity, its graph context is automatically injected into the LLM prompt.</p>
|
|
161
|
+
|
|
162
|
+
<h3>How the Layers Work Together</h3>
|
|
163
|
+
<pre><code>You: I'm working with Alex on the Horizon project. He handles backend,
|
|
164
|
+
I do frontend.
|
|
165
|
+
|
|
166
|
+
Zubo automatically:
|
|
167
|
+
1. Saves this to semantic memory via memory_write
|
|
168
|
+
2. Creates KG entities: You (person), Alex (person), Horizon (project)
|
|
169
|
+
3. Creates KG relations:
|
|
170
|
+
You --works_on--> Horizon
|
|
171
|
+
Alex --works_on--> Horizon
|
|
172
|
+
You --role:frontend--> Horizon
|
|
173
|
+
Alex --role:backend--> Horizon
|
|
174
|
+
4. Next time you mention "Alex" or "Horizon", this context is
|
|
175
|
+
auto-injected into the LLM prompt</code></pre>
|
|
176
|
+
<p>This means you can teach Zubo facts naturally through conversation, and it will recall them when relevant — without being asked.</p>
|
|
177
|
+
|
|
118
178
|
<h2>Creating Custom Agents</h2>
|
|
119
179
|
<p>Custom agents are defined as directories inside <code>~/.zubo/workspace/agents/</code>. Each directory contains a single <code>AGENT.md</code> file that specifies the agent's name, description, system prompt, and allowed tools.</p>
|
|
120
180
|
<p>Here is an example <code>AGENT.md</code> for a research specialist:</p>
|
|
@@ -137,6 +197,26 @@ to ensure comprehensive coverage.
|
|
|
137
197
|
<li><strong>Conversationally</strong> — Tell Zubo: "Create an agent called research_agent that specializes in web research and has access to web_search, url_fetch, and memory_write." Zubo will generate the <code>AGENT.md</code> for you.</li>
|
|
138
198
|
<li><strong>Programmatically</strong> — Use the <code>manage_agents</code> tool to create, update, list, or delete agents.</li>
|
|
139
199
|
</ul>
|
|
200
|
+
<p>Here is an example of creating and using an agent entirely through conversation:</p>
|
|
201
|
+
<pre><code>You: Create an agent called "researcher" that can only search the web
|
|
202
|
+
and fetch URLs. Its job is deep research.
|
|
203
|
+
|
|
204
|
+
Zubo: Created agent "researcher" with tools: web_search, url_fetch,
|
|
205
|
+
http_request. System prompt focused on thorough research and
|
|
206
|
+
source citation.
|
|
207
|
+
|
|
208
|
+
You: @researcher Find the top 3 competitors to Linear and compare
|
|
209
|
+
their pricing
|
|
210
|
+
|
|
211
|
+
Zubo: [delegates to researcher agent]
|
|
212
|
+
|
|
213
|
+
Here's a comparison of Linear's top competitors:
|
|
214
|
+
|
|
215
|
+
1. Jira — Free tier for up to 10 users, Standard at $8.15/user/mo...
|
|
216
|
+
2. Shortcut — Free for up to 10 members, Team at $8.50/user/mo...
|
|
217
|
+
3. Asana — Free tier available, Premium at $10.99/user/mo...
|
|
218
|
+
|
|
219
|
+
Sources: [jira.com, shortcut.com, asana.com]</code></pre>
|
|
140
220
|
<p>Agents have restricted tool access — they can only use the tools explicitly listed in their <code>## Tools</code> section. This is a key security and reliability feature: a research agent does not need access to your calendar, and a writing agent does not need access to the shell.</p>
|
|
141
221
|
|
|
142
222
|
<h3>Agent Fields</h3>
|
|
@@ -156,8 +236,9 @@ to ensure comprehensive coverage.
|
|
|
156
236
|
<ul>
|
|
157
237
|
<li><strong>Maximum delegation depth: 2</strong> — This prevents infinite recursion. The main agent (depth 0) can delegate to a sub-agent (depth 1), which can delegate once more (depth 2), but no further.</li>
|
|
158
238
|
<li><strong>Sub-agents cannot delegate further or access the <code>manage_agents</code> or <code>delegate</code> tools</strong> — These tools are automatically stripped from sub-agent tool lists to prevent abuse.</li>
|
|
239
|
+
<li><strong>Immutable security preamble</strong> — Every sub-agent's system prompt is prefixed with an immutable set of security rules that cannot be overridden by the user-defined agent prompt. These rules prevent sub-agents from revealing secrets, bypassing tool permission levels, delegating to other agents, or modifying their own configuration.</li>
|
|
159
240
|
<li><strong>Each delegation creates a separate session</strong> — This provides context isolation. The sub-agent's conversation history does not bleed into the main agent's context.</li>
|
|
160
|
-
<li><strong>Memory is shared</strong> — Sub-agents
|
|
241
|
+
<li><strong>Memory is shared</strong> — Sub-agents share the same memory store (semantic memory and knowledge graph) as the main agent. Research findings, facts, and knowledge graph entities written by a sub-agent are immediately available to the main agent and all other sub-agents.</li>
|
|
161
242
|
</ul>
|
|
162
243
|
<p>Here is an example of how delegation works in practice:</p>
|
|
163
244
|
<pre><code>User: "Research the latest AI news and summarize it"
|
package/site/docs/api.html
CHANGED
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
<div class="docs-sidebar-links">
|
|
67
67
|
<a href="channels.html">Channel Setup</a>
|
|
68
68
|
<a href="integrations.html">Integrations</a>
|
|
69
|
+
<a href="integrations.html#oauth">OAuth</a>
|
|
69
70
|
<a href="security.html">Security & Auth</a>
|
|
70
71
|
</div>
|
|
71
72
|
</div>
|
|
@@ -231,9 +232,9 @@ Content-Type: application/json
|
|
|
231
232
|
]
|
|
232
233
|
}</code></pre>
|
|
233
234
|
|
|
234
|
-
<h3>Cron Jobs</h3>
|
|
235
|
+
<h3>Cron Jobs & Reminders</h3>
|
|
235
236
|
<pre><code>GET /api/dashboard/cron</code></pre>
|
|
236
|
-
<p>List all configured cron jobs and
|
|
237
|
+
<p>List all configured cron jobs and one-shot reminders.</p>
|
|
237
238
|
<p><strong>Response:</strong></p>
|
|
238
239
|
<pre><code>{
|
|
239
240
|
"jobs": [
|
|
@@ -242,18 +243,313 @@ Content-Type: application/json
|
|
|
242
243
|
"schedule": "0 9 * * *",
|
|
243
244
|
"task": "Send a daily briefing",
|
|
244
245
|
"enabled": true,
|
|
246
|
+
"once": false,
|
|
245
247
|
"last_run": "2026-02-12T09:00:00Z"
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"name": "marketing-followup",
|
|
251
|
+
"schedule": "2026-02-14T15:30:00.000Z",
|
|
252
|
+
"task": "Hey! Have you worked on marketing yet?",
|
|
253
|
+
"enabled": true,
|
|
254
|
+
"once": true,
|
|
255
|
+
"last_run": null
|
|
246
256
|
}
|
|
247
257
|
]
|
|
248
258
|
}</code></pre>
|
|
259
|
+
<p>Jobs with <code>"once": true</code> are one-shot reminders that auto-delete after firing.</p>
|
|
260
|
+
|
|
261
|
+
<h3>Providers</h3>
|
|
262
|
+
<pre><code>GET /api/dashboard/providers</code></pre>
|
|
263
|
+
<p>List all configured LLM providers with masked API keys, the active provider, and the failover order.</p>
|
|
264
|
+
<p><strong>Response:</strong></p>
|
|
265
|
+
<pre><code>{
|
|
266
|
+
"providers": [
|
|
267
|
+
{
|
|
268
|
+
"name": "anthropic",
|
|
269
|
+
"model": "claude-sonnet-4-5-20250929",
|
|
270
|
+
"apiKey": "sk-ant-...xxxx",
|
|
271
|
+
"baseUrl": "",
|
|
272
|
+
"contextWindow": null,
|
|
273
|
+
"streaming": true
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"name": "openai",
|
|
277
|
+
"model": "gpt-4o",
|
|
278
|
+
"apiKey": "sk-...xxxx",
|
|
279
|
+
"baseUrl": "",
|
|
280
|
+
"contextWindow": null,
|
|
281
|
+
"streaming": true
|
|
282
|
+
}
|
|
283
|
+
],
|
|
284
|
+
"activeProvider": "anthropic",
|
|
285
|
+
"failover": ["openai"]
|
|
286
|
+
}</code></pre>
|
|
287
|
+
<pre><code>PUT /api/dashboard/providers/:name
|
|
288
|
+
Content-Type: application/json
|
|
289
|
+
|
|
290
|
+
{
|
|
291
|
+
"model": "gpt-4o",
|
|
292
|
+
"apiKey": "sk-...",
|
|
293
|
+
"baseUrl": "",
|
|
294
|
+
"streaming": true
|
|
295
|
+
}</code></pre>
|
|
296
|
+
<p>Add or update a provider configuration. If this is the first provider, it is automatically set as active. Masked API key values (containing <code>...</code>) are ignored to preserve the existing key.</p>
|
|
297
|
+
<pre><code>DELETE /api/dashboard/providers/:name</code></pre>
|
|
298
|
+
<p>Remove a provider. If the deleted provider was active, the first remaining provider is selected. The provider is also removed from the failover list.</p>
|
|
299
|
+
<pre><code>PUT /api/dashboard/providers/active
|
|
300
|
+
Content-Type: application/json
|
|
301
|
+
|
|
302
|
+
{
|
|
303
|
+
"provider": "openai"
|
|
304
|
+
}</code></pre>
|
|
305
|
+
<p>Set the active LLM provider. The change is hot-reloaded into the running agent — no restart is needed.</p>
|
|
306
|
+
<pre><code>PUT /api/dashboard/providers/failover
|
|
307
|
+
Content-Type: application/json
|
|
308
|
+
|
|
309
|
+
{
|
|
310
|
+
"failover": ["openai", "anthropic"]
|
|
311
|
+
}</code></pre>
|
|
312
|
+
<p>Update the provider failover order. When the active provider fails, the agent tries each failover provider in the order listed.</p>
|
|
313
|
+
|
|
314
|
+
<h3>MCP Servers</h3>
|
|
315
|
+
<pre><code>GET /api/dashboard/mcp/servers</code></pre>
|
|
316
|
+
<p>List all configured MCP (Model Context Protocol) server connections with their current status and tool count.</p>
|
|
317
|
+
<p><strong>Response:</strong></p>
|
|
318
|
+
<pre><code>{
|
|
319
|
+
"servers": [
|
|
320
|
+
{
|
|
321
|
+
"name": "filesystem",
|
|
322
|
+
"command": "npx",
|
|
323
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem"],
|
|
324
|
+
"env": ["HOME"],
|
|
325
|
+
"enabled": true,
|
|
326
|
+
"connected": true,
|
|
327
|
+
"tools": 5
|
|
328
|
+
}
|
|
329
|
+
]
|
|
330
|
+
}</code></pre>
|
|
331
|
+
<pre><code>POST /api/dashboard/mcp/servers
|
|
332
|
+
Content-Type: application/json
|
|
333
|
+
|
|
334
|
+
{
|
|
335
|
+
"name": "filesystem",
|
|
336
|
+
"command": "npx",
|
|
337
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem"],
|
|
338
|
+
"env": { "HOME": "/Users/me" },
|
|
339
|
+
"enabled": true
|
|
340
|
+
}</code></pre>
|
|
341
|
+
<p>Add and connect a new MCP server. If a server with the same name already exists, it is replaced. The server is hot-connected immediately if <code>enabled</code> is <code>true</code> (or omitted).</p>
|
|
342
|
+
<pre><code>DELETE /api/dashboard/mcp/servers/:name</code></pre>
|
|
343
|
+
<p>Disconnect and remove an MCP server. The server process is terminated and the configuration is deleted.</p>
|
|
344
|
+
<pre><code>POST /api/dashboard/mcp/servers/:name/restart</code></pre>
|
|
345
|
+
<p>Restart an MCP server connection. The server is disconnected and then reconnected using its saved configuration. Returns <code>404</code> if the server is not found.</p>
|
|
346
|
+
|
|
347
|
+
<h3>Channels Configuration</h3>
|
|
348
|
+
<pre><code>GET /api/dashboard/channels/config</code></pre>
|
|
349
|
+
<p>Get all channel configurations with masked tokens and running status. Returns an object keyed by channel name (telegram, discord, slack, whatsapp, signal, email), each containing <code>enabled</code>, <code>configured</code>, <code>running</code>, and <code>config</code> fields.</p>
|
|
350
|
+
<pre><code>PUT /api/dashboard/channels/:name/config
|
|
351
|
+
Content-Type: application/json
|
|
352
|
+
|
|
353
|
+
{
|
|
354
|
+
"botToken": "123456:ABC-DEF...",
|
|
355
|
+
"allowedUsers": ["user1"],
|
|
356
|
+
"enabled": true
|
|
357
|
+
}</code></pre>
|
|
358
|
+
<p>Update a channel's configuration. Valid channel names are <code>telegram</code>, <code>discord</code>, <code>slack</code>, <code>whatsapp</code>, <code>signal</code>, and <code>email</code>. If <code>enabled</code> is <code>true</code>, the channel is hot-started immediately. If <code>false</code>, the channel is stopped. Masked token values are preserved.</p>
|
|
359
|
+
<pre><code>PUT /api/dashboard/channels/:name/toggle
|
|
360
|
+
Content-Type: application/json
|
|
361
|
+
|
|
362
|
+
{
|
|
363
|
+
"enabled": true
|
|
364
|
+
}</code></pre>
|
|
365
|
+
<p>Enable or disable a channel with immediate start or stop. The channel must already be configured.</p>
|
|
366
|
+
|
|
367
|
+
<h3>OAuth</h3>
|
|
368
|
+
<pre><code>GET /api/dashboard/oauth/status</code></pre>
|
|
369
|
+
<p>Get OAuth connection status for all supported providers. Returns a list of supported providers and their current connection state, including whether each provider has credentials configured.</p>
|
|
370
|
+
<pre><code>PUT /api/dashboard/oauth/:provider/config
|
|
371
|
+
Content-Type: application/json
|
|
372
|
+
|
|
373
|
+
{
|
|
374
|
+
"clientId": "your-client-id",
|
|
375
|
+
"clientSecret": "your-client-secret"
|
|
376
|
+
}</code></pre>
|
|
377
|
+
<p>Save OAuth client credentials for a provider (e.g. <code>google</code>, <code>github</code>). These credentials are stored in the config file and used when initiating OAuth authorization flows.</p>
|
|
378
|
+
<pre><code>DELETE /api/dashboard/oauth/:provider/config</code></pre>
|
|
379
|
+
<p>Remove OAuth client credentials for a provider from the configuration.</p>
|
|
380
|
+
<pre><code>DELETE /api/dashboard/oauth/:provider</code></pre>
|
|
381
|
+
<p>Disconnect an OAuth provider by revoking its stored tokens. The client credentials remain in the configuration.</p>
|
|
382
|
+
|
|
383
|
+
<h3>Budget</h3>
|
|
384
|
+
<pre><code>GET /api/dashboard/budget</code></pre>
|
|
385
|
+
<p>Get budget configuration and current usage, including today's spend, this month's spend, and a daily breakdown for the last 7 days.</p>
|
|
386
|
+
<p><strong>Response:</strong></p>
|
|
387
|
+
<pre><code>{
|
|
388
|
+
"daily_limit_usd": 5.00,
|
|
389
|
+
"monthly_limit_usd": 100.00,
|
|
390
|
+
"alert_threshold": 0.8,
|
|
391
|
+
"paused": false,
|
|
392
|
+
"today_spend_usd": 1.2345,
|
|
393
|
+
"month_spend_usd": 42.50,
|
|
394
|
+
"daily_breakdown": [
|
|
395
|
+
{ "day": "2026-02-13", "cost": 1.50, "tokens": 45000 },
|
|
396
|
+
{ "day": "2026-02-14", "cost": 1.23, "tokens": 38000 }
|
|
397
|
+
]
|
|
398
|
+
}</code></pre>
|
|
399
|
+
<pre><code>PUT /api/dashboard/budget
|
|
400
|
+
Content-Type: application/json
|
|
401
|
+
|
|
402
|
+
{
|
|
403
|
+
"daily_limit_usd": 5.00,
|
|
404
|
+
"monthly_limit_usd": 100.00,
|
|
405
|
+
"alert_threshold": 0.8
|
|
406
|
+
}</code></pre>
|
|
407
|
+
<p>Update budget limits. Set a field to <code>null</code> to remove that limit. The <code>alert_threshold</code> is a fraction (0–1) of the limit at which a warning is triggered. Updating the budget also resets the <code>paused</code> state.</p>
|
|
408
|
+
|
|
409
|
+
<h3>Privacy & Data</h3>
|
|
410
|
+
<pre><code>GET /api/dashboard/privacy/summary</code></pre>
|
|
411
|
+
<p>Get a summary of all stored data, including counts of memories, messages, sessions, secrets, cron jobs, API calls, tool calls, and total tokens sent and received.</p>
|
|
412
|
+
<p><strong>Response:</strong></p>
|
|
413
|
+
<pre><code>{
|
|
414
|
+
"memoryCount": 567,
|
|
415
|
+
"messageCount": 1234,
|
|
416
|
+
"sessionCount": 15,
|
|
417
|
+
"secretCount": 3,
|
|
418
|
+
"cronCount": 2,
|
|
419
|
+
"apiCallCount": 890,
|
|
420
|
+
"toolCallCount": 456,
|
|
421
|
+
"totalTokensSent": 1500000,
|
|
422
|
+
"totalTokensReceived": 750000,
|
|
423
|
+
"providerBreakdown": [
|
|
424
|
+
{ "provider": "anthropic", "calls": 800, "tokens_sent": 1200000 }
|
|
425
|
+
]
|
|
426
|
+
}</code></pre>
|
|
427
|
+
<pre><code>GET /api/dashboard/privacy/api-log?limit=50&offset=0</code></pre>
|
|
428
|
+
<p>View API call history with session ID, provider, model, token counts, cost, and response time. Supports pagination via <code>limit</code> (max 100) and <code>offset</code> query parameters.</p>
|
|
429
|
+
<pre><code>GET /api/dashboard/privacy/tool-log?limit=50&offset=0</code></pre>
|
|
430
|
+
<p>View tool call history with tool name, session ID, duration, and success status. Supports pagination via <code>limit</code> (max 100) and <code>offset</code> query parameters.</p>
|
|
431
|
+
<pre><code>POST /api/dashboard/privacy/wipe-memories
|
|
432
|
+
Content-Type: application/json
|
|
433
|
+
|
|
434
|
+
{ "confirm": "DELETE" }</code></pre>
|
|
435
|
+
<p>Delete all memory chunks and full-text search index. Requires <code>{ "confirm": "DELETE" }</code> in the request body.</p>
|
|
436
|
+
<pre><code>POST /api/dashboard/privacy/wipe-messages
|
|
437
|
+
Content-Type: application/json
|
|
438
|
+
|
|
439
|
+
{ "confirm": "DELETE" }</code></pre>
|
|
440
|
+
<p>Delete all stored messages. Requires <code>{ "confirm": "DELETE" }</code> in the request body.</p>
|
|
441
|
+
<pre><code>POST /api/dashboard/privacy/wipe-usage
|
|
442
|
+
Content-Type: application/json
|
|
443
|
+
|
|
444
|
+
{ "confirm": "DELETE" }</code></pre>
|
|
445
|
+
<p>Delete all usage analytics and tool metrics. Requires <code>{ "confirm": "DELETE" }</code> in the request body.</p>
|
|
446
|
+
<pre><code>POST /api/dashboard/privacy/wipe-all
|
|
447
|
+
Content-Type: application/json
|
|
448
|
+
|
|
449
|
+
{ "confirm": "DELETE_ALL" }</code></pre>
|
|
450
|
+
<p>Complete data wipe: deletes all memories, messages, usage analytics, tool metrics, secrets, and cron logs. Requires <code>{ "confirm": "DELETE_ALL" }</code> in the request body.</p>
|
|
451
|
+
|
|
452
|
+
<h3>Threads</h3>
|
|
453
|
+
<pre><code>GET /api/dashboard/threads</code></pre>
|
|
454
|
+
<p>List all conversation threads, ordered by most recently updated.</p>
|
|
455
|
+
<pre><code>POST /api/dashboard/threads
|
|
456
|
+
Content-Type: application/json
|
|
457
|
+
|
|
458
|
+
{
|
|
459
|
+
"title": "Project discussion"
|
|
460
|
+
}</code></pre>
|
|
461
|
+
<p>Create a new conversation thread. The <code>title</code> field is optional and defaults to "New conversation". Returns the generated thread <code>id</code> and <code>title</code>.</p>
|
|
462
|
+
<pre><code>PUT /api/dashboard/threads/:id
|
|
463
|
+
Content-Type: application/json
|
|
464
|
+
|
|
465
|
+
{
|
|
466
|
+
"title": "Renamed thread"
|
|
467
|
+
}</code></pre>
|
|
468
|
+
<p>Rename a thread by its ID.</p>
|
|
469
|
+
<pre><code>DELETE /api/dashboard/threads/:id</code></pre>
|
|
470
|
+
<p>Delete a thread and its associated session file.</p>
|
|
471
|
+
<pre><code>GET /api/dashboard/threads/:id/messages</code></pre>
|
|
472
|
+
<p>Get the messages in a thread (up to 100 messages). Returns the session's message array.</p>
|
|
473
|
+
<pre><code>GET /api/dashboard/threads/:id/export</code></pre>
|
|
474
|
+
<p>Export a thread as a Markdown file. Returns a <code>text/markdown</code> response with a <code>Content-Disposition</code> header for download.</p>
|
|
475
|
+
|
|
476
|
+
<h3>Recipes</h3>
|
|
477
|
+
<pre><code>GET /api/dashboard/recipes</code></pre>
|
|
478
|
+
<p>List all available workflow recipe templates with their install status. Each recipe includes its <code>id</code>, metadata, and an <code>installed</code> flag indicating whether it has already been added as a cron job.</p>
|
|
479
|
+
<pre><code>POST /api/dashboard/recipes/install
|
|
480
|
+
Content-Type: application/json
|
|
481
|
+
|
|
482
|
+
{
|
|
483
|
+
"recipeId": "daily-summary"
|
|
484
|
+
}</code></pre>
|
|
485
|
+
<p>Install a recipe as a cron job. The recipe is looked up by <code>recipeId</code> and inserted into the cron jobs table. Returns an error if the recipe is already installed.</p>
|
|
486
|
+
<pre><code>POST /api/dashboard/recipes/uninstall
|
|
487
|
+
Content-Type: application/json
|
|
488
|
+
|
|
489
|
+
{
|
|
490
|
+
"recipeId": "daily-summary"
|
|
491
|
+
}</code></pre>
|
|
492
|
+
<p>Uninstall a recipe by removing its cron job.</p>
|
|
493
|
+
|
|
494
|
+
<h3>Smart Routing</h3>
|
|
495
|
+
<pre><code>GET /api/dashboard/smart-routing</code></pre>
|
|
496
|
+
<p>Get the current smart routing configuration. Smart routing automatically directs simple queries to a faster, cheaper model while using the primary model for complex tasks.</p>
|
|
497
|
+
<p><strong>Response:</strong></p>
|
|
498
|
+
<pre><code>{
|
|
499
|
+
"enabled": false,
|
|
500
|
+
"fastProvider": "openai",
|
|
501
|
+
"fastModel": "gpt-4o-mini"
|
|
502
|
+
}</code></pre>
|
|
503
|
+
<pre><code>PUT /api/dashboard/smart-routing
|
|
504
|
+
Content-Type: application/json
|
|
505
|
+
|
|
506
|
+
{
|
|
507
|
+
"enabled": true,
|
|
508
|
+
"fastProvider": "openai",
|
|
509
|
+
"fastModel": "gpt-4o-mini"
|
|
510
|
+
}</code></pre>
|
|
511
|
+
<p>Update smart routing settings. All fields are optional — only the fields you include will be updated.</p>
|
|
249
512
|
|
|
250
513
|
<h3>Logs</h3>
|
|
251
514
|
<pre><code>GET /api/dashboard/logs</code></pre>
|
|
252
515
|
<p>Returns the last 100 log lines from the agent's log output.</p>
|
|
253
516
|
|
|
254
|
-
<h3>
|
|
517
|
+
<h3>Configuration</h3>
|
|
255
518
|
<pre><code>GET /api/dashboard/config</code></pre>
|
|
256
|
-
<p>Returns the current configuration
|
|
519
|
+
<p>Returns the current configuration summary with API keys masked.</p>
|
|
520
|
+
<p><strong>Response:</strong></p>
|
|
521
|
+
<pre><code>{
|
|
522
|
+
"agentName": "Zubo",
|
|
523
|
+
"activeProvider": "anthropic",
|
|
524
|
+
"providers": {
|
|
525
|
+
"anthropic": { "model": "claude-sonnet-4-5-20250929", "hasApiKey": true },
|
|
526
|
+
"groq": { "model": "llama-3.3-70b-versatile", "hasApiKey": true }
|
|
527
|
+
},
|
|
528
|
+
"failover": ["groq"],
|
|
529
|
+
"channels": {
|
|
530
|
+
"webchat": { "enabled": true },
|
|
531
|
+
"telegram": { "enabled": true }
|
|
532
|
+
},
|
|
533
|
+
"smartRouting": { "enabled": true, "fastProvider": "groq" },
|
|
534
|
+
"budget": { "dailyLimitUsd": 5, "monthlyLimitUsd": 50, "alertThreshold": 0.8 },
|
|
535
|
+
"maxTurns": 50,
|
|
536
|
+
"heartbeatMinutes": 30
|
|
537
|
+
}</code></pre>
|
|
538
|
+
<pre><code>PUT /api/dashboard/config
|
|
539
|
+
Content-Type: application/json
|
|
540
|
+
|
|
541
|
+
{
|
|
542
|
+
"key": "budget.dailyLimitUsd",
|
|
543
|
+
"value": 10
|
|
544
|
+
}</code></pre>
|
|
545
|
+
<p>Updates a configuration value using dot-notation paths. The value is validated against the config schema before saving. API keys and tokens cannot be set through this endpoint — use the secrets API instead.</p>
|
|
546
|
+
<p><strong>Response:</strong></p>
|
|
547
|
+
<pre><code>{
|
|
548
|
+
"success": true,
|
|
549
|
+
"key": "budget.dailyLimitUsd",
|
|
550
|
+
"value": 10,
|
|
551
|
+
"message": "Config updated. Changes take effect on next restart."
|
|
552
|
+
}</code></pre>
|
|
257
553
|
<pre><code>PUT /api/dashboard/config/model
|
|
258
554
|
Content-Type: application/json
|
|
259
555
|
|
package/site/docs/channels.html
CHANGED
|
@@ -4,18 +4,18 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Channel Setup — Zubo Docs</title>
|
|
7
|
-
<meta name="description" content="Connect Zubo to Telegram, Discord, Slack, WhatsApp, Signal, and Web Chat. Step-by-step setup guides for every supported messaging channel.">
|
|
7
|
+
<meta name="description" content="Connect Zubo to Telegram, Discord, Slack, WhatsApp, Signal, Email, and Web Chat. Step-by-step setup guides for every supported messaging channel.">
|
|
8
8
|
<meta name="theme-color" content="#060608">
|
|
9
9
|
<link rel="canonical" href="https://zubo.bot/docs/channels.html">
|
|
10
10
|
<meta property="og:title" content="Channel Setup — Zubo Docs">
|
|
11
|
-
<meta property="og:description" content="Connect Zubo to Telegram, Discord, Slack, WhatsApp, Signal, and Web Chat. Step-by-step setup guides.">
|
|
11
|
+
<meta property="og:description" content="Connect Zubo to Telegram, Discord, Slack, WhatsApp, Signal, Email, and Web Chat. Step-by-step setup guides.">
|
|
12
12
|
<meta property="og:type" content="article">
|
|
13
13
|
<meta property="og:url" content="https://zubo.bot/docs/channels.html">
|
|
14
14
|
<meta property="og:image" content="https://zubo.bot/og-image.png">
|
|
15
15
|
<meta property="og:site_name" content="Zubo">
|
|
16
16
|
<meta name="twitter:card" content="summary_large_image">
|
|
17
17
|
<meta name="twitter:title" content="Channel Setup — Zubo Docs">
|
|
18
|
-
<meta name="twitter:description" content="Connect Zubo to Telegram, Discord, Slack, WhatsApp, Signal, and Web Chat.">
|
|
18
|
+
<meta name="twitter:description" content="Connect Zubo to Telegram, Discord, Slack, WhatsApp, Signal, Email, and Web Chat.">
|
|
19
19
|
<meta name="twitter:image" content="https://zubo.bot/og-image.png">
|
|
20
20
|
<meta name="twitter:creator" content="@thomaskanze">
|
|
21
21
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
<div class="docs-sidebar-links">
|
|
73
73
|
<a href="channels.html" class="active">Channel Setup</a>
|
|
74
74
|
<a href="integrations.html">Integrations</a>
|
|
75
|
+
<a href="integrations.html#oauth">OAuth</a>
|
|
75
76
|
<a href="security.html">Security & Auth</a>
|
|
76
77
|
</div>
|
|
77
78
|
</div>
|
|
@@ -285,6 +286,72 @@ brew install signal-cli
|
|
|
285
286
|
</tbody>
|
|
286
287
|
</table>
|
|
287
288
|
|
|
289
|
+
<h2>Email</h2>
|
|
290
|
+
<p>Connect Zubo to an email account via IMAP/SMTP so it can receive and reply to emails. Great for workflows like processing incoming emails, auto-replies, or email-based task management.</p>
|
|
291
|
+
<h3>Prerequisites</h3>
|
|
292
|
+
<ul>
|
|
293
|
+
<li>An email account with IMAP and SMTP access (Gmail, Outlook, FastMail, etc.)</li>
|
|
294
|
+
<li>For Gmail, an <strong>App Password</strong> is required — your regular Google account password will not work</li>
|
|
295
|
+
</ul>
|
|
296
|
+
<h3>Setup Steps</h3>
|
|
297
|
+
<ol>
|
|
298
|
+
<li>Gather your IMAP and SMTP server details from your email provider (host, port, username, password)</li>
|
|
299
|
+
<li>Add the email channel to your Zubo config:
|
|
300
|
+
<pre><code>{
|
|
301
|
+
"channels": {
|
|
302
|
+
"email": {
|
|
303
|
+
"enabled": true,
|
|
304
|
+
"imap": {
|
|
305
|
+
"host": "imap.gmail.com",
|
|
306
|
+
"port": 993,
|
|
307
|
+
"user": "you@gmail.com",
|
|
308
|
+
"password": "your-app-password",
|
|
309
|
+
"tls": true
|
|
310
|
+
},
|
|
311
|
+
"smtp": {
|
|
312
|
+
"host": "smtp.gmail.com",
|
|
313
|
+
"port": 587,
|
|
314
|
+
"user": "you@gmail.com",
|
|
315
|
+
"password": "your-app-password",
|
|
316
|
+
"tls": true
|
|
317
|
+
},
|
|
318
|
+
"pollIntervalSeconds": 60,
|
|
319
|
+
"allowedSenders": ["boss@company.com", "team@company.com"],
|
|
320
|
+
"fromName": "Zubo Assistant"
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}</code></pre>
|
|
324
|
+
</li>
|
|
325
|
+
<li>Restart Zubo: <code>zubo restart</code></li>
|
|
326
|
+
</ol>
|
|
327
|
+
|
|
328
|
+
<h3>Config Fields</h3>
|
|
329
|
+
<table>
|
|
330
|
+
<thead>
|
|
331
|
+
<tr><th>Field</th><th>Type</th><th>Default</th><th>Description</th></tr>
|
|
332
|
+
</thead>
|
|
333
|
+
<tbody>
|
|
334
|
+
<tr><td><code>enabled</code></td><td>boolean</td><td><code>true</code></td><td>Enable or disable the Email channel</td></tr>
|
|
335
|
+
<tr><td><code>imap.host</code></td><td>string</td><td>—</td><td>IMAP server hostname (e.g., <code>imap.gmail.com</code>)</td></tr>
|
|
336
|
+
<tr><td><code>imap.port</code></td><td>number</td><td><code>993</code></td><td>IMAP server port</td></tr>
|
|
337
|
+
<tr><td><code>imap.user</code></td><td>string</td><td>—</td><td>IMAP login username (usually your email address)</td></tr>
|
|
338
|
+
<tr><td><code>imap.password</code></td><td>string</td><td>—</td><td>IMAP login password or app password</td></tr>
|
|
339
|
+
<tr><td><code>imap.tls</code></td><td>boolean</td><td><code>true</code></td><td>Use TLS for the IMAP connection</td></tr>
|
|
340
|
+
<tr><td><code>smtp.host</code></td><td>string</td><td>—</td><td>SMTP server hostname (e.g., <code>smtp.gmail.com</code>)</td></tr>
|
|
341
|
+
<tr><td><code>smtp.port</code></td><td>number</td><td><code>587</code></td><td>SMTP server port (587 for STARTTLS, 465 for implicit TLS)</td></tr>
|
|
342
|
+
<tr><td><code>smtp.user</code></td><td>string</td><td>—</td><td>SMTP login username (usually your email address)</td></tr>
|
|
343
|
+
<tr><td><code>smtp.password</code></td><td>string</td><td>—</td><td>SMTP login password or app password</td></tr>
|
|
344
|
+
<tr><td><code>smtp.tls</code></td><td>boolean</td><td><code>true</code></td><td>Use TLS for the SMTP connection</td></tr>
|
|
345
|
+
<tr><td><code>pollIntervalSeconds</code></td><td>number</td><td><code>60</code></td><td>How often (in seconds) to check for new emails. Minimum is 10.</td></tr>
|
|
346
|
+
<tr><td><code>allowedSenders</code></td><td>string[]</td><td>—</td><td>Email addresses allowed to message. If omitted or empty, all incoming emails are processed.</td></tr>
|
|
347
|
+
<tr><td><code>fromName</code></td><td>string</td><td><code>"Zubo"</code></td><td>Display name used in the <code>From</code> header of outgoing replies</td></tr>
|
|
348
|
+
</tbody>
|
|
349
|
+
</table>
|
|
350
|
+
|
|
351
|
+
<p><strong>Security note — <code>allowedSenders</code>:</strong> If set, only emails from the listed addresses will be processed. All other incoming emails are marked as read and skipped. If <code>allowedSenders</code> is omitted or empty, Zubo will process every incoming email — use this only for private or low-traffic mailboxes.</p>
|
|
352
|
+
|
|
353
|
+
<p><strong>Gmail setup:</strong> Gmail requires an App Password for third-party IMAP/SMTP access. To create one, go to <a href="https://myaccount.google.com/apppasswords">Google Account → Security → App Passwords</a> (requires 2-Step Verification to be enabled). Generate a new app password, then use that 16-character password in both the <code>imap.password</code> and <code>smtp.password</code> fields above.</p>
|
|
354
|
+
|
|
288
355
|
<h2>Running Multiple Channels</h2>
|
|
289
356
|
<p>Zubo is designed to run all channels simultaneously. There is no limit to how many channels you can enable at once.</p>
|
|
290
357
|
<ul>
|