@hailer/mcp 1.1.12 → 1.1.13
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/CHANGELOG.md +0 -7
- package/{.claude → dist}/CLAUDE.md +2 -2
- package/dist/app.js +18 -5
- package/dist/bot/bot-config.d.ts +10 -1
- package/dist/bot/bot-config.js +64 -3
- package/dist/bot/bot-manager.d.ts +2 -0
- package/dist/bot/bot-manager.js +9 -2
- package/dist/bot/bot.d.ts +33 -0
- package/dist/bot/bot.js +461 -160
- package/dist/bot/services/message-classifier.js +17 -0
- package/dist/bot/services/permission-guard.d.ts +52 -0
- package/dist/bot/services/permission-guard.js +149 -0
- package/dist/bot/services/types.d.ts +5 -0
- package/dist/bot/services/typing-indicator.d.ts +6 -1
- package/dist/bot/services/typing-indicator.js +19 -3
- package/dist/cli.js +0 -0
- package/dist/config.d.ts +6 -1
- package/dist/config.js +43 -0
- package/dist/core.js +3 -6
- package/dist/lib/discussion-lock.d.ts +42 -0
- package/dist/lib/discussion-lock.js +110 -0
- package/dist/mcp/UserContextCache.d.ts +5 -0
- package/dist/mcp/UserContextCache.js +51 -19
- package/dist/mcp/hailer-clients.d.ts +19 -1
- package/dist/mcp/hailer-clients.js +158 -24
- package/dist/mcp/session-store.d.ts +68 -0
- package/dist/mcp/session-store.js +169 -0
- package/dist/mcp/signal-handler.js +2 -0
- package/dist/mcp/tool-registry.d.ts +17 -4
- package/dist/mcp/tool-registry.js +37 -7
- package/dist/mcp/tools/activity.js +99 -7
- package/dist/mcp/tools/app-scaffold.js +304 -336
- package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
- package/dist/mcp/tools/bot-config/constants.js +94 -0
- package/dist/mcp/tools/bot-config/core.d.ts +253 -0
- package/dist/mcp/tools/bot-config/core.js +2456 -0
- package/dist/mcp/tools/bot-config/index.d.ts +10 -0
- package/dist/mcp/tools/bot-config/index.js +59 -0
- package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
- package/dist/mcp/tools/bot-config/tools.js +15 -0
- package/dist/mcp/tools/bot-config/types.d.ts +50 -0
- package/dist/mcp/tools/bot-config/types.js +6 -0
- package/dist/mcp/tools/bug-fixer-tools.d.ts +45 -0
- package/dist/mcp/tools/bug-fixer-tools.js +1096 -0
- package/dist/mcp/tools/company.d.ts +9 -0
- package/dist/mcp/tools/company.js +88 -0
- package/dist/mcp/tools/discussion.js +68 -0
- package/dist/mcp/tools/document.d.ts +11 -0
- package/dist/mcp/tools/document.js +741 -0
- package/dist/mcp/tools/investigate.d.ts +9 -0
- package/dist/mcp/tools/investigate.js +254 -0
- package/dist/mcp/tools/workflow-permissions.d.ts +15 -0
- package/dist/mcp/tools/workflow-permissions.js +204 -0
- package/dist/mcp/tools/workflow.js +57 -18
- package/dist/mcp/utils/index.d.ts +2 -0
- package/dist/mcp/utils/index.js +12 -1
- package/dist/mcp/utils/role-utils.d.ts +74 -0
- package/dist/mcp/utils/role-utils.js +151 -0
- package/dist/mcp/utils/types.d.ts +43 -1
- package/dist/mcp/utils/types.js +14 -0
- package/dist/mcp/webhook-handler.d.ts +4 -0
- package/dist/mcp/webhook-handler.js +8 -0
- package/dist/mcp-server.d.ts +23 -2
- package/dist/mcp-server.js +639 -127
- package/dist/plugins/vipunen/client.d.ts +150 -0
- package/dist/plugins/vipunen/client.js +535 -0
- package/dist/plugins/vipunen/config/schema-config.json +19 -0
- package/dist/plugins/vipunen/config/schema-doc.json +22 -0
- package/dist/plugins/vipunen/index.d.ts +41 -0
- package/dist/plugins/vipunen/index.js +88 -0
- package/dist/plugins/vipunen/tools.d.ts +26 -0
- package/dist/plugins/vipunen/tools.js +501 -0
- package/dist/stdio-server.d.ts +14 -0
- package/dist/stdio-server.js +101 -0
- package/package.json +2 -1
- package/.claude/agents/agent-ada-skill-builder.md +0 -94
- package/.claude/agents/agent-alejandro-function-fields.md +0 -342
- package/.claude/agents/agent-bjorn-config-audit.md +0 -103
- package/.claude/agents/agent-builder-agent-creator.md +0 -130
- package/.claude/agents/agent-code-simplifier.md +0 -53
- package/.claude/agents/agent-dmitri-activity-crud.md +0 -159
- package/.claude/agents/agent-giuseppe-app-builder.md +0 -247
- package/.claude/agents/agent-gunther-mcp-tools.md +0 -39
- package/.claude/agents/agent-helga-workflow-config.md +0 -204
- package/.claude/agents/agent-igor-activity-mover-automation.md +0 -125
- package/.claude/agents/agent-ingrid-doc-templates.md +0 -261
- package/.claude/agents/agent-ivan-monolith.md +0 -154
- package/.claude/agents/agent-kenji-data-reader.md +0 -86
- package/.claude/agents/agent-lars-code-inspector.md +0 -102
- package/.claude/agents/agent-marco-mockup-builder.md +0 -110
- package/.claude/agents/agent-marcus-api-documenter.md +0 -323
- package/.claude/agents/agent-marketplace-publisher.md +0 -280
- package/.claude/agents/agent-marketplace-reviewer.md +0 -309
- package/.claude/agents/agent-permissions-handler.md +0 -208
- package/.claude/agents/agent-simple-writer.md +0 -48
- package/.claude/agents/agent-svetlana-code-review.md +0 -171
- package/.claude/agents/agent-tanya-test-runner.md +0 -333
- package/.claude/agents/agent-ui-designer.md +0 -100
- package/.claude/agents/agent-viktor-sql-insights.md +0 -212
- package/.claude/agents/agent-web-search.md +0 -55
- package/.claude/agents/agent-yevgeni-discussions.md +0 -45
- package/.claude/agents/agent-zara-zapier.md +0 -159
- package/.claude/commands/app-squad.md +0 -135
- package/.claude/commands/audit-squad.md +0 -158
- package/.claude/commands/autoplan.md +0 -563
- package/.claude/commands/cleanup-squad.md +0 -98
- package/.claude/commands/config-squad.md +0 -106
- package/.claude/commands/crud-squad.md +0 -87
- package/.claude/commands/data-squad.md +0 -97
- package/.claude/commands/debug-squad.md +0 -303
- package/.claude/commands/doc-squad.md +0 -65
- package/.claude/commands/handoff.md +0 -137
- package/.claude/commands/health.md +0 -49
- package/.claude/commands/help.md +0 -29
- package/.claude/commands/help:agents.md +0 -151
- package/.claude/commands/help:commands.md +0 -78
- package/.claude/commands/help:faq.md +0 -79
- package/.claude/commands/help:plugins.md +0 -50
- package/.claude/commands/help:skills.md +0 -93
- package/.claude/commands/help:tools.md +0 -75
- package/.claude/commands/hotfix-squad.md +0 -112
- package/.claude/commands/integration-squad.md +0 -82
- package/.claude/commands/janitor-squad.md +0 -167
- package/.claude/commands/learn-auto.md +0 -120
- package/.claude/commands/learn.md +0 -120
- package/.claude/commands/mcp-list.md +0 -27
- package/.claude/commands/onboard-squad.md +0 -140
- package/.claude/commands/plan-workspace.md +0 -732
- package/.claude/commands/prd.md +0 -130
- package/.claude/commands/project-status.md +0 -82
- package/.claude/commands/publish.md +0 -138
- package/.claude/commands/recap.md +0 -69
- package/.claude/commands/restore.md +0 -64
- package/.claude/commands/review-squad.md +0 -152
- package/.claude/commands/save.md +0 -24
- package/.claude/commands/stats.md +0 -19
- package/.claude/commands/swarm.md +0 -210
- package/.claude/commands/tool-builder.md +0 -39
- package/.claude/commands/ws-pull.md +0 -44
- package/.claude/hooks/_shared-memory.cjs +0 -305
- package/.claude/hooks/_utils.cjs +0 -108
- package/.claude/hooks/agent-failure-detector.cjs +0 -383
- package/.claude/hooks/agent-usage-logger.cjs +0 -204
- package/.claude/hooks/app-edit-guard.cjs +0 -494
- package/.claude/hooks/auto-learn.cjs +0 -304
- package/.claude/hooks/bash-guard.cjs +0 -272
- package/.claude/hooks/builder-mode-manager.cjs +0 -354
- package/.claude/hooks/bulk-activity-guard.cjs +0 -271
- package/.claude/hooks/context-watchdog.cjs +0 -230
- package/.claude/hooks/delegation-reminder.cjs +0 -465
- package/.claude/hooks/design-system-lint.cjs +0 -271
- package/.claude/hooks/post-scaffold-hook.cjs +0 -181
- package/.claude/hooks/prompt-guard.cjs +0 -354
- package/.claude/hooks/publish-template-guard.cjs +0 -147
- package/.claude/hooks/session-start.cjs +0 -35
- package/.claude/hooks/shared-memory-writer.cjs +0 -147
- package/.claude/hooks/skill-injector.cjs +0 -140
- package/.claude/hooks/skill-usage-logger.cjs +0 -258
- package/.claude/hooks/src-edit-guard.cjs +0 -240
- package/.claude/hooks/sync-marketplace-agents.cjs +0 -346
- package/.claude/settings.json +0 -257
- package/.claude/skills/SDK-activity-patterns/SKILL.md +0 -428
- package/.claude/skills/SDK-document-templates/SKILL.md +0 -1033
- package/.claude/skills/SDK-function-fields/SKILL.md +0 -542
- package/.claude/skills/SDK-generate-skill/SKILL.md +0 -92
- package/.claude/skills/SDK-init-skill/SKILL.md +0 -127
- package/.claude/skills/SDK-insight-queries/SKILL.md +0 -787
- package/.claude/skills/SDK-ws-config-skill/SKILL.md +0 -1139
- package/.claude/skills/agent-structure/SKILL.md +0 -98
- package/.claude/skills/api-documentation-patterns/SKILL.md +0 -474
- package/.claude/skills/chrome-mcp-reference/SKILL.md +0 -370
- package/.claude/skills/delegation-routing/SKILL.md +0 -202
- package/.claude/skills/frontend-design/SKILL.md +0 -254
- package/.claude/skills/hailer-activity-mover/SKILL.md +0 -213
- package/.claude/skills/hailer-api-client/SKILL.md +0 -518
- package/.claude/skills/hailer-app-builder/SKILL.md +0 -1434
- package/.claude/skills/hailer-apps-pictures/SKILL.md +0 -269
- package/.claude/skills/hailer-design-system/SKILL.md +0 -235
- package/.claude/skills/hailer-monolith-automations/SKILL.md +0 -686
- package/.claude/skills/hailer-permissions-system/SKILL.md +0 -121
- package/.claude/skills/hailer-project-protocol/SKILL.md +0 -488
- package/.claude/skills/hailer-rest-api/SKILL.md +0 -61
- package/.claude/skills/hailer-rest-api/hailer-activities.md +0 -184
- package/.claude/skills/hailer-rest-api/hailer-admin.md +0 -473
- package/.claude/skills/hailer-rest-api/hailer-calendar.md +0 -256
- package/.claude/skills/hailer-rest-api/hailer-feed.md +0 -249
- package/.claude/skills/hailer-rest-api/hailer-insights.md +0 -195
- package/.claude/skills/hailer-rest-api/hailer-messaging.md +0 -276
- package/.claude/skills/hailer-rest-api/hailer-workflows.md +0 -283
- package/.claude/skills/insight-join-patterns/SKILL.md +0 -174
- package/.claude/skills/integration-patterns/SKILL.md +0 -421
- package/.claude/skills/json-only-output/SKILL.md +0 -72
- package/.claude/skills/lsp-setup/SKILL.md +0 -160
- package/.claude/skills/mcp-direct-tools/SKILL.md +0 -153
- package/.claude/skills/optional-parameters/SKILL.md +0 -72
- package/.claude/skills/publish-hailer-app/SKILL.md +0 -244
- package/.claude/skills/testing-patterns/SKILL.md +0 -630
- package/.claude/skills/tool-builder/SKILL.md +0 -250
- package/.claude/skills/tool-parameter-usage/SKILL.md +0 -126
- package/.claude/skills/tool-response-verification/SKILL.md +0 -92
- package/.claude/skills/zapier-hailer-patterns/SKILL.md +0 -581
- package/.mcp.json +0 -13
- package/.opencode/agent/agent-ada-skill-builder.md +0 -35
- package/.opencode/agent/agent-alejandro-function-fields.md +0 -39
- package/.opencode/agent/agent-bjorn-config-audit.md +0 -36
- package/.opencode/agent/agent-builder-agent-creator.md +0 -39
- package/.opencode/agent/agent-code-simplifier.md +0 -31
- package/.opencode/agent/agent-dmitri-activity-crud.md +0 -40
- package/.opencode/agent/agent-giuseppe-app-builder.md +0 -37
- package/.opencode/agent/agent-gunther-mcp-tools.md +0 -39
- package/.opencode/agent/agent-helga-workflow-config.md +0 -203
- package/.opencode/agent/agent-igor-activity-mover-automation.md +0 -46
- package/.opencode/agent/agent-ingrid-doc-templates.md +0 -39
- package/.opencode/agent/agent-ivan-monolith.md +0 -46
- package/.opencode/agent/agent-kenji-data-reader.md +0 -53
- package/.opencode/agent/agent-lars-code-inspector.md +0 -28
- package/.opencode/agent/agent-marco-mockup-builder.md +0 -42
- package/.opencode/agent/agent-marcus-api-documenter.md +0 -53
- package/.opencode/agent/agent-marketplace-publisher.md +0 -44
- package/.opencode/agent/agent-marketplace-reviewer.md +0 -42
- package/.opencode/agent/agent-permissions-handler.md +0 -50
- package/.opencode/agent/agent-simple-writer.md +0 -45
- package/.opencode/agent/agent-svetlana-code-review.md +0 -39
- package/.opencode/agent/agent-tanya-test-runner.md +0 -57
- package/.opencode/agent/agent-ui-designer.md +0 -56
- package/.opencode/agent/agent-viktor-sql-insights.md +0 -34
- package/.opencode/agent/agent-web-search.md +0 -42
- package/.opencode/agent/agent-yevgeni-discussions.md +0 -37
- package/.opencode/agent/agent-zara-zapier.md +0 -53
- package/.opencode/commands/app-squad.md +0 -135
- package/.opencode/commands/audit-squad.md +0 -158
- package/.opencode/commands/autoplan.md +0 -563
- package/.opencode/commands/cleanup-squad.md +0 -98
- package/.opencode/commands/config-squad.md +0 -106
- package/.opencode/commands/crud-squad.md +0 -87
- package/.opencode/commands/data-squad.md +0 -97
- package/.opencode/commands/debug-squad.md +0 -303
- package/.opencode/commands/doc-squad.md +0 -65
- package/.opencode/commands/handoff.md +0 -137
- package/.opencode/commands/health.md +0 -49
- package/.opencode/commands/help-agents.md +0 -151
- package/.opencode/commands/help-commands.md +0 -32
- package/.opencode/commands/help-faq.md +0 -29
- package/.opencode/commands/help-plugins.md +0 -28
- package/.opencode/commands/help-skills.md +0 -7
- package/.opencode/commands/help-tools.md +0 -40
- package/.opencode/commands/help.md +0 -28
- package/.opencode/commands/hotfix-squad.md +0 -112
- package/.opencode/commands/integration-squad.md +0 -82
- package/.opencode/commands/janitor-squad.md +0 -167
- package/.opencode/commands/learn-auto.md +0 -120
- package/.opencode/commands/learn.md +0 -120
- package/.opencode/commands/mcp-list.md +0 -27
- package/.opencode/commands/onboard-squad.md +0 -140
- package/.opencode/commands/plan-workspace.md +0 -732
- package/.opencode/commands/prd.md +0 -131
- package/.opencode/commands/project-status.md +0 -82
- package/.opencode/commands/publish.md +0 -138
- package/.opencode/commands/recap.md +0 -69
- package/.opencode/commands/restore.md +0 -64
- package/.opencode/commands/review-squad.md +0 -152
- package/.opencode/commands/save.md +0 -24
- package/.opencode/commands/stats.md +0 -19
- package/.opencode/commands/swarm.md +0 -210
- package/.opencode/commands/tool-builder.md +0 -39
- package/.opencode/commands/ws-pull.md +0 -44
- package/.opencode/opencode.json +0 -28
- package/SESSION-HANDOFF.md +0 -68
- package/inbox/2026-03-04-bot-config-patterns.md +0 -24
- package/scripts/postinstall.cjs +0 -64
- package/scripts/test-hal-tools.ts +0 -154
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Vipunen Tools — Weaviate RAG Knowledge Base
|
|
4
|
+
*
|
|
5
|
+
* Tools for querying and managing vectorized documentation in Weaviate.
|
|
6
|
+
* All tools use contextType: 'none' — they don't need Hailer authentication.
|
|
7
|
+
*
|
|
8
|
+
* Auth model:
|
|
9
|
+
* - Server authenticates to Weaviate with a single WEAVIATE_API_KEY
|
|
10
|
+
* - Clients authenticate to MCP with their own API keys (VIPUNEN_API_KEYS)
|
|
11
|
+
* - Each client key belongs to a group: admin, dev, or readonly
|
|
12
|
+
* - Groups control what operations and collections are accessible
|
|
13
|
+
*
|
|
14
|
+
* Permission tiers:
|
|
15
|
+
* - readonly: 5 tools (query, find-similar, list-sources, count, filter)
|
|
16
|
+
* - dev: 8 tools (readonly + insert-one, update-chunks, delete-source) — no VipunenConfig writes
|
|
17
|
+
* - admin: 13 tools (dev + get-schema, export, batch-insert, create-collection, delete-collection)
|
|
18
|
+
*/
|
|
19
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
20
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.createVipunenTools = createVipunenTools;
|
|
24
|
+
const zod_1 = require("zod");
|
|
25
|
+
const tool_registry_1 = require("../../mcp/tool-registry");
|
|
26
|
+
const schema_doc_json_1 = __importDefault(require("./config/schema-doc.json"));
|
|
27
|
+
const schema_config_json_1 = __importDefault(require("./config/schema-config.json"));
|
|
28
|
+
const response_builder_1 = require("../../mcp/utils/response-builder");
|
|
29
|
+
const client_1 = require("./client");
|
|
30
|
+
const logger_1 = require("../../lib/logger");
|
|
31
|
+
const logger = (0, logger_1.createLogger)({ component: 'vipunen-tools' });
|
|
32
|
+
/** Check if a group can perform write operations on a collection */
|
|
33
|
+
function canWrite(group, collection) {
|
|
34
|
+
if (group === 'admin')
|
|
35
|
+
return true;
|
|
36
|
+
if (group === 'readonly')
|
|
37
|
+
return false;
|
|
38
|
+
// Dev: everything except VipunenConfig writes
|
|
39
|
+
if (group === 'dev')
|
|
40
|
+
return collection !== 'VipunenConfig';
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
/** Check if a group can perform admin operations */
|
|
44
|
+
function canAdmin(group) {
|
|
45
|
+
return group === 'admin';
|
|
46
|
+
}
|
|
47
|
+
/** Permission error message */
|
|
48
|
+
function permissionError(group, operation, collection) {
|
|
49
|
+
if (group === 'readonly') {
|
|
50
|
+
return `Group "readonly" cannot perform write operation "${operation}". Read-only access only.`;
|
|
51
|
+
}
|
|
52
|
+
if (group === 'dev' && collection === 'VipunenConfig') {
|
|
53
|
+
return `Group "dev" has read-only access to VipunenConfig. Use an admin key for writes.`;
|
|
54
|
+
}
|
|
55
|
+
return `Group "${group}" cannot perform "${operation}" on collection "${collection}".`;
|
|
56
|
+
}
|
|
57
|
+
/** Admin-only permission error */
|
|
58
|
+
function adminPermissionError(group, operation) {
|
|
59
|
+
return `Group "${group}" cannot perform admin operation "${operation}". Admin access required.`;
|
|
60
|
+
}
|
|
61
|
+
// ============================================================================
|
|
62
|
+
// Schema loading for create-collection
|
|
63
|
+
// ============================================================================
|
|
64
|
+
function loadSchemaTemplate(schemaType) {
|
|
65
|
+
return schemaType === 'doc' ? schema_doc_json_1.default : schema_config_json_1.default;
|
|
66
|
+
}
|
|
67
|
+
// ============================================================================
|
|
68
|
+
// Shared where filter schema (reused by query and filter tools)
|
|
69
|
+
// ============================================================================
|
|
70
|
+
const whereFilterSchema = zod_1.z.lazy(() => zod_1.z.object({
|
|
71
|
+
path: zod_1.z.array(zod_1.z.string()).optional(),
|
|
72
|
+
operator: zod_1.z.string(),
|
|
73
|
+
valueText: zod_1.z.string().optional(),
|
|
74
|
+
valueInt: zod_1.z.number().optional(),
|
|
75
|
+
valueBoolean: zod_1.z.boolean().optional(),
|
|
76
|
+
valueDate: zod_1.z.string().optional(),
|
|
77
|
+
operands: zod_1.z.array(whereFilterSchema).optional(),
|
|
78
|
+
}));
|
|
79
|
+
// ============================================================================
|
|
80
|
+
// Error handling
|
|
81
|
+
// ============================================================================
|
|
82
|
+
function handleToolError(toolName, error) {
|
|
83
|
+
const message = (0, response_builder_1.getErrorMessage)(error);
|
|
84
|
+
if (error instanceof client_1.WeaviateAuthError) {
|
|
85
|
+
logger.warn(`${toolName} auth rejected`, { error: message });
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
logger.error(`${toolName} failed`, { error: message });
|
|
89
|
+
}
|
|
90
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: message }));
|
|
91
|
+
}
|
|
92
|
+
// ============================================================================
|
|
93
|
+
// Tool factory
|
|
94
|
+
// ============================================================================
|
|
95
|
+
function createVipunenTools(client) {
|
|
96
|
+
const tools = [];
|
|
97
|
+
// --------------------------------------------------------------------------
|
|
98
|
+
// vipunen-query — Hybrid search (BM25 + vector)
|
|
99
|
+
// --------------------------------------------------------------------------
|
|
100
|
+
tools.push({
|
|
101
|
+
name: 'vipunen-query',
|
|
102
|
+
group: tool_registry_1.ToolGroup.READ,
|
|
103
|
+
description: 'Search the Weaviate knowledge base using hybrid search (BM25 + vector). Returns matching documents ranked by relevance.',
|
|
104
|
+
contextType: 'none',
|
|
105
|
+
schema: zod_1.z.object({
|
|
106
|
+
collection: zod_1.z.string().describe('Weaviate collection name (e.g., "InternalDev")'),
|
|
107
|
+
query: zod_1.z.string().describe('Natural language search query — vector search understands intent, not just keywords'),
|
|
108
|
+
targetProperties: zod_1.z.array(zod_1.z.string()).describe('Properties to search and return (e.g., ["title", "content", "tags"])'),
|
|
109
|
+
limit: zod_1.z.number().min(1).max(25).default(5).describe('Max results to return (1-25, default 5)'),
|
|
110
|
+
where: whereFilterSchema.optional().describe('Weaviate where filter for metadata filtering (e.g., {path: ["scope"], operator: "Equal", valueText: "hailer-mcp"})'),
|
|
111
|
+
}),
|
|
112
|
+
async execute(args, _context) {
|
|
113
|
+
try {
|
|
114
|
+
logger.debug('vipunen-query', { collection: args.collection, query: args.query.substring(0, 50), limit: args.limit, hasWhere: !!args.where });
|
|
115
|
+
const result = await client.hybridSearch(args.collection, args.query, args.targetProperties, args.limit, args.where);
|
|
116
|
+
return (0, response_builder_1.textResponse)(JSON.stringify({ count: result.objects.length, objects: result.objects }));
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
return handleToolError('vipunen-query', error);
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
// --------------------------------------------------------------------------
|
|
124
|
+
// vipunen-find-similar — Pure vector search for dedup detection
|
|
125
|
+
// --------------------------------------------------------------------------
|
|
126
|
+
tools.push({
|
|
127
|
+
name: 'vipunen-find-similar',
|
|
128
|
+
group: tool_registry_1.ToolGroup.READ,
|
|
129
|
+
description: 'Find semantically similar documents using pure vector search (nearText). Use for dedup detection — returns objects with similarity scores.',
|
|
130
|
+
contextType: 'none',
|
|
131
|
+
schema: zod_1.z.object({
|
|
132
|
+
collection: zod_1.z.string().describe('Weaviate collection name'),
|
|
133
|
+
query: zod_1.z.string().describe('Text to find similar documents for'),
|
|
134
|
+
limit: zod_1.z.number().min(1).max(25).default(5).describe('Max results (1-25, default 5)'),
|
|
135
|
+
}),
|
|
136
|
+
async execute(args, _context) {
|
|
137
|
+
try {
|
|
138
|
+
logger.debug('vipunen-find-similar', { collection: args.collection, query: args.query.substring(0, 50), limit: args.limit });
|
|
139
|
+
const result = await client.nearTextSearch(args.collection, args.query, args.limit);
|
|
140
|
+
return (0, response_builder_1.textResponse)(JSON.stringify({ count: result.objects.length, objects: result.objects }));
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
return handleToolError('vipunen-find-similar', error);
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
// --------------------------------------------------------------------------
|
|
148
|
+
// vipunen-list-sources — Aggregate chunks by source_file
|
|
149
|
+
// --------------------------------------------------------------------------
|
|
150
|
+
tools.push({
|
|
151
|
+
name: 'vipunen-list-sources',
|
|
152
|
+
group: tool_registry_1.ToolGroup.READ,
|
|
153
|
+
description: 'List all source files in a Weaviate collection with their chunk counts. Useful for understanding what documentation is indexed.',
|
|
154
|
+
contextType: 'none',
|
|
155
|
+
schema: zod_1.z.object({
|
|
156
|
+
collection: zod_1.z.string().describe('Weaviate collection name'),
|
|
157
|
+
}),
|
|
158
|
+
async execute(args, _context) {
|
|
159
|
+
try {
|
|
160
|
+
logger.debug('vipunen-list-sources', { collection: args.collection });
|
|
161
|
+
const groups = await client.aggregateGroupBy(args.collection, 'source_file');
|
|
162
|
+
return (0, response_builder_1.textResponse)(JSON.stringify({
|
|
163
|
+
totalSources: groups.length,
|
|
164
|
+
sources: groups.map(g => ({ source_file: g.value, chunk_count: g.count })),
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
return handleToolError('vipunen-list-sources', error);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
// --------------------------------------------------------------------------
|
|
173
|
+
// vipunen-count — Count objects in a collection
|
|
174
|
+
// --------------------------------------------------------------------------
|
|
175
|
+
tools.push({
|
|
176
|
+
name: 'vipunen-count',
|
|
177
|
+
group: tool_registry_1.ToolGroup.READ,
|
|
178
|
+
description: 'Count the total number of objects in a Weaviate collection.',
|
|
179
|
+
contextType: 'none',
|
|
180
|
+
schema: zod_1.z.object({
|
|
181
|
+
collection: zod_1.z.string().describe('Weaviate collection name'),
|
|
182
|
+
}),
|
|
183
|
+
async execute(args, _context) {
|
|
184
|
+
try {
|
|
185
|
+
logger.debug('vipunen-count', { collection: args.collection });
|
|
186
|
+
const count = await client.countCollection(args.collection);
|
|
187
|
+
return (0, response_builder_1.textResponse)(JSON.stringify({ collection: args.collection, count }));
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
return handleToolError('vipunen-count', error);
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
// --------------------------------------------------------------------------
|
|
195
|
+
// vipunen-filter — Where filter query (no vector search)
|
|
196
|
+
// --------------------------------------------------------------------------
|
|
197
|
+
tools.push({
|
|
198
|
+
name: 'vipunen-filter',
|
|
199
|
+
group: tool_registry_1.ToolGroup.READ,
|
|
200
|
+
description: 'Query a Weaviate collection using only where filters (no vector/BM25 search). Works on all collections including non-vectorized ones like VipunenConfig.',
|
|
201
|
+
contextType: 'none',
|
|
202
|
+
schema: zod_1.z.object({
|
|
203
|
+
collection: zod_1.z.string().describe('Weaviate collection name'),
|
|
204
|
+
where: whereFilterSchema.describe('Weaviate where filter (e.g., {path: ["scope"], operator: "Equal", valueText: "hailer-mcp"})'),
|
|
205
|
+
properties: zod_1.z.array(zod_1.z.string()).optional().describe('Properties to return (defaults to all)'),
|
|
206
|
+
limit: zod_1.z.number().min(1).max(100).default(25).describe('Max results to return (1-100, default 25)'),
|
|
207
|
+
}),
|
|
208
|
+
async execute(args, _context) {
|
|
209
|
+
try {
|
|
210
|
+
logger.debug('vipunen-filter', { collection: args.collection, limit: args.limit });
|
|
211
|
+
const result = await client.filterQuery(args.collection, args.where, args.properties, args.limit);
|
|
212
|
+
return (0, response_builder_1.textResponse)(JSON.stringify({ count: result.objects.length, objects: result.objects }));
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
return handleToolError('vipunen-filter', error);
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
// --------------------------------------------------------------------------
|
|
220
|
+
// vipunen-insert-one — Insert a single object
|
|
221
|
+
// --------------------------------------------------------------------------
|
|
222
|
+
tools.push({
|
|
223
|
+
name: 'vipunen-insert-one',
|
|
224
|
+
group: tool_registry_1.ToolGroup.WRITE,
|
|
225
|
+
description: 'Insert a single document into a Weaviate collection. Returns the created object UUID.',
|
|
226
|
+
contextType: 'none',
|
|
227
|
+
schema: zod_1.z.object({
|
|
228
|
+
collection: zod_1.z.string().describe('Weaviate collection name'),
|
|
229
|
+
properties: zod_1.z.record(zod_1.z.any()).describe('Object properties to insert (e.g., { title, content, tags, scope, topic, doc_type })'),
|
|
230
|
+
}),
|
|
231
|
+
async execute(args, context) {
|
|
232
|
+
try {
|
|
233
|
+
const ctx = context;
|
|
234
|
+
if (!ctx?.group) {
|
|
235
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: 'Missing Vipunen group context' }));
|
|
236
|
+
}
|
|
237
|
+
if (!canWrite(ctx.group, args.collection)) {
|
|
238
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: permissionError(ctx.group, 'insert', args.collection) }));
|
|
239
|
+
}
|
|
240
|
+
logger.debug('vipunen-insert-one', { collection: args.collection, title: args.properties?.title, group: ctx.group });
|
|
241
|
+
const result = await client.insertObject(args.collection, args.properties);
|
|
242
|
+
return (0, response_builder_1.textResponse)(JSON.stringify({ uuid: result.uuid }));
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
return handleToolError('vipunen-insert-one', error);
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
// --------------------------------------------------------------------------
|
|
250
|
+
// vipunen-update-chunks — Replace scope+topic+chunk_index chunks
|
|
251
|
+
// --------------------------------------------------------------------------
|
|
252
|
+
tools.push({
|
|
253
|
+
name: 'vipunen-update-chunks',
|
|
254
|
+
group: tool_registry_1.ToolGroup.WRITE,
|
|
255
|
+
description: 'Update documentation chunks by replacing existing objects matching scope + topic + chunk_index. Deletes old chunks then inserts replacements.',
|
|
256
|
+
contextType: 'none',
|
|
257
|
+
schema: zod_1.z.object({
|
|
258
|
+
collection: zod_1.z.string().describe('Weaviate collection name'),
|
|
259
|
+
scope: zod_1.z.string().describe('Scope to match (e.g., "hailer-mcp")'),
|
|
260
|
+
topic: zod_1.z.string().describe('Topic to match (e.g., "overview")'),
|
|
261
|
+
chunks: zod_1.z.array(zod_1.z.object({
|
|
262
|
+
chunk_index: zod_1.z.number().describe('Chunk index to replace'),
|
|
263
|
+
properties: zod_1.z.record(zod_1.z.any()).describe('New properties for this chunk'),
|
|
264
|
+
})).describe('Chunks to update — each identified by chunk_index'),
|
|
265
|
+
}),
|
|
266
|
+
async execute(args, context) {
|
|
267
|
+
try {
|
|
268
|
+
const ctx = context;
|
|
269
|
+
if (!ctx?.group) {
|
|
270
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: 'Missing Vipunen group context' }));
|
|
271
|
+
}
|
|
272
|
+
if (!canWrite(ctx.group, args.collection)) {
|
|
273
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: permissionError(ctx.group, 'update', args.collection) }));
|
|
274
|
+
}
|
|
275
|
+
logger.debug('vipunen-update-chunks', {
|
|
276
|
+
collection: args.collection,
|
|
277
|
+
scope: args.scope,
|
|
278
|
+
topic: args.topic,
|
|
279
|
+
chunkCount: args.chunks.length,
|
|
280
|
+
group: ctx.group,
|
|
281
|
+
});
|
|
282
|
+
// Insert first, then delete — minimizes data loss window on failure
|
|
283
|
+
const results = await Promise.allSettled(args.chunks.map(async (chunk) => {
|
|
284
|
+
const newProps = {
|
|
285
|
+
...chunk.properties,
|
|
286
|
+
scope: args.scope,
|
|
287
|
+
topic: args.topic,
|
|
288
|
+
chunk_index: chunk.chunk_index,
|
|
289
|
+
};
|
|
290
|
+
// Insert the new chunk first
|
|
291
|
+
const inserted = await client.insertObject(args.collection, newProps);
|
|
292
|
+
// Only delete old chunks after successful insert
|
|
293
|
+
try {
|
|
294
|
+
await client.deleteByMultipleProperties(args.collection, [
|
|
295
|
+
{ property: 'scope', value: args.scope },
|
|
296
|
+
{ property: 'topic', value: args.topic },
|
|
297
|
+
{ property: 'chunk_index', value: chunk.chunk_index },
|
|
298
|
+
]);
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
// Old chunk may not exist — that's fine
|
|
302
|
+
}
|
|
303
|
+
return { chunk_index: chunk.chunk_index, uuid: inserted.uuid };
|
|
304
|
+
}));
|
|
305
|
+
const succeeded = results.filter(r => r.status === 'fulfilled').length;
|
|
306
|
+
const failures = results
|
|
307
|
+
.map((r, i) => r.status === 'rejected'
|
|
308
|
+
? { chunk_index: args.chunks[i].chunk_index, error: r.reason?.message || String(r.reason) }
|
|
309
|
+
: null)
|
|
310
|
+
.filter(Boolean);
|
|
311
|
+
return (0, response_builder_1.textResponse)(JSON.stringify({ updated: succeeded, failed: failures.length, ...(failures.length > 0 ? { failures } : {}) }));
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
return handleToolError('vipunen-update-chunks', error);
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
// --------------------------------------------------------------------------
|
|
319
|
+
// vipunen-delete-source — Delete all chunks for a source file
|
|
320
|
+
// --------------------------------------------------------------------------
|
|
321
|
+
tools.push({
|
|
322
|
+
name: 'vipunen-delete-source',
|
|
323
|
+
group: tool_registry_1.ToolGroup.WRITE,
|
|
324
|
+
description: 'Delete ALL objects from a collection where source_file matches. Destructive — requires write access to the collection.',
|
|
325
|
+
contextType: 'none',
|
|
326
|
+
schema: zod_1.z.object({
|
|
327
|
+
collection: zod_1.z.string().describe('Weaviate collection name'),
|
|
328
|
+
source_file: zod_1.z.string().describe('source_file value to match for deletion'),
|
|
329
|
+
}),
|
|
330
|
+
async execute(args, context) {
|
|
331
|
+
try {
|
|
332
|
+
const ctx = context;
|
|
333
|
+
if (!ctx?.group) {
|
|
334
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: 'Missing Vipunen group context' }));
|
|
335
|
+
}
|
|
336
|
+
if (!canWrite(ctx.group, args.collection)) {
|
|
337
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: permissionError(ctx.group, 'delete', args.collection) }));
|
|
338
|
+
}
|
|
339
|
+
logger.info('vipunen-delete-source', { collection: args.collection, source_file: args.source_file, group: ctx.group });
|
|
340
|
+
const result = await client.deleteByProperty(args.collection, 'source_file', args.source_file);
|
|
341
|
+
return (0, response_builder_1.textResponse)(JSON.stringify({ deleted: result.successful, matched: result.matches }));
|
|
342
|
+
}
|
|
343
|
+
catch (error) {
|
|
344
|
+
return handleToolError('vipunen-delete-source', error);
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
});
|
|
348
|
+
// --------------------------------------------------------------------------
|
|
349
|
+
// vipunen-get-schema — Get collection schema (admin only)
|
|
350
|
+
// --------------------------------------------------------------------------
|
|
351
|
+
tools.push({
|
|
352
|
+
name: 'vipunen-get-schema',
|
|
353
|
+
group: tool_registry_1.ToolGroup.READ,
|
|
354
|
+
description: 'Get the full schema definition of a Weaviate collection. Admin access required.',
|
|
355
|
+
contextType: 'none',
|
|
356
|
+
schema: zod_1.z.object({
|
|
357
|
+
collection: zod_1.z.string().describe('Weaviate collection name'),
|
|
358
|
+
}),
|
|
359
|
+
async execute(args, context) {
|
|
360
|
+
try {
|
|
361
|
+
const ctx = context;
|
|
362
|
+
if (!ctx?.group) {
|
|
363
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: 'Missing Vipunen group context' }));
|
|
364
|
+
}
|
|
365
|
+
if (!canAdmin(ctx.group)) {
|
|
366
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: adminPermissionError(ctx.group, 'get-schema') }));
|
|
367
|
+
}
|
|
368
|
+
logger.debug('vipunen-get-schema', { collection: args.collection, group: ctx.group });
|
|
369
|
+
const schema = await client.getCollectionSchema(args.collection);
|
|
370
|
+
return (0, response_builder_1.textResponse)(JSON.stringify(schema));
|
|
371
|
+
}
|
|
372
|
+
catch (error) {
|
|
373
|
+
return handleToolError('vipunen-get-schema', error);
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
});
|
|
377
|
+
// --------------------------------------------------------------------------
|
|
378
|
+
// vipunen-export — Export all objects from a collection (admin only)
|
|
379
|
+
// --------------------------------------------------------------------------
|
|
380
|
+
tools.push({
|
|
381
|
+
name: 'vipunen-export',
|
|
382
|
+
group: tool_registry_1.ToolGroup.READ,
|
|
383
|
+
description: 'Export all objects from a Weaviate collection using cursor-based pagination. Admin access required.',
|
|
384
|
+
contextType: 'none',
|
|
385
|
+
schema: zod_1.z.object({
|
|
386
|
+
collection: zod_1.z.string().describe('Weaviate collection name'),
|
|
387
|
+
properties: zod_1.z.array(zod_1.z.string()).optional().describe('Properties to return (defaults to all)'),
|
|
388
|
+
pageSize: zod_1.z.number().min(1).max(500).default(100).describe('Objects per page (1-500, default 100)'),
|
|
389
|
+
}),
|
|
390
|
+
async execute(args, context) {
|
|
391
|
+
try {
|
|
392
|
+
const ctx = context;
|
|
393
|
+
if (!ctx?.group) {
|
|
394
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: 'Missing Vipunen group context' }));
|
|
395
|
+
}
|
|
396
|
+
if (!canAdmin(ctx.group)) {
|
|
397
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: adminPermissionError(ctx.group, 'export') }));
|
|
398
|
+
}
|
|
399
|
+
logger.debug('vipunen-export', { collection: args.collection, pageSize: args.pageSize, group: ctx.group });
|
|
400
|
+
const result = await client.exportCollection(args.collection, args.properties, args.pageSize);
|
|
401
|
+
return (0, response_builder_1.textResponse)(JSON.stringify({ collection: args.collection, count: result.totalCount, objects: result.objects }));
|
|
402
|
+
}
|
|
403
|
+
catch (error) {
|
|
404
|
+
return handleToolError('vipunen-export', error);
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
});
|
|
408
|
+
// --------------------------------------------------------------------------
|
|
409
|
+
// vipunen-batch-insert — Batch insert objects (admin only)
|
|
410
|
+
// --------------------------------------------------------------------------
|
|
411
|
+
tools.push({
|
|
412
|
+
name: 'vipunen-batch-insert',
|
|
413
|
+
group: tool_registry_1.ToolGroup.WRITE,
|
|
414
|
+
description: 'Insert multiple objects into a Weaviate collection in batches. Admin access required.',
|
|
415
|
+
contextType: 'none',
|
|
416
|
+
schema: zod_1.z.object({
|
|
417
|
+
collection: zod_1.z.string().describe('Weaviate collection name'),
|
|
418
|
+
objects: zod_1.z.array(zod_1.z.record(zod_1.z.any())).describe('Array of objects to insert (each is a properties object)'),
|
|
419
|
+
batchSize: zod_1.z.number().min(1).max(100).default(20).describe('Objects per batch (1-100, default 20)'),
|
|
420
|
+
}),
|
|
421
|
+
async execute(args, context) {
|
|
422
|
+
try {
|
|
423
|
+
const ctx = context;
|
|
424
|
+
if (!ctx?.group) {
|
|
425
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: 'Missing Vipunen group context' }));
|
|
426
|
+
}
|
|
427
|
+
if (!canAdmin(ctx.group)) {
|
|
428
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: adminPermissionError(ctx.group, 'batch-insert') }));
|
|
429
|
+
}
|
|
430
|
+
logger.debug('vipunen-batch-insert', { collection: args.collection, count: args.objects.length, batchSize: args.batchSize, group: ctx.group });
|
|
431
|
+
const result = await client.batchInsert(args.collection, args.objects, args.batchSize);
|
|
432
|
+
return (0, response_builder_1.textResponse)(JSON.stringify(result));
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
return handleToolError('vipunen-batch-insert', error);
|
|
436
|
+
}
|
|
437
|
+
},
|
|
438
|
+
});
|
|
439
|
+
// --------------------------------------------------------------------------
|
|
440
|
+
// vipunen-create-collection — Create a collection (admin only)
|
|
441
|
+
// --------------------------------------------------------------------------
|
|
442
|
+
tools.push({
|
|
443
|
+
name: 'vipunen-create-collection',
|
|
444
|
+
group: tool_registry_1.ToolGroup.WRITE,
|
|
445
|
+
description: 'Create a new Weaviate collection with a predefined schema template. Idempotent — returns existing collection info if already present. Admin access required.',
|
|
446
|
+
contextType: 'none',
|
|
447
|
+
schema: zod_1.z.object({
|
|
448
|
+
collection: zod_1.z.string().describe('Collection name (must start with uppercase, e.g., "MyDocs")'),
|
|
449
|
+
schema: zod_1.z.enum(['doc', 'config']).default('doc').describe('Schema template: "doc" (text2vec-transformers vectorizer) or "config" (no vectorizer)'),
|
|
450
|
+
}),
|
|
451
|
+
async execute(args, context) {
|
|
452
|
+
try {
|
|
453
|
+
const ctx = context;
|
|
454
|
+
if (!ctx?.group) {
|
|
455
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: 'Missing Vipunen group context' }));
|
|
456
|
+
}
|
|
457
|
+
if (!canAdmin(ctx.group)) {
|
|
458
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: adminPermissionError(ctx.group, 'create-collection') }));
|
|
459
|
+
}
|
|
460
|
+
logger.info('vipunen-create-collection', { collection: args.collection, schema: args.schema, group: ctx.group });
|
|
461
|
+
const schemaTemplate = loadSchemaTemplate(args.schema);
|
|
462
|
+
const result = await client.createCollection(args.collection, schemaTemplate);
|
|
463
|
+
return (0, response_builder_1.textResponse)(JSON.stringify({ collection: args.collection, created: result.created, objectCount: result.objectCount }));
|
|
464
|
+
}
|
|
465
|
+
catch (error) {
|
|
466
|
+
return handleToolError('vipunen-create-collection', error);
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
});
|
|
470
|
+
// --------------------------------------------------------------------------
|
|
471
|
+
// vipunen-delete-collection — Delete a collection (admin only)
|
|
472
|
+
// --------------------------------------------------------------------------
|
|
473
|
+
tools.push({
|
|
474
|
+
name: 'vipunen-delete-collection',
|
|
475
|
+
group: tool_registry_1.ToolGroup.WRITE,
|
|
476
|
+
description: 'Delete an entire Weaviate collection and all its objects. DESTRUCTIVE. Admin access required.',
|
|
477
|
+
contextType: 'none',
|
|
478
|
+
schema: zod_1.z.object({
|
|
479
|
+
collection: zod_1.z.string().describe('Weaviate collection name to delete'),
|
|
480
|
+
}),
|
|
481
|
+
async execute(args, context) {
|
|
482
|
+
try {
|
|
483
|
+
const ctx = context;
|
|
484
|
+
if (!ctx?.group) {
|
|
485
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: 'Missing Vipunen group context' }));
|
|
486
|
+
}
|
|
487
|
+
if (!canAdmin(ctx.group)) {
|
|
488
|
+
return (0, response_builder_1.errorResponse)(JSON.stringify({ error: adminPermissionError(ctx.group, 'delete-collection') }));
|
|
489
|
+
}
|
|
490
|
+
logger.info('vipunen-delete-collection', { collection: args.collection, group: ctx.group });
|
|
491
|
+
const result = await client.deleteCollection(args.collection);
|
|
492
|
+
return (0, response_builder_1.textResponse)(JSON.stringify({ collection: args.collection, deleted: result.deleted }));
|
|
493
|
+
}
|
|
494
|
+
catch (error) {
|
|
495
|
+
return handleToolError('vipunen-delete-collection', error);
|
|
496
|
+
}
|
|
497
|
+
},
|
|
498
|
+
});
|
|
499
|
+
return tools;
|
|
500
|
+
}
|
|
501
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stdio MCP Server for Claude Desktop
|
|
3
|
+
*
|
|
4
|
+
* Uses @modelcontextprotocol/sdk with StdioServerTransport for
|
|
5
|
+
* JSON-RPC communication via stdin/stdout.
|
|
6
|
+
*
|
|
7
|
+
* This is the entry point when running as Claude Desktop MCP connector.
|
|
8
|
+
*/
|
|
9
|
+
import { ToolRegistry } from './mcp/tool-registry';
|
|
10
|
+
/**
|
|
11
|
+
* Start the stdio MCP server with all registered tools
|
|
12
|
+
*/
|
|
13
|
+
export declare function startStdioServer(toolRegistry: ToolRegistry): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=stdio-server.d.ts.map
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Stdio MCP Server for Claude Desktop
|
|
4
|
+
*
|
|
5
|
+
* Uses @modelcontextprotocol/sdk with StdioServerTransport for
|
|
6
|
+
* JSON-RPC communication via stdin/stdout.
|
|
7
|
+
*
|
|
8
|
+
* This is the entry point when running as Claude Desktop MCP connector.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.startStdioServer = startStdioServer;
|
|
12
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
13
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
14
|
+
const logger_1 = require("./lib/logger");
|
|
15
|
+
const tool_registry_1 = require("./mcp/tool-registry");
|
|
16
|
+
const UserContextCache_1 = require("./mcp/UserContextCache");
|
|
17
|
+
const config_1 = require("./config");
|
|
18
|
+
const logger = (0, logger_1.createLogger)({ component: 'stdio-server' });
|
|
19
|
+
/**
|
|
20
|
+
* Start the stdio MCP server with all registered tools
|
|
21
|
+
*/
|
|
22
|
+
async function startStdioServer(toolRegistry) {
|
|
23
|
+
logger.info('Starting stdio MCP server for Claude Desktop');
|
|
24
|
+
// Get API key from environment (set in Claude Desktop config)
|
|
25
|
+
const apiKey = process.env.MCP_CLIENT_API_KEY;
|
|
26
|
+
if (!apiKey) {
|
|
27
|
+
logger.error('MCP_CLIENT_API_KEY environment variable is required for stdio mode');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
// Create MCP server
|
|
31
|
+
const server = new mcp_js_1.McpServer({
|
|
32
|
+
name: 'hailer-mcp-server',
|
|
33
|
+
version: '1.0.0',
|
|
34
|
+
});
|
|
35
|
+
// Get tool definitions (filtered by allowed groups, excluding NUCLEAR unless enabled)
|
|
36
|
+
const allowedGroups = config_1.environment.ENABLE_NUCLEAR_TOOLS
|
|
37
|
+
? [tool_registry_1.ToolGroup.READ, tool_registry_1.ToolGroup.WRITE, tool_registry_1.ToolGroup.PLAYGROUND, tool_registry_1.ToolGroup.NUCLEAR]
|
|
38
|
+
: [tool_registry_1.ToolGroup.READ, tool_registry_1.ToolGroup.WRITE, tool_registry_1.ToolGroup.PLAYGROUND];
|
|
39
|
+
const toolDefinitions = toolRegistry.getToolDefinitions({ allowedGroups });
|
|
40
|
+
logger.info('Registering tools for stdio server', {
|
|
41
|
+
toolCount: toolDefinitions.length,
|
|
42
|
+
allowedGroups,
|
|
43
|
+
});
|
|
44
|
+
// Register each tool with the MCP server
|
|
45
|
+
for (const toolDef of toolDefinitions) {
|
|
46
|
+
server.tool(toolDef.name, toolDef.description, toolDef.inputSchema.properties ? toolDef.inputSchema : { type: 'object', properties: {} }, async (args) => {
|
|
47
|
+
const startTime = Date.now();
|
|
48
|
+
logger.debug('Tool call received', { toolName: toolDef.name, args });
|
|
49
|
+
try {
|
|
50
|
+
// Get user context (cached)
|
|
51
|
+
const userContext = await UserContextCache_1.UserContextCache.getContext(apiKey);
|
|
52
|
+
// Execute the tool
|
|
53
|
+
const result = await toolRegistry.executeTool(toolDef.name, args, userContext);
|
|
54
|
+
const duration = Date.now() - startTime;
|
|
55
|
+
logger.info('Tool call completed', { toolName: toolDef.name, duration });
|
|
56
|
+
// Handle different result formats
|
|
57
|
+
if (result && typeof result === 'object' && 'content' in result) {
|
|
58
|
+
// Result is already in MCP format { content: [...] }
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
// Wrap result in MCP format
|
|
62
|
+
return {
|
|
63
|
+
content: [{
|
|
64
|
+
type: 'text',
|
|
65
|
+
text: typeof result === 'string' ? result : JSON.stringify(result, null, 2)
|
|
66
|
+
}]
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
const duration = Date.now() - startTime;
|
|
71
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
72
|
+
logger.error('Tool call failed', error, { toolName: toolDef.name, duration });
|
|
73
|
+
return {
|
|
74
|
+
content: [{
|
|
75
|
+
type: 'text',
|
|
76
|
+
text: `Error: ${errorMessage}`
|
|
77
|
+
}],
|
|
78
|
+
isError: true
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
// Create stdio transport
|
|
84
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
85
|
+
// Handle graceful shutdown
|
|
86
|
+
process.on('SIGINT', async () => {
|
|
87
|
+
logger.info('Received SIGINT, shutting down stdio server');
|
|
88
|
+
await server.close();
|
|
89
|
+
process.exit(0);
|
|
90
|
+
});
|
|
91
|
+
process.on('SIGTERM', async () => {
|
|
92
|
+
logger.info('Received SIGTERM, shutting down stdio server');
|
|
93
|
+
await server.close();
|
|
94
|
+
process.exit(0);
|
|
95
|
+
});
|
|
96
|
+
// Connect and start serving
|
|
97
|
+
logger.info('Connecting stdio transport');
|
|
98
|
+
await server.connect(transport);
|
|
99
|
+
logger.info('Stdio MCP server is running');
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=stdio-server.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hailer/mcp",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.13",
|
|
4
4
|
"config": {
|
|
5
5
|
"docker": {
|
|
6
6
|
"registry": "registry.gitlab.com/hailer-repos/hailer-mcp"
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"form-data": "^4.0.4",
|
|
45
45
|
"openai": "^5.5.1",
|
|
46
46
|
"sharp": "^0.34.5",
|
|
47
|
+
"tar": "^7.5.13",
|
|
47
48
|
"typescript-language-server": "^5.1.3",
|
|
48
49
|
"zod": "^3.24.1"
|
|
49
50
|
},
|