musubi-sdd 5.1.0 → 5.6.1
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.ja.md +106 -48
- package/README.md +110 -32
- package/bin/musubi-analyze.js +74 -67
- package/bin/musubi-browser.js +27 -26
- package/bin/musubi-change.js +48 -47
- package/bin/musubi-checkpoint.js +10 -7
- package/bin/musubi-convert.js +25 -25
- package/bin/musubi-costs.js +27 -10
- package/bin/musubi-gui.js +52 -46
- package/bin/musubi-init.js +1952 -10
- package/bin/musubi-orchestrate.js +327 -239
- package/bin/musubi-remember.js +69 -56
- package/bin/musubi-resolve.js +53 -45
- package/bin/musubi-trace.js +51 -22
- package/bin/musubi-validate.js +39 -30
- package/bin/musubi-workflow.js +33 -34
- package/bin/musubi.js +39 -2
- package/package.json +1 -1
- package/src/agents/agent-loop.js +94 -95
- package/src/agents/agentic/code-generator.js +119 -109
- package/src/agents/agentic/code-reviewer.js +105 -108
- package/src/agents/agentic/index.js +4 -4
- package/src/agents/browser/action-executor.js +13 -13
- package/src/agents/browser/ai-comparator.js +11 -10
- package/src/agents/browser/context-manager.js +6 -6
- package/src/agents/browser/index.js +5 -5
- package/src/agents/browser/nl-parser.js +31 -46
- package/src/agents/browser/screenshot.js +2 -2
- package/src/agents/browser/test-generator.js +6 -4
- package/src/agents/function-tool.js +71 -65
- package/src/agents/index.js +7 -7
- package/src/agents/schema-generator.js +98 -94
- package/src/analyzers/ast-extractor.js +158 -146
- package/src/analyzers/codegraph-auto-update.js +858 -0
- package/src/analyzers/complexity-analyzer.js +536 -0
- package/src/analyzers/context-optimizer.js +241 -126
- package/src/analyzers/impact-analyzer.js +1 -1
- package/src/analyzers/large-project-analyzer.js +766 -0
- package/src/analyzers/repository-map.js +77 -81
- package/src/analyzers/security-analyzer.js +19 -11
- package/src/analyzers/stuck-detector.js +19 -17
- package/src/converters/index.js +78 -57
- package/src/converters/ir/types.js +12 -12
- package/src/converters/parsers/musubi-parser.js +134 -126
- package/src/converters/parsers/openapi-parser.js +70 -53
- package/src/converters/parsers/speckit-parser.js +239 -175
- package/src/converters/writers/musubi-writer.js +123 -118
- package/src/converters/writers/speckit-writer.js +124 -113
- package/src/generators/rust-migration-generator.js +512 -0
- package/src/gui/public/index.html +1365 -1211
- package/src/gui/server.js +41 -40
- package/src/gui/services/file-watcher.js +23 -8
- package/src/gui/services/project-scanner.js +26 -20
- package/src/gui/services/replanning-service.js +27 -23
- package/src/gui/services/traceability-service.js +8 -8
- package/src/gui/services/workflow-service.js +14 -7
- package/src/index.js +151 -0
- package/src/integrations/cicd.js +90 -104
- package/src/integrations/codegraph-mcp.js +643 -0
- package/src/integrations/documentation.js +142 -103
- package/src/integrations/examples.js +95 -80
- package/src/integrations/github-client.js +17 -17
- package/src/integrations/index.js +5 -5
- package/src/integrations/mcp/index.js +21 -21
- package/src/integrations/mcp/mcp-context-provider.js +76 -78
- package/src/integrations/mcp/mcp-discovery.js +74 -72
- package/src/integrations/mcp/mcp-tool-registry.js +99 -94
- package/src/integrations/mcp-connector.js +70 -66
- package/src/integrations/platforms.js +50 -49
- package/src/integrations/tool-discovery.js +37 -31
- package/src/llm-providers/anthropic-provider.js +11 -11
- package/src/llm-providers/base-provider.js +16 -18
- package/src/llm-providers/copilot-provider.js +22 -19
- package/src/llm-providers/index.js +26 -25
- package/src/llm-providers/ollama-provider.js +11 -11
- package/src/llm-providers/openai-provider.js +12 -12
- package/src/managers/agent-memory.js +36 -24
- package/src/managers/checkpoint-manager.js +4 -8
- package/src/managers/delta-spec.js +19 -19
- package/src/managers/index.js +13 -4
- package/src/managers/memory-condenser.js +35 -45
- package/src/managers/repo-skill-manager.js +57 -31
- package/src/managers/skill-loader.js +25 -22
- package/src/managers/skill-tools.js +36 -72
- package/src/managers/workflow.js +30 -22
- package/src/monitoring/cost-tracker.js +48 -46
- package/src/monitoring/incident-manager.js +116 -106
- package/src/monitoring/index.js +144 -134
- package/src/monitoring/observability.js +75 -62
- package/src/monitoring/quality-dashboard.js +45 -41
- package/src/monitoring/release-manager.js +63 -53
- package/src/orchestration/agent-skill-binding.js +39 -47
- package/src/orchestration/error-handler.js +65 -107
- package/src/orchestration/guardrails/base-guardrail.js +26 -24
- package/src/orchestration/guardrails/guardrail-rules.js +50 -64
- package/src/orchestration/guardrails/index.js +5 -5
- package/src/orchestration/guardrails/input-guardrail.js +58 -45
- package/src/orchestration/guardrails/output-guardrail.js +104 -81
- package/src/orchestration/guardrails/safety-check.js +79 -79
- package/src/orchestration/index.js +38 -55
- package/src/orchestration/mcp-tool-adapters.js +96 -99
- package/src/orchestration/orchestration-engine.js +21 -21
- package/src/orchestration/pattern-registry.js +60 -45
- package/src/orchestration/patterns/auto.js +34 -47
- package/src/orchestration/patterns/group-chat.js +59 -65
- package/src/orchestration/patterns/handoff.js +67 -65
- package/src/orchestration/patterns/human-in-loop.js +51 -72
- package/src/orchestration/patterns/nested.js +25 -40
- package/src/orchestration/patterns/sequential.js +35 -34
- package/src/orchestration/patterns/swarm.js +63 -56
- package/src/orchestration/patterns/triage.js +150 -109
- package/src/orchestration/reasoning/index.js +9 -9
- package/src/orchestration/reasoning/planning-engine.js +143 -140
- package/src/orchestration/reasoning/reasoning-engine.js +206 -144
- package/src/orchestration/reasoning/self-correction.js +121 -128
- package/src/orchestration/replanning/adaptive-goal-modifier.js +107 -112
- package/src/orchestration/replanning/alternative-generator.js +37 -42
- package/src/orchestration/replanning/config.js +63 -59
- package/src/orchestration/replanning/goal-progress-tracker.js +98 -100
- package/src/orchestration/replanning/index.js +24 -20
- package/src/orchestration/replanning/plan-evaluator.js +49 -50
- package/src/orchestration/replanning/plan-monitor.js +32 -28
- package/src/orchestration/replanning/proactive-path-optimizer.js +175 -178
- package/src/orchestration/replanning/replan-history.js +33 -26
- package/src/orchestration/replanning/replanning-engine.js +106 -108
- package/src/orchestration/skill-executor.js +107 -109
- package/src/orchestration/skill-registry.js +85 -89
- package/src/orchestration/workflow-examples.js +228 -231
- package/src/orchestration/workflow-executor.js +65 -68
- package/src/orchestration/workflow-orchestrator.js +72 -73
- package/src/phase4-integration.js +47 -40
- package/src/phase5-integration.js +89 -30
- package/src/reporters/coverage-report.js +82 -30
- package/src/reporters/hierarchical-reporter.js +498 -0
- package/src/reporters/traceability-matrix-report.js +29 -20
- package/src/resolvers/issue-resolver.js +43 -31
- package/src/steering/advanced-validation.js +133 -124
- package/src/steering/auto-updater.js +60 -73
- package/src/steering/index.js +6 -6
- package/src/steering/quality-metrics.js +41 -35
- package/src/steering/steering-auto-update.js +83 -86
- package/src/steering/steering-validator.js +98 -106
- package/src/steering/template-constraints.js +53 -54
- package/src/templates/agents/claude-code/CLAUDE.md +32 -32
- package/src/templates/agents/claude-code/skills/agent-assistant/SKILL.md +13 -5
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/mlops-guide.md +23 -23
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/model-card-template.md +60 -41
- package/src/templates/agents/claude-code/skills/api-designer/api-patterns.md +27 -19
- package/src/templates/agents/claude-code/skills/api-designer/openapi-template.md +11 -7
- package/src/templates/agents/claude-code/skills/bug-hunter/SKILL.md +4 -3
- package/src/templates/agents/claude-code/skills/bug-hunter/root-cause-analysis.md +37 -15
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/dependency-graph-patterns.md +36 -42
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/impact-analysis-template.md +69 -60
- package/src/templates/agents/claude-code/skills/cloud-architect/aws-patterns.md +31 -38
- package/src/templates/agents/claude-code/skills/cloud-architect/azure-patterns.md +28 -23
- package/src/templates/agents/claude-code/skills/code-reviewer/SKILL.md +61 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/best-practices.md +27 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/review-checklist.md +29 -10
- package/src/templates/agents/claude-code/skills/code-reviewer/review-standards.md +29 -24
- package/src/templates/agents/claude-code/skills/constitution-enforcer/SKILL.md +8 -6
- package/src/templates/agents/claude-code/skills/constitution-enforcer/constitutional-articles.md +62 -26
- package/src/templates/agents/claude-code/skills/constitution-enforcer/phase-minus-one-gates.md +35 -16
- package/src/templates/agents/claude-code/skills/database-administrator/backup-recovery.md +27 -17
- package/src/templates/agents/claude-code/skills/database-administrator/tuning-guide.md +25 -20
- package/src/templates/agents/claude-code/skills/database-schema-designer/schema-patterns.md +39 -22
- package/src/templates/agents/claude-code/skills/devops-engineer/ci-cd-templates.md +25 -22
- package/src/templates/agents/claude-code/skills/issue-resolver/SKILL.md +24 -21
- package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +148 -63
- package/src/templates/agents/claude-code/skills/orchestrator/patterns.md +35 -16
- package/src/templates/agents/claude-code/skills/orchestrator/selection-matrix.md +69 -64
- package/src/templates/agents/claude-code/skills/performance-engineer/optimization-playbook.md +47 -47
- package/src/templates/agents/claude-code/skills/performance-optimizer/SKILL.md +69 -0
- package/src/templates/agents/claude-code/skills/performance-optimizer/benchmark-template.md +63 -45
- package/src/templates/agents/claude-code/skills/performance-optimizer/optimization-patterns.md +33 -35
- package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +7 -6
- package/src/templates/agents/claude-code/skills/project-manager/agile-ceremonies.md +47 -28
- package/src/templates/agents/claude-code/skills/project-manager/project-templates.md +94 -78
- package/src/templates/agents/claude-code/skills/quality-assurance/SKILL.md +20 -17
- package/src/templates/agents/claude-code/skills/quality-assurance/qa-plan-template.md +63 -49
- package/src/templates/agents/claude-code/skills/release-coordinator/SKILL.md +5 -5
- package/src/templates/agents/claude-code/skills/release-coordinator/feature-flag-guide.md +30 -26
- package/src/templates/agents/claude-code/skills/release-coordinator/release-plan-template.md +67 -35
- package/src/templates/agents/claude-code/skills/requirements-analyst/ears-format.md +54 -42
- package/src/templates/agents/claude-code/skills/requirements-analyst/validation-rules.md +36 -33
- package/src/templates/agents/claude-code/skills/security-auditor/SKILL.md +77 -19
- package/src/templates/agents/claude-code/skills/security-auditor/audit-checklists.md +24 -24
- package/src/templates/agents/claude-code/skills/security-auditor/owasp-top-10.md +61 -20
- package/src/templates/agents/claude-code/skills/security-auditor/vulnerability-patterns.md +43 -11
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/incident-response-template.md +55 -25
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/observability-patterns.md +78 -68
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/slo-sli-guide.md +73 -53
- package/src/templates/agents/claude-code/skills/software-developer/solid-principles.md +83 -37
- package/src/templates/agents/claude-code/skills/software-developer/test-first-workflow.md +38 -31
- package/src/templates/agents/claude-code/skills/steering/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/steering/auto-update-rules.md +31 -0
- package/src/templates/agents/claude-code/skills/system-architect/adr-template.md +25 -7
- package/src/templates/agents/claude-code/skills/system-architect/c4-model-guide.md +74 -61
- package/src/templates/agents/claude-code/skills/technical-writer/doc-templates/documentation-templates.md +70 -52
- package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +2 -0
- package/src/templates/agents/claude-code/skills/test-engineer/ears-test-mapping.md +75 -71
- package/src/templates/agents/claude-code/skills/test-engineer/test-types.md +85 -63
- package/src/templates/agents/claude-code/skills/traceability-auditor/coverage-matrix-template.md +39 -36
- package/src/templates/agents/claude-code/skills/traceability-auditor/gap-detection-rules.md +22 -17
- package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/ui-ux-designer/accessibility-guidelines.md +49 -75
- package/src/templates/agents/claude-code/skills/ui-ux-designer/design-system-components.md +71 -59
- package/src/templates/agents/codex/AGENTS.md +74 -42
- package/src/templates/agents/cursor/AGENTS.md +74 -42
- package/src/templates/agents/gemini-cli/GEMINI.md +74 -42
- package/src/templates/agents/github-copilot/AGENTS.md +83 -51
- package/src/templates/agents/qwen-code/QWEN.md +74 -42
- package/src/templates/agents/windsurf/AGENTS.md +74 -42
- package/src/templates/architectures/README.md +41 -0
- package/src/templates/architectures/clean-architecture/README.md +113 -0
- package/src/templates/architectures/event-driven/README.md +162 -0
- package/src/templates/architectures/hexagonal/README.md +130 -0
- package/src/templates/index.js +6 -1
- package/src/templates/locale-manager.js +16 -16
- package/src/templates/shared/delta-spec-template.md +20 -13
- package/src/templates/shared/github-actions/musubi-issue-resolver.yml +5 -5
- package/src/templates/shared/github-actions/musubi-security-check.yml +3 -3
- package/src/templates/shared/github-actions/musubi-validate.yml +4 -4
- package/src/templates/shared/steering/structure.md +95 -0
- package/src/templates/skills/browser-agent.md +21 -16
- package/src/templates/skills/web-gui.md +8 -0
- package/src/templates/template-constraints.js +50 -53
- package/src/validators/advanced-validation.js +30 -36
- package/src/validators/constitutional-validator.js +77 -73
- package/src/validators/critic-system.js +49 -59
- package/src/validators/delta-format.js +59 -55
- package/src/validators/traceability-validator.js +7 -11
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MUSUBI MCP Tool Registry
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Manages MCP tools from discovered servers and provides
|
|
5
5
|
* automatic registration with the Agent Loop and Skill System.
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
7
|
* @module integrations/mcp/mcp-tool-registry
|
|
8
8
|
*/
|
|
9
9
|
|
|
@@ -40,24 +40,24 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
40
40
|
*/
|
|
41
41
|
constructor(options = {}) {
|
|
42
42
|
super();
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
this.connector = options.connector || null;
|
|
45
45
|
this.skillRegistry = options.skillRegistry || null;
|
|
46
46
|
this.autoRegister = options.autoRegister ?? true;
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
/** @type {Map<string, MCPToolDefinition>} */
|
|
49
49
|
this.tools = new Map();
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
/** @type {Map<string, string[]>} */
|
|
52
52
|
this.serverTools = new Map();
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
/** @type {Map<string, number>} */
|
|
55
55
|
this.invocationCounts = new Map();
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
/** @type {Map<string, number[]>} */
|
|
58
58
|
this.latencyHistory = new Map();
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
/**
|
|
62
62
|
* Set the MCP connector
|
|
63
63
|
* @param {Object} connector
|
|
@@ -65,7 +65,7 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
65
65
|
setConnector(connector) {
|
|
66
66
|
this.connector = connector;
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
/**
|
|
70
70
|
* Set the skill registry for auto-registration
|
|
71
71
|
* @param {Object} skillRegistry
|
|
@@ -73,7 +73,7 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
73
73
|
setSkillRegistry(skillRegistry) {
|
|
74
74
|
this.skillRegistry = skillRegistry;
|
|
75
75
|
}
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
/**
|
|
78
78
|
* Discover and register tools from an MCP server
|
|
79
79
|
* @param {string} serverName - Server name
|
|
@@ -84,17 +84,17 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
84
84
|
if (!this.connector) {
|
|
85
85
|
throw new Error('MCP connector not set');
|
|
86
86
|
}
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
try {
|
|
89
89
|
// Connect to server
|
|
90
90
|
await this.connector.connect(serverName, serverConfig);
|
|
91
|
-
|
|
91
|
+
|
|
92
92
|
// List tools
|
|
93
93
|
const toolsResponse = await this.connector.listTools(serverName);
|
|
94
94
|
const tools = toolsResponse.tools || [];
|
|
95
|
-
|
|
95
|
+
|
|
96
96
|
const registered = [];
|
|
97
|
-
|
|
97
|
+
|
|
98
98
|
for (const tool of tools) {
|
|
99
99
|
const toolDef = {
|
|
100
100
|
name: `${serverName}/${tool.name}`,
|
|
@@ -102,30 +102,32 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
102
102
|
description: tool.description || '',
|
|
103
103
|
inputSchema: tool.inputSchema || { type: 'object', properties: {} },
|
|
104
104
|
serverName,
|
|
105
|
-
annotations: tool.annotations || {}
|
|
105
|
+
annotations: tool.annotations || {},
|
|
106
106
|
};
|
|
107
|
-
|
|
107
|
+
|
|
108
108
|
this.registerTool(toolDef);
|
|
109
109
|
registered.push(toolDef);
|
|
110
110
|
}
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
// Track tools per server
|
|
113
|
-
this.serverTools.set(
|
|
114
|
-
|
|
113
|
+
this.serverTools.set(
|
|
114
|
+
serverName,
|
|
115
|
+
registered.map(t => t.name)
|
|
116
|
+
);
|
|
117
|
+
|
|
115
118
|
this.emit('tools:discovered', {
|
|
116
119
|
serverName,
|
|
117
120
|
count: registered.length,
|
|
118
|
-
tools: registered.map(t => t.name)
|
|
121
|
+
tools: registered.map(t => t.name),
|
|
119
122
|
});
|
|
120
|
-
|
|
123
|
+
|
|
121
124
|
return registered;
|
|
122
|
-
|
|
123
125
|
} catch (error) {
|
|
124
126
|
this.emit('tools:discovery:error', { serverName, error });
|
|
125
127
|
throw error;
|
|
126
128
|
}
|
|
127
129
|
}
|
|
128
|
-
|
|
130
|
+
|
|
129
131
|
/**
|
|
130
132
|
* Register a tool
|
|
131
133
|
* @param {MCPToolDefinition} toolDef
|
|
@@ -134,22 +136,22 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
134
136
|
this.tools.set(toolDef.name, toolDef);
|
|
135
137
|
this.invocationCounts.set(toolDef.name, 0);
|
|
136
138
|
this.latencyHistory.set(toolDef.name, []);
|
|
137
|
-
|
|
139
|
+
|
|
138
140
|
// Auto-register with skill registry
|
|
139
141
|
if (this.autoRegister && this.skillRegistry) {
|
|
140
142
|
this.registerAsSkill(toolDef);
|
|
141
143
|
}
|
|
142
|
-
|
|
144
|
+
|
|
143
145
|
this.emit('tool:registered', { name: toolDef.name });
|
|
144
146
|
}
|
|
145
|
-
|
|
147
|
+
|
|
146
148
|
/**
|
|
147
149
|
* Register tool as a MUSUBI skill
|
|
148
150
|
* @param {MCPToolDefinition} toolDef
|
|
149
151
|
*/
|
|
150
152
|
registerAsSkill(toolDef) {
|
|
151
153
|
if (!this.skillRegistry) return;
|
|
152
|
-
|
|
154
|
+
|
|
153
155
|
const skill = {
|
|
154
156
|
id: `mcp-${toolDef.name.replace('/', '-')}`,
|
|
155
157
|
name: toolDef.name,
|
|
@@ -159,13 +161,13 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
159
161
|
serverName: toolDef.serverName,
|
|
160
162
|
originalName: toolDef.originalName,
|
|
161
163
|
inputSchema: toolDef.inputSchema,
|
|
162
|
-
source: 'mcp'
|
|
164
|
+
source: 'mcp',
|
|
163
165
|
},
|
|
164
|
-
handler: async
|
|
166
|
+
handler: async input => {
|
|
165
167
|
return this.invokeTool(toolDef.name, input);
|
|
166
|
-
}
|
|
168
|
+
},
|
|
167
169
|
};
|
|
168
|
-
|
|
170
|
+
|
|
169
171
|
try {
|
|
170
172
|
this.skillRegistry.registerSkill(skill);
|
|
171
173
|
this.emit('skill:registered', { skillId: skill.id, toolName: toolDef.name });
|
|
@@ -173,7 +175,7 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
173
175
|
this.emit('skill:registration:error', { toolName: toolDef.name, error });
|
|
174
176
|
}
|
|
175
177
|
}
|
|
176
|
-
|
|
178
|
+
|
|
177
179
|
/**
|
|
178
180
|
* Invoke a tool
|
|
179
181
|
* @param {string} toolName - Full tool name (serverName/toolName)
|
|
@@ -185,60 +187,55 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
185
187
|
if (!tool) {
|
|
186
188
|
throw new Error(`Tool not found: ${toolName}`);
|
|
187
189
|
}
|
|
188
|
-
|
|
190
|
+
|
|
189
191
|
if (!this.connector) {
|
|
190
192
|
throw new Error('MCP connector not set');
|
|
191
193
|
}
|
|
192
|
-
|
|
194
|
+
|
|
193
195
|
const startTime = Date.now();
|
|
194
|
-
|
|
196
|
+
|
|
195
197
|
try {
|
|
196
198
|
// Validate input
|
|
197
199
|
const validation = this.validateInput(tool, input);
|
|
198
200
|
if (!validation.valid) {
|
|
199
201
|
throw new Error(`Invalid input: ${validation.errors.join(', ')}`);
|
|
200
202
|
}
|
|
201
|
-
|
|
203
|
+
|
|
202
204
|
// Call tool via connector
|
|
203
|
-
const result = await this.connector.callTool(
|
|
204
|
-
|
|
205
|
-
tool.originalName,
|
|
206
|
-
input
|
|
207
|
-
);
|
|
208
|
-
|
|
205
|
+
const result = await this.connector.callTool(tool.serverName, tool.originalName, input);
|
|
206
|
+
|
|
209
207
|
const duration = Date.now() - startTime;
|
|
210
208
|
this.recordInvocation(toolName, duration, true);
|
|
211
|
-
|
|
209
|
+
|
|
212
210
|
this.emit('tool:invoked', {
|
|
213
211
|
name: toolName,
|
|
214
212
|
duration,
|
|
215
|
-
success: true
|
|
213
|
+
success: true,
|
|
216
214
|
});
|
|
217
|
-
|
|
215
|
+
|
|
218
216
|
return {
|
|
219
217
|
success: true,
|
|
220
218
|
result: result.content || result,
|
|
221
|
-
duration
|
|
219
|
+
duration,
|
|
222
220
|
};
|
|
223
|
-
|
|
224
221
|
} catch (error) {
|
|
225
222
|
const duration = Date.now() - startTime;
|
|
226
223
|
this.recordInvocation(toolName, duration, false);
|
|
227
|
-
|
|
224
|
+
|
|
228
225
|
this.emit('tool:error', {
|
|
229
226
|
name: toolName,
|
|
230
227
|
error: error.message,
|
|
231
|
-
duration
|
|
228
|
+
duration,
|
|
232
229
|
});
|
|
233
|
-
|
|
230
|
+
|
|
234
231
|
return {
|
|
235
232
|
success: false,
|
|
236
233
|
error,
|
|
237
|
-
duration
|
|
234
|
+
duration,
|
|
238
235
|
};
|
|
239
236
|
}
|
|
240
237
|
}
|
|
241
|
-
|
|
238
|
+
|
|
242
239
|
/**
|
|
243
240
|
* Validate tool input against schema
|
|
244
241
|
* @param {MCPToolDefinition} tool
|
|
@@ -248,11 +245,11 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
248
245
|
validateInput(tool, input) {
|
|
249
246
|
const errors = [];
|
|
250
247
|
const schema = tool.inputSchema;
|
|
251
|
-
|
|
248
|
+
|
|
252
249
|
if (!schema || !schema.properties) {
|
|
253
250
|
return { valid: true, errors: [] };
|
|
254
251
|
}
|
|
255
|
-
|
|
252
|
+
|
|
256
253
|
// Check required fields
|
|
257
254
|
if (schema.required) {
|
|
258
255
|
for (const field of schema.required) {
|
|
@@ -261,25 +258,25 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
261
258
|
}
|
|
262
259
|
}
|
|
263
260
|
}
|
|
264
|
-
|
|
261
|
+
|
|
265
262
|
// Type checking
|
|
266
263
|
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
267
264
|
if (key in input) {
|
|
268
265
|
const value = input[key];
|
|
269
266
|
const expectedType = prop.type;
|
|
270
|
-
|
|
267
|
+
|
|
271
268
|
if (expectedType && !this.checkType(value, expectedType)) {
|
|
272
269
|
errors.push(`Invalid type for ${key}: expected ${expectedType}`);
|
|
273
270
|
}
|
|
274
271
|
}
|
|
275
272
|
}
|
|
276
|
-
|
|
273
|
+
|
|
277
274
|
return {
|
|
278
275
|
valid: errors.length === 0,
|
|
279
|
-
errors
|
|
276
|
+
errors,
|
|
280
277
|
};
|
|
281
278
|
}
|
|
282
|
-
|
|
279
|
+
|
|
283
280
|
/**
|
|
284
281
|
* Check if value matches expected type
|
|
285
282
|
* @param {*} value
|
|
@@ -288,37 +285,45 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
288
285
|
*/
|
|
289
286
|
checkType(value, expectedType) {
|
|
290
287
|
switch (expectedType) {
|
|
291
|
-
case 'string':
|
|
292
|
-
|
|
293
|
-
case '
|
|
294
|
-
|
|
295
|
-
case '
|
|
296
|
-
|
|
297
|
-
case '
|
|
298
|
-
|
|
288
|
+
case 'string':
|
|
289
|
+
return typeof value === 'string';
|
|
290
|
+
case 'number':
|
|
291
|
+
return typeof value === 'number';
|
|
292
|
+
case 'integer':
|
|
293
|
+
return Number.isInteger(value);
|
|
294
|
+
case 'boolean':
|
|
295
|
+
return typeof value === 'boolean';
|
|
296
|
+
case 'array':
|
|
297
|
+
return Array.isArray(value);
|
|
298
|
+
case 'object':
|
|
299
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
300
|
+
case 'null':
|
|
301
|
+
return value === null;
|
|
302
|
+
default:
|
|
303
|
+
return true;
|
|
299
304
|
}
|
|
300
305
|
}
|
|
301
|
-
|
|
306
|
+
|
|
302
307
|
/**
|
|
303
308
|
* Record invocation metrics
|
|
304
309
|
* @param {string} toolName
|
|
305
310
|
* @param {number} duration
|
|
306
311
|
* @param {boolean} success
|
|
307
312
|
*/
|
|
308
|
-
recordInvocation(toolName, duration,
|
|
313
|
+
recordInvocation(toolName, duration, _success) {
|
|
309
314
|
const count = this.invocationCounts.get(toolName) || 0;
|
|
310
315
|
this.invocationCounts.set(toolName, count + 1);
|
|
311
|
-
|
|
316
|
+
|
|
312
317
|
const history = this.latencyHistory.get(toolName) || [];
|
|
313
318
|
history.push(duration);
|
|
314
|
-
|
|
319
|
+
|
|
315
320
|
// Keep last 100 latencies
|
|
316
321
|
if (history.length > 100) {
|
|
317
322
|
history.shift();
|
|
318
323
|
}
|
|
319
324
|
this.latencyHistory.set(toolName, history);
|
|
320
325
|
}
|
|
321
|
-
|
|
326
|
+
|
|
322
327
|
/**
|
|
323
328
|
* Get tool by name
|
|
324
329
|
* @param {string} name
|
|
@@ -327,7 +332,7 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
327
332
|
getTool(name) {
|
|
328
333
|
return this.tools.get(name);
|
|
329
334
|
}
|
|
330
|
-
|
|
335
|
+
|
|
331
336
|
/**
|
|
332
337
|
* Get all tools
|
|
333
338
|
* @returns {MCPToolDefinition[]}
|
|
@@ -335,7 +340,7 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
335
340
|
getAllTools() {
|
|
336
341
|
return Array.from(this.tools.values());
|
|
337
342
|
}
|
|
338
|
-
|
|
343
|
+
|
|
339
344
|
/**
|
|
340
345
|
* Get tools by server
|
|
341
346
|
* @param {string} serverName
|
|
@@ -345,7 +350,7 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
345
350
|
const toolNames = this.serverTools.get(serverName) || [];
|
|
346
351
|
return toolNames.map(name => this.tools.get(name)).filter(Boolean);
|
|
347
352
|
}
|
|
348
|
-
|
|
353
|
+
|
|
349
354
|
/**
|
|
350
355
|
* Get tools in OpenAI format
|
|
351
356
|
* @returns {Object[]}
|
|
@@ -356,11 +361,11 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
356
361
|
function: {
|
|
357
362
|
name: tool.name.replace('/', '_'),
|
|
358
363
|
description: tool.description,
|
|
359
|
-
parameters: tool.inputSchema
|
|
360
|
-
}
|
|
364
|
+
parameters: tool.inputSchema,
|
|
365
|
+
},
|
|
361
366
|
}));
|
|
362
367
|
}
|
|
363
|
-
|
|
368
|
+
|
|
364
369
|
/**
|
|
365
370
|
* Get tools in Anthropic format
|
|
366
371
|
* @returns {Object[]}
|
|
@@ -369,10 +374,10 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
369
374
|
return this.getAllTools().map(tool => ({
|
|
370
375
|
name: tool.name.replace('/', '_'),
|
|
371
376
|
description: tool.description,
|
|
372
|
-
input_schema: tool.inputSchema
|
|
377
|
+
input_schema: tool.inputSchema,
|
|
373
378
|
}));
|
|
374
379
|
}
|
|
375
|
-
|
|
380
|
+
|
|
376
381
|
/**
|
|
377
382
|
* Get tool statistics
|
|
378
383
|
* @param {string} toolName
|
|
@@ -381,26 +386,26 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
381
386
|
getToolStats(toolName) {
|
|
382
387
|
const invocations = this.invocationCounts.get(toolName) || 0;
|
|
383
388
|
const latencies = this.latencyHistory.get(toolName) || [];
|
|
384
|
-
|
|
389
|
+
|
|
385
390
|
let avgLatency = 0;
|
|
386
391
|
let minLatency = 0;
|
|
387
392
|
let maxLatency = 0;
|
|
388
|
-
|
|
393
|
+
|
|
389
394
|
if (latencies.length > 0) {
|
|
390
395
|
avgLatency = latencies.reduce((a, b) => a + b, 0) / latencies.length;
|
|
391
396
|
minLatency = Math.min(...latencies);
|
|
392
397
|
maxLatency = Math.max(...latencies);
|
|
393
398
|
}
|
|
394
|
-
|
|
399
|
+
|
|
395
400
|
return {
|
|
396
401
|
invocations,
|
|
397
402
|
avgLatency: Math.round(avgLatency),
|
|
398
403
|
minLatency,
|
|
399
404
|
maxLatency,
|
|
400
|
-
recentLatencies: latencies.slice(-10)
|
|
405
|
+
recentLatencies: latencies.slice(-10),
|
|
401
406
|
};
|
|
402
407
|
}
|
|
403
|
-
|
|
408
|
+
|
|
404
409
|
/**
|
|
405
410
|
* Get registry statistics
|
|
406
411
|
* @returns {Object}
|
|
@@ -408,33 +413,33 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
408
413
|
getStats() {
|
|
409
414
|
const tools = this.getAllTools();
|
|
410
415
|
let totalInvocations = 0;
|
|
411
|
-
|
|
416
|
+
|
|
412
417
|
for (const count of this.invocationCounts.values()) {
|
|
413
418
|
totalInvocations += count;
|
|
414
419
|
}
|
|
415
|
-
|
|
420
|
+
|
|
416
421
|
return {
|
|
417
422
|
totalTools: tools.length,
|
|
418
423
|
servers: this.serverTools.size,
|
|
419
424
|
totalInvocations,
|
|
420
425
|
toolsByServer: Object.fromEntries(
|
|
421
426
|
Array.from(this.serverTools.entries()).map(([server, tools]) => [server, tools.length])
|
|
422
|
-
)
|
|
427
|
+
),
|
|
423
428
|
};
|
|
424
429
|
}
|
|
425
|
-
|
|
430
|
+
|
|
426
431
|
/**
|
|
427
432
|
* Unregister tools from a server
|
|
428
433
|
* @param {string} serverName
|
|
429
434
|
*/
|
|
430
435
|
unregisterServer(serverName) {
|
|
431
436
|
const toolNames = this.serverTools.get(serverName) || [];
|
|
432
|
-
|
|
437
|
+
|
|
433
438
|
for (const name of toolNames) {
|
|
434
439
|
this.tools.delete(name);
|
|
435
440
|
this.invocationCounts.delete(name);
|
|
436
441
|
this.latencyHistory.delete(name);
|
|
437
|
-
|
|
442
|
+
|
|
438
443
|
// Unregister from skill registry
|
|
439
444
|
if (this.skillRegistry) {
|
|
440
445
|
const skillId = `mcp-${name.replace('/', '-')}`;
|
|
@@ -445,11 +450,11 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
445
450
|
}
|
|
446
451
|
}
|
|
447
452
|
}
|
|
448
|
-
|
|
453
|
+
|
|
449
454
|
this.serverTools.delete(serverName);
|
|
450
455
|
this.emit('server:unregistered', { serverName, toolCount: toolNames.length });
|
|
451
456
|
}
|
|
452
|
-
|
|
457
|
+
|
|
453
458
|
/**
|
|
454
459
|
* Clear all tools
|
|
455
460
|
*/
|
|
@@ -463,5 +468,5 @@ class MCPToolRegistry extends EventEmitter {
|
|
|
463
468
|
}
|
|
464
469
|
|
|
465
470
|
module.exports = {
|
|
466
|
-
MCPToolRegistry
|
|
471
|
+
MCPToolRegistry,
|
|
467
472
|
};
|