@botuyo/mcp 0.7.5 → 0.8.0
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 +26 -4
- package/dist/commands/auth.d.ts +1 -1
- package/dist/commands/auth.js +1 -1
- package/dist/index.js +19 -3
- package/dist/index.js.map +1 -1
- package/dist/tools/__tests__/channels.spec.d.ts +1 -0
- package/dist/tools/__tests__/channels.spec.js +93 -0
- package/dist/tools/__tests__/channels.spec.js.map +1 -0
- package/dist/tools/__tests__/ingest_knowledge_url.spec.d.ts +1 -0
- package/dist/tools/__tests__/ingest_knowledge_url.spec.js +39 -0
- package/dist/tools/__tests__/ingest_knowledge_url.spec.js.map +1 -0
- package/dist/tools/__tests__/upload_agent_media.spec.d.ts +1 -0
- package/dist/tools/__tests__/upload_agent_media.spec.js +68 -0
- package/dist/tools/__tests__/upload_agent_media.spec.js.map +1 -0
- package/dist/tools/channels.d.ts +24 -0
- package/dist/tools/channels.js +105 -0
- package/dist/tools/channels.js.map +1 -0
- package/dist/tools/index.js +7 -0
- package/dist/tools/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -74,7 +74,9 @@ The server resolves your JWT from `BOTUYO_TOKEN`, falling back to `~/.botuyo/cre
|
|
|
74
74
|
|
|
75
75
|
## Available tools
|
|
76
76
|
|
|
77
|
-
The server exposes **
|
|
77
|
+
The server exposes **45 tools**. Read tools (`list_*`, `get_*`, `export_*`, `audit_*`) need `viewer+`; write/publish tools need `developer+`; channel connect/disconnect need `admin+` (see [Roles](#roles)).
|
|
78
|
+
|
|
79
|
+
> **For AI assistants / IDE agents:** every tool is self-describing — its `inputSchema` lists the exact arguments (with `required`) and its `description` states role requirements and side effects. Discover the live catalog with the MCP `tools/list` request; you never need to hardcode tool names. A typical build flow is `create_agent` → `update_agent` (identity/voice) → `upsert_stage` (conversation graph) → `update_enabled_tools` / `configure_agent_tool` (capabilities) → `publish_agent`. Use `example_agent` to see a fully documented reference config, and `audit_agent_family` to validate before publishing.
|
|
78
80
|
|
|
79
81
|
### Agents
|
|
80
82
|
|
|
@@ -105,7 +107,8 @@ A **family** is one logical agent with a shared `base` config plus multiple `var
|
|
|
105
107
|
| `publish_agent_family` | Publish the family and all its member agents |
|
|
106
108
|
| `delete_agent_family` | Delete a family and all its agents (irreversible; requires confirmation) |
|
|
107
109
|
| `export_agent_family` | Export a portable family JSON (base + variants) to a local file |
|
|
108
|
-
| `import_agent_family` | Replace a family's base + variants from JSON (full replace) |
|
|
110
|
+
| `import_agent_family` | Replace a family's base + variants from JSON (full replace), or create a new family from a folder/payload |
|
|
111
|
+
| `audit_agent_family` | Read-only config-quality audit of one family (`familyId`) or all families in the tenant — flags invalid/non-canonical voices, over-long `customInstructions`, non-URL avatars, deprecated AI models; changes nothing |
|
|
109
112
|
|
|
110
113
|
### Conversation flow
|
|
111
114
|
|
|
@@ -163,6 +166,23 @@ A **family** is one logical agent with a shared `base` config plus multiple `var
|
|
|
163
166
|
| `list_agent_versions` | List an agent's saved version snapshots |
|
|
164
167
|
| `restore_agent_version` | Roll back an agent to a previous version |
|
|
165
168
|
|
|
169
|
+
### Channels
|
|
170
|
+
|
|
171
|
+
Connect messaging channels to the tenant **with their secrets**. Secrets are **write-only** — the server stores them and never returns their values; `list_channels` reports only which credential keys are set. Connect/disconnect require role **owner or admin**.
|
|
172
|
+
|
|
173
|
+
| Tool | Description |
|
|
174
|
+
|---|---|
|
|
175
|
+
| `list_channels` | List the tenant's channels + status. Never returns secret values — only `credentialsSet` (which keys are configured) |
|
|
176
|
+
| `connect_channel` | Connect a channel (WhatsApp, Telegram, Discord, Web, …) with its credentials. Validated against the provider API and stored server-side |
|
|
177
|
+
| `disconnect_channel` | Disconnect a channel by id (archives its open conversations) |
|
|
178
|
+
|
|
179
|
+
**Passing secrets safely.** `connect_channel` accepts the secret two ways:
|
|
180
|
+
|
|
181
|
+
- `credentials` — literal values, e.g. `{ "botToken": "123:ABC" }`. Simplest, but the secret passes through the conversation/LLM.
|
|
182
|
+
- `credentialsFromEnv` (**recommended for real secrets**) — a map of credential key → environment variable name, e.g. `{ "botToken": "MY_TG_TOKEN" }`. The MCP server reads the value from its **own** environment (set it in your MCP client config), so the secret never appears in the chat.
|
|
183
|
+
|
|
184
|
+
> Channels that require an interactive flow (WhatsApp/Instagram Embedded Signup QR/OAuth) still need [admin.botuyo.com](https://admin.botuyo.com). Channels that authenticate with a static token (Telegram, Discord, WhatsApp Cloud API with an existing token, Web) can be connected here.
|
|
185
|
+
|
|
166
186
|
### Account
|
|
167
187
|
|
|
168
188
|
| Tool | Description |
|
|
@@ -178,11 +198,13 @@ A **family** is one logical agent with a shared `base` config plus multiple `var
|
|
|
178
198
|
| `developer` | ✅ | ✅ | ✅ |
|
|
179
199
|
| `viewer` | ✅ | ❌ | ❌ |
|
|
180
200
|
|
|
201
|
+
> **Channels:** `connect_channel` / `disconnect_channel` additionally require **owner or admin** (a `developer` can build agents but not wire up channel secrets).
|
|
202
|
+
|
|
181
203
|
## Channel Integrations
|
|
182
204
|
|
|
183
|
-
|
|
205
|
+
Channels that authenticate with a **static secret** — Telegram (bot token), Discord (bot token), WhatsApp Cloud API (existing access token), Web — can be connected directly via the `connect_channel` tool (see [Channels](#channels)). Channels that need an **interactive flow** (WhatsApp/Instagram Embedded Signup with QR scans or OAuth consent) must still be connected from [admin.botuyo.com](https://admin.botuyo.com).
|
|
184
206
|
|
|
185
|
-
Use `get_agent_status` to check which channels are connected
|
|
207
|
+
Use `get_agent_status` to check which channels are connected (it links to the admin panel for any missing channel), or `list_channels` for the tenant-wide channel list and status.
|
|
186
208
|
|
|
187
209
|
## Build from source
|
|
188
210
|
|
package/dist/commands/auth.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Flow:
|
|
8
8
|
* 1. Starts a local HTTP server on a random port
|
|
9
|
-
* 2. Opens
|
|
9
|
+
* 2. Opens ${BOTUYO_ADMIN_URL}/mcp-auth?redirect=http://localhost:PORT (default https://botuyo.com)
|
|
10
10
|
* 3. The admin panel authenticates the user (login/Google),
|
|
11
11
|
* calls POST /api/v1/mcp/oauth/authorize, then redirects to localhost with ?code=...
|
|
12
12
|
* 4. CLI exchanges the code for a JWT directly (POST /api/v1/mcp/oauth/token)
|
package/dist/commands/auth.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Flow:
|
|
8
8
|
* 1. Starts a local HTTP server on a random port
|
|
9
|
-
* 2. Opens
|
|
9
|
+
* 2. Opens ${BOTUYO_ADMIN_URL}/mcp-auth?redirect=http://localhost:PORT (default https://botuyo.com)
|
|
10
10
|
* 3. The admin panel authenticates the user (login/Google),
|
|
11
11
|
* calls POST /api/v1/mcp/oauth/authorize, then redirects to localhost with ?code=...
|
|
12
12
|
* 4. CLI exchanges the code for a JWT directly (POST /api/v1/mcp/oauth/token)
|
package/dist/index.js
CHANGED
|
@@ -22,9 +22,25 @@ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprot
|
|
|
22
22
|
import { BotuyoApiClient, ApiError } from './client.js';
|
|
23
23
|
import { ALL_TOOLS, TOOL_HANDLERS } from './tools/index.js';
|
|
24
24
|
import { resolveToken, readCredentials, clearCredentials, isTokenExpired, resolveApiUrl } from './commands/credentials.js';
|
|
25
|
-
import { watch, existsSync, mkdirSync } from 'fs';
|
|
26
|
-
import { join } from 'path';
|
|
25
|
+
import { watch, existsSync, mkdirSync, readFileSync } from 'fs';
|
|
26
|
+
import { join, dirname } from 'path';
|
|
27
27
|
import { homedir } from 'os';
|
|
28
|
+
import { fileURLToPath } from 'url';
|
|
29
|
+
/**
|
|
30
|
+
* Resolve the real package version from package.json (shipped at the package
|
|
31
|
+
* root = dist/../package.json) so the MCP server advertises the published
|
|
32
|
+
* version to clients instead of a hardcoded literal that silently drifts.
|
|
33
|
+
*/
|
|
34
|
+
function resolvePackageVersion() {
|
|
35
|
+
try {
|
|
36
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
37
|
+
const pkg = JSON.parse(readFileSync(join(here, '..', 'package.json'), 'utf8'));
|
|
38
|
+
return typeof pkg.version === 'string' ? pkg.version : '0.0.0';
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return '0.0.0';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
28
44
|
// ─── Sub-command routing ──────────────────────────────────────────────────────
|
|
29
45
|
const [, , cmd, ...rest] = process.argv;
|
|
30
46
|
async function main() {
|
|
@@ -158,7 +174,7 @@ async function startMcpServer() {
|
|
|
158
174
|
await tryHotReload();
|
|
159
175
|
});
|
|
160
176
|
// ── MCP Server — starts ALWAYS, even without valid auth ────────────────
|
|
161
|
-
const server = new Server({ name: 'botuyo-mcp', version:
|
|
177
|
+
const server = new Server({ name: 'botuyo-mcp', version: resolvePackageVersion() }, { capabilities: { tools: {} } });
|
|
162
178
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: ALL_TOOLS }));
|
|
163
179
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
164
180
|
const { name, arguments: args } = request.params;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAA;AAClG,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAC1H,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from 'vitest';
|
|
2
|
+
import { listChannelsHandler, connectChannelHandler, disconnectChannelHandler } from '../channels.js';
|
|
3
|
+
class MockClient {
|
|
4
|
+
gets = [];
|
|
5
|
+
posts = [];
|
|
6
|
+
deletes = [];
|
|
7
|
+
async get(path) {
|
|
8
|
+
this.gets.push(path);
|
|
9
|
+
return { success: true, data: { channels: [], total: 0 } };
|
|
10
|
+
}
|
|
11
|
+
async post(path, payload) {
|
|
12
|
+
this.posts.push({ path, payload });
|
|
13
|
+
return { success: true, data: { channelId: 'ch1', status: 'connected' } };
|
|
14
|
+
}
|
|
15
|
+
async delete(path) {
|
|
16
|
+
this.deletes.push(path);
|
|
17
|
+
return { success: true, data: { message: 'disconnected' } };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
describe('listChannelsHandler', () => {
|
|
21
|
+
it('GETs the MCP channels namespace', async () => {
|
|
22
|
+
const client = new MockClient();
|
|
23
|
+
await listChannelsHandler(client);
|
|
24
|
+
expect(client.gets[0]).toBe('/api/v1/mcp/channels');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe('connectChannelHandler', () => {
|
|
28
|
+
it('POSTs channelType + config + literal credentials', async () => {
|
|
29
|
+
const client = new MockClient();
|
|
30
|
+
await connectChannelHandler(client, {
|
|
31
|
+
channelType: 'telegram',
|
|
32
|
+
config: { botUsername: 'mybot' },
|
|
33
|
+
credentials: { botToken: 'T-123' }
|
|
34
|
+
});
|
|
35
|
+
expect(client.posts[0].path).toBe('/api/v1/mcp/channels/connect');
|
|
36
|
+
expect(client.posts[0].payload).toEqual({
|
|
37
|
+
channelType: 'telegram',
|
|
38
|
+
config: { botUsername: 'mybot' },
|
|
39
|
+
credentials: { botToken: 'T-123' }
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
it('throws when channelType is missing', async () => {
|
|
43
|
+
const client = new MockClient();
|
|
44
|
+
await expect(connectChannelHandler(client, {})).rejects.toThrow(/channelType/i);
|
|
45
|
+
});
|
|
46
|
+
describe('credentialsFromEnv (keeps secrets out of the chat)', () => {
|
|
47
|
+
afterEach(() => {
|
|
48
|
+
delete process.env.TEST_TG_TOKEN;
|
|
49
|
+
});
|
|
50
|
+
it('resolves the secret from the MCP server environment', async () => {
|
|
51
|
+
process.env.TEST_TG_TOKEN = 'secret-from-env';
|
|
52
|
+
const client = new MockClient();
|
|
53
|
+
await connectChannelHandler(client, {
|
|
54
|
+
channelType: 'telegram',
|
|
55
|
+
credentialsFromEnv: { botToken: 'TEST_TG_TOKEN' }
|
|
56
|
+
});
|
|
57
|
+
expect(client.posts[0].payload.credentials).toEqual({ botToken: 'secret-from-env' });
|
|
58
|
+
});
|
|
59
|
+
it('merges literal + env credentials', async () => {
|
|
60
|
+
process.env.TEST_TG_TOKEN = 'env-token';
|
|
61
|
+
const client = new MockClient();
|
|
62
|
+
await connectChannelHandler(client, {
|
|
63
|
+
channelType: 'whatsapp',
|
|
64
|
+
credentials: { appSecret: 'literal-secret' },
|
|
65
|
+
credentialsFromEnv: { accessToken: 'TEST_TG_TOKEN' }
|
|
66
|
+
});
|
|
67
|
+
expect(client.posts[0].payload.credentials).toEqual({
|
|
68
|
+
appSecret: 'literal-secret',
|
|
69
|
+
accessToken: 'env-token'
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
it('throws a helpful error when the env var is not set', async () => {
|
|
73
|
+
const client = new MockClient();
|
|
74
|
+
await expect(connectChannelHandler(client, {
|
|
75
|
+
channelType: 'telegram',
|
|
76
|
+
credentialsFromEnv: { botToken: 'DEFINITELY_UNSET_ENV_VAR_XYZ' }
|
|
77
|
+
})).rejects.toThrow(/DEFINITELY_UNSET_ENV_VAR_XYZ/);
|
|
78
|
+
expect(client.posts).toHaveLength(0);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe('disconnectChannelHandler', () => {
|
|
83
|
+
it('DELETEs the channel by id', async () => {
|
|
84
|
+
const client = new MockClient();
|
|
85
|
+
await disconnectChannelHandler(client, { channelId: 'ch1' });
|
|
86
|
+
expect(client.deletes[0]).toBe('/api/v1/mcp/channels/ch1');
|
|
87
|
+
});
|
|
88
|
+
it('throws when channelId is missing', async () => {
|
|
89
|
+
const client = new MockClient();
|
|
90
|
+
await expect(disconnectChannelHandler(client, {})).rejects.toThrow(/channelId/i);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
//# sourceMappingURL=channels.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.spec.js","sourceRoot":"","sources":["../../../src/tools/__tests__/channels.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { ingestKnowledgeUrlHandler } from '../ingest_knowledge_url.js';
|
|
3
|
+
class MockPostClient {
|
|
4
|
+
calls = [];
|
|
5
|
+
async post(path, payload) {
|
|
6
|
+
this.calls.push({ path, payload });
|
|
7
|
+
return { success: true, data: { id: 'doc1' } };
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
describe('ingestKnowledgeUrlHandler', () => {
|
|
11
|
+
it('POSTs the url to the MCP knowledge namespace', async () => {
|
|
12
|
+
const client = new MockPostClient();
|
|
13
|
+
await ingestKnowledgeUrlHandler(client, { url: 'https://example.com' });
|
|
14
|
+
expect(client.calls[0].path).toBe('/api/v1/mcp/knowledge/urls');
|
|
15
|
+
expect(client.calls[0].payload).toEqual({ url: 'https://example.com' });
|
|
16
|
+
});
|
|
17
|
+
it('includes optional fields only when provided', async () => {
|
|
18
|
+
const client = new MockPostClient();
|
|
19
|
+
await ingestKnowledgeUrlHandler(client, {
|
|
20
|
+
url: 'https://example.com',
|
|
21
|
+
name: 'Docs',
|
|
22
|
+
description: 'desc',
|
|
23
|
+
tags: ['a', 'b'],
|
|
24
|
+
topic: 'faq'
|
|
25
|
+
});
|
|
26
|
+
expect(client.calls[0].payload).toEqual({
|
|
27
|
+
url: 'https://example.com',
|
|
28
|
+
name: 'Docs',
|
|
29
|
+
description: 'desc',
|
|
30
|
+
tags: ['a', 'b'],
|
|
31
|
+
topic: 'faq'
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
it('throws when url is missing', async () => {
|
|
35
|
+
const client = new MockPostClient();
|
|
36
|
+
await expect(ingestKnowledgeUrlHandler(client, {})).rejects.toThrow();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=ingest_knowledge_url.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest_knowledge_url.spec.js","sourceRoot":"","sources":["../../../src/tools/__tests__/ingest_knowledge_url.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAA;AAEtE,MAAM,cAAc;IACX,KAAK,GAA0C,EAAE,CAAA;IACxD,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,OAAY;QACnC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;QAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,CAAA;IAChD,CAAC;CACF;AAED,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,MAAM,GAAG,IAAI,cAAc,EAAS,CAAA;QAC1C,MAAM,yBAAyB,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,qBAAqB,EAAE,CAAC,CAAA;QACvE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAA;QAC/D,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,qBAAqB,EAAE,CAAC,CAAA;IACzE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,IAAI,cAAc,EAAS,CAAA;QAC1C,MAAM,yBAAyB,CAAC,MAAM,EAAE;YACtC,GAAG,EAAE,qBAAqB;YAC1B,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,MAAM;YACnB,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;YAChB,KAAK,EAAE,KAAK;SACb,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;YACtC,GAAG,EAAE,qBAAqB;YAC1B,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,MAAM;YACnB,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;YAChB,KAAK,EAAE,KAAK;SACb,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,MAAM,GAAG,IAAI,cAAc,EAAS,CAAA;QAC1C,MAAM,MAAM,CAAC,yBAAyB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAA;IACvE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
// Mock the filesystem so the handler doesn't touch a real file.
|
|
3
|
+
vi.mock('fs', () => ({
|
|
4
|
+
existsSync: vi.fn(() => true),
|
|
5
|
+
statSync: vi.fn(() => ({ size: 1024 })),
|
|
6
|
+
readFileSync: vi.fn(() => Buffer.from('fake-image-bytes'))
|
|
7
|
+
}));
|
|
8
|
+
import { uploadAgentMediaHandler } from '../upload_agent_media.js';
|
|
9
|
+
import { existsSync, statSync } from 'fs';
|
|
10
|
+
class MockClient {
|
|
11
|
+
putCalls = [];
|
|
12
|
+
uploadArgs = null;
|
|
13
|
+
async uploadMedia(_buf, fileName, category) {
|
|
14
|
+
this.uploadArgs = { fileName, category };
|
|
15
|
+
return 'https://cdn.botuyo.com/agents/uploaded.png';
|
|
16
|
+
}
|
|
17
|
+
async put(path, payload) {
|
|
18
|
+
this.putCalls.push({ path, payload });
|
|
19
|
+
return { success: true };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
describe('uploadAgentMediaHandler', () => {
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
vi.mocked(existsSync).mockReturnValue(true);
|
|
25
|
+
vi.mocked(statSync).mockReturnValue({ size: 1024 });
|
|
26
|
+
});
|
|
27
|
+
it('uploads an avatar and patches widgetConfig.avatarUrl', async () => {
|
|
28
|
+
const client = new MockClient();
|
|
29
|
+
const result = await uploadAgentMediaHandler(client, {
|
|
30
|
+
agentId: 'a1',
|
|
31
|
+
filePath: '/tmp/pic.png'
|
|
32
|
+
});
|
|
33
|
+
expect(client.uploadArgs).toEqual({ fileName: 'pic.png', category: 'avatar' });
|
|
34
|
+
expect(client.putCalls[0].path).toBe('/api/v1/mcp/agents/a1');
|
|
35
|
+
expect(client.putCalls[0].payload.widgetConfig.avatarUrl).toBe('https://cdn.botuyo.com/agents/uploaded.png');
|
|
36
|
+
expect(result.data.assignedTo).toBe('widgetConfig.avatarUrl');
|
|
37
|
+
});
|
|
38
|
+
it('uploads a logo and patches widgetConfig.logoUrl', async () => {
|
|
39
|
+
const client = new MockClient();
|
|
40
|
+
await uploadAgentMediaHandler(client, {
|
|
41
|
+
agentId: 'a1',
|
|
42
|
+
filePath: '/tmp/logo.webp',
|
|
43
|
+
mediaType: 'logo'
|
|
44
|
+
});
|
|
45
|
+
expect(client.uploadArgs).toEqual({ fileName: 'logo.webp', category: 'logo' });
|
|
46
|
+
expect(client.putCalls[0].payload.widgetConfig.logoUrl).toBe('https://cdn.botuyo.com/agents/uploaded.png');
|
|
47
|
+
});
|
|
48
|
+
it('throws when required args are missing', async () => {
|
|
49
|
+
const client = new MockClient();
|
|
50
|
+
await expect(uploadAgentMediaHandler(client, { agentId: 'a1' })).rejects.toThrow();
|
|
51
|
+
await expect(uploadAgentMediaHandler(client, { filePath: '/tmp/pic.png' })).rejects.toThrow();
|
|
52
|
+
});
|
|
53
|
+
it('throws when the file does not exist', async () => {
|
|
54
|
+
vi.mocked(existsSync).mockReturnValueOnce(false);
|
|
55
|
+
const client = new MockClient();
|
|
56
|
+
await expect(uploadAgentMediaHandler(client, { agentId: 'a1', filePath: '/tmp/missing.png' })).rejects.toThrow(/no encontrado/i);
|
|
57
|
+
});
|
|
58
|
+
it('rejects unsupported extensions', async () => {
|
|
59
|
+
const client = new MockClient();
|
|
60
|
+
await expect(uploadAgentMediaHandler(client, { agentId: 'a1', filePath: '/tmp/pic.gif' })).rejects.toThrow(/Formato no soportado/i);
|
|
61
|
+
});
|
|
62
|
+
it('rejects files over the 2MB limit', async () => {
|
|
63
|
+
vi.mocked(statSync).mockReturnValueOnce({ size: 3 * 1024 * 1024 });
|
|
64
|
+
const client = new MockClient();
|
|
65
|
+
await expect(uploadAgentMediaHandler(client, { agentId: 'a1', filePath: '/tmp/big.png' })).rejects.toThrow(/2MB/i);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
//# sourceMappingURL=upload_agent_media.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload_agent_media.spec.js","sourceRoot":"","sources":["../../../src/tools/__tests__/upload_agent_media.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel tools — connect/list/disconnect the tenant's messaging channels.
|
|
3
|
+
*
|
|
4
|
+
* SECURITY MODEL (read before editing):
|
|
5
|
+
* - Channel secrets (bot tokens, access tokens, app secrets…) are WRITE-ONLY: the server
|
|
6
|
+
* stores them and NEVER returns their values. `list_channels` only reports which credential
|
|
7
|
+
* keys are set (`credentialsSet`), never the values.
|
|
8
|
+
* - To keep secrets OUT of the AI assistant's context, `connect_channel` supports two modes:
|
|
9
|
+
* 1. `credentials` — literal values (simplest; the secret travels through the chat/LLM).
|
|
10
|
+
* 2. `credentialsFromEnv` — a map of `{ credentialKey: ENV_VAR_NAME }`; the MCP server reads
|
|
11
|
+
* the value from its OWN environment (process.env) and the secret never appears in the
|
|
12
|
+
* conversation. PREFER this for production secrets.
|
|
13
|
+
* - Connecting/disconnecting requires role owner or admin (enforced server-side too).
|
|
14
|
+
*
|
|
15
|
+
* All calls go through the /api/v1/mcp/channels namespace (RULE 7).
|
|
16
|
+
*/
|
|
17
|
+
import type { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
18
|
+
import type { BotuyoApiClient } from '../client.js';
|
|
19
|
+
export declare const LIST_CHANNELS_TOOL: Tool;
|
|
20
|
+
export declare const CONNECT_CHANNEL_TOOL: Tool;
|
|
21
|
+
export declare const DISCONNECT_CHANNEL_TOOL: Tool;
|
|
22
|
+
export declare function listChannelsHandler(client: BotuyoApiClient): Promise<unknown>;
|
|
23
|
+
export declare function connectChannelHandler(client: BotuyoApiClient, args: Record<string, unknown>): Promise<unknown>;
|
|
24
|
+
export declare function disconnectChannelHandler(client: BotuyoApiClient, args: Record<string, unknown>): Promise<unknown>;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel tools — connect/list/disconnect the tenant's messaging channels.
|
|
3
|
+
*
|
|
4
|
+
* SECURITY MODEL (read before editing):
|
|
5
|
+
* - Channel secrets (bot tokens, access tokens, app secrets…) are WRITE-ONLY: the server
|
|
6
|
+
* stores them and NEVER returns their values. `list_channels` only reports which credential
|
|
7
|
+
* keys are set (`credentialsSet`), never the values.
|
|
8
|
+
* - To keep secrets OUT of the AI assistant's context, `connect_channel` supports two modes:
|
|
9
|
+
* 1. `credentials` — literal values (simplest; the secret travels through the chat/LLM).
|
|
10
|
+
* 2. `credentialsFromEnv` — a map of `{ credentialKey: ENV_VAR_NAME }`; the MCP server reads
|
|
11
|
+
* the value from its OWN environment (process.env) and the secret never appears in the
|
|
12
|
+
* conversation. PREFER this for production secrets.
|
|
13
|
+
* - Connecting/disconnecting requires role owner or admin (enforced server-side too).
|
|
14
|
+
*
|
|
15
|
+
* All calls go through the /api/v1/mcp/channels namespace (RULE 7).
|
|
16
|
+
*/
|
|
17
|
+
const BASE = '/api/v1/mcp/channels';
|
|
18
|
+
export const LIST_CHANNELS_TOOL = {
|
|
19
|
+
name: 'list_channels',
|
|
20
|
+
description: 'List the tenant\'s messaging channels (WhatsApp, Telegram, Discord, Web, Instagram…) with their ' +
|
|
21
|
+
'connection status. SECRETS ARE NEVER RETURNED — each channel reports only `credentialsSet` (which ' +
|
|
22
|
+
'secret keys are configured), never their values. Available to any authenticated role.',
|
|
23
|
+
inputSchema: { type: 'object', properties: {} }
|
|
24
|
+
};
|
|
25
|
+
export const CONNECT_CHANNEL_TOOL = {
|
|
26
|
+
name: 'connect_channel',
|
|
27
|
+
description: 'Connect a messaging channel to the tenant with its secret credentials (bot token, access token, etc.). ' +
|
|
28
|
+
'Requires role owner or admin. The server validates the credential against the provider API and stores ' +
|
|
29
|
+
'it server-side; the secret is WRITE-ONLY and is never echoed back — DO NOT repeat the secret to the user. ' +
|
|
30
|
+
'\n\nTwo ways to pass the secret:\n' +
|
|
31
|
+
'• `credentials`: literal values, e.g. { "botToken": "123:ABC" }. Simplest, but the secret passes through ' +
|
|
32
|
+
'this conversation.\n' +
|
|
33
|
+
'• `credentialsFromEnv` (RECOMMENDED for real secrets): a map of credential key → environment variable ' +
|
|
34
|
+
'name, e.g. { "botToken": "MY_TG_TOKEN" }. The MCP server reads the value from its own environment so the ' +
|
|
35
|
+
'secret NEVER appears in the chat. Set that env var in your MCP client config.\n\n' +
|
|
36
|
+
'Typical per channel: telegram → credentials.botToken; whatsapp → credentials.accessToken + ' +
|
|
37
|
+
'config.phoneNumberId; discord → credentials.botToken; web → no secret. Fields from both sources are merged.',
|
|
38
|
+
inputSchema: {
|
|
39
|
+
type: 'object',
|
|
40
|
+
properties: {
|
|
41
|
+
channelType: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
enum: ['whatsapp', 'telegram', 'discord', 'web', 'webchat', 'instagram', 'facebook'],
|
|
44
|
+
description: 'Channel to connect.'
|
|
45
|
+
},
|
|
46
|
+
config: {
|
|
47
|
+
type: 'object',
|
|
48
|
+
description: 'Non-secret settings (e.g. { "phoneNumberId": "..." } for WhatsApp).',
|
|
49
|
+
additionalProperties: true
|
|
50
|
+
},
|
|
51
|
+
credentials: {
|
|
52
|
+
type: 'object',
|
|
53
|
+
description: 'Secret values as literals (e.g. { "botToken": "..." }). Prefer credentialsFromEnv for real secrets.',
|
|
54
|
+
additionalProperties: true
|
|
55
|
+
},
|
|
56
|
+
credentialsFromEnv: {
|
|
57
|
+
type: 'object',
|
|
58
|
+
description: 'Map of credential key → env var name read from the MCP server environment (keeps the secret out of the chat). ' +
|
|
59
|
+
'e.g. { "botToken": "MY_TG_TOKEN" }.',
|
|
60
|
+
additionalProperties: { type: 'string' }
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
required: ['channelType']
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
export const DISCONNECT_CHANNEL_TOOL = {
|
|
67
|
+
name: 'disconnect_channel',
|
|
68
|
+
description: 'Disconnect a channel by its id (archives its open conversations). Use list_channels first to get the id. ' +
|
|
69
|
+
'Requires role owner or admin.',
|
|
70
|
+
inputSchema: {
|
|
71
|
+
type: 'object',
|
|
72
|
+
properties: { channelId: { type: 'string', description: 'The channel id (from list_channels).' } },
|
|
73
|
+
required: ['channelId']
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
export async function listChannelsHandler(client) {
|
|
77
|
+
return client.get(BASE);
|
|
78
|
+
}
|
|
79
|
+
export async function connectChannelHandler(client, args) {
|
|
80
|
+
const channelType = args.channelType;
|
|
81
|
+
if (!channelType)
|
|
82
|
+
throw new Error('channelType is required');
|
|
83
|
+
const config = args.config || {};
|
|
84
|
+
const credentials = { ...(args.credentials || {}) };
|
|
85
|
+
// Resolve credentialsFromEnv against the MCP server's own environment so secrets stay out of the chat.
|
|
86
|
+
const fromEnv = args.credentialsFromEnv;
|
|
87
|
+
if (fromEnv) {
|
|
88
|
+
for (const [key, envName] of Object.entries(fromEnv)) {
|
|
89
|
+
const value = process.env[envName];
|
|
90
|
+
if (value === undefined || value === '') {
|
|
91
|
+
throw new Error(`Environment variable "${envName}" (for credential "${key}") is not set in the MCP server environment. ` +
|
|
92
|
+
`Add it to your MCP client config or use the literal "credentials" field.`);
|
|
93
|
+
}
|
|
94
|
+
credentials[key] = value;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return client.post(`${BASE}/connect`, { channelType, config, credentials });
|
|
98
|
+
}
|
|
99
|
+
export async function disconnectChannelHandler(client, args) {
|
|
100
|
+
const channelId = args.channelId;
|
|
101
|
+
if (!channelId)
|
|
102
|
+
throw new Error('channelId is required');
|
|
103
|
+
return client.delete(`${BASE}/${channelId}`);
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=channels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../../src/tools/channels.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/index.js
CHANGED
|
@@ -44,6 +44,7 @@ import { LIST_AGENT_VERSIONS_TOOL, listAgentVersionsHandler } from './list_agent
|
|
|
44
44
|
import { RESTORE_AGENT_VERSION_TOOL, restoreAgentVersionHandler } from './restore_agent_version.js';
|
|
45
45
|
import { LIST_AGENT_FAMILIES_TOOL, listAgentFamiliesHandler, GET_AGENT_FAMILY_TOOL, getAgentFamilyHandler, CREATE_AGENT_FAMILY_TOOL, createAgentFamilyHandler, UPDATE_FAMILY_BASE_TOOL, updateFamilyBaseHandler, ADD_FAMILY_VARIANT_TOOL, addFamilyVariantHandler, UPDATE_FAMILY_VARIANT_TOOL, updateFamilyVariantHandler, REMOVE_FAMILY_VARIANT_TOOL, removeFamilyVariantHandler, PUBLISH_AGENT_FAMILY_TOOL, publishAgentFamilyHandler, DELETE_AGENT_FAMILY_TOOL, deleteAgentFamilyHandler, EXPORT_AGENT_FAMILY_TOOL, exportAgentFamilyHandler, IMPORT_AGENT_FAMILY_TOOL, importAgentFamilyHandler } from './agent_families.js';
|
|
46
46
|
import { AUDIT_AGENT_FAMILY_TOOL, auditAgentFamilyHandler } from './audit_agent_family.js';
|
|
47
|
+
import { LIST_CHANNELS_TOOL, listChannelsHandler, CONNECT_CHANNEL_TOOL, connectChannelHandler, DISCONNECT_CHANNEL_TOOL, disconnectChannelHandler } from './channels.js';
|
|
47
48
|
export const ALL_TOOLS = [
|
|
48
49
|
LIST_AGENTS_TOOL,
|
|
49
50
|
GET_AGENT_TOOL,
|
|
@@ -87,6 +88,9 @@ export const ALL_TOOLS = [
|
|
|
87
88
|
EXPORT_AGENT_FAMILY_TOOL,
|
|
88
89
|
IMPORT_AGENT_FAMILY_TOOL,
|
|
89
90
|
AUDIT_AGENT_FAMILY_TOOL,
|
|
91
|
+
LIST_CHANNELS_TOOL,
|
|
92
|
+
CONNECT_CHANNEL_TOOL,
|
|
93
|
+
DISCONNECT_CHANNEL_TOOL,
|
|
90
94
|
];
|
|
91
95
|
export const TOOL_HANDLERS = {
|
|
92
96
|
list_agents: listAgentsHandler,
|
|
@@ -131,5 +135,8 @@ export const TOOL_HANDLERS = {
|
|
|
131
135
|
export_agent_family: exportAgentFamilyHandler,
|
|
132
136
|
import_agent_family: importAgentFamilyHandler,
|
|
133
137
|
audit_agent_family: auditAgentFamilyHandler,
|
|
138
|
+
list_channels: (client) => listChannelsHandler(client),
|
|
139
|
+
connect_channel: connectChannelHandler,
|
|
140
|
+
disconnect_channel: disconnectChannelHandler,
|
|
134
141
|
};
|
|
135
142
|
//# sourceMappingURL=index.js.map
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|