@botuyo/mcp 0.7.5 → 0.7.6
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 -2
- 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__/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/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 **42 tools**. Read tools (`list_*`, `get_*`, `export_*`, `audit_*`) need `viewer+`; write/publish tools need `developer+` (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
|
|
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,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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"}
|