@hailer/mcp 0.0.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/.claude/commands/tool-builder.md +37 -0
- package/.claude/commands/ws-pull.md +44 -0
- package/.claude/settings.json +8 -0
- package/.claude/settings.local.json +49 -0
- package/.claude/skills/activity-api/SKILL.md +96 -0
- package/.claude/skills/activity-api/references/activity-endpoints.md +845 -0
- package/.claude/skills/add-app-member-skill/SKILL.md +977 -0
- package/.claude/skills/agent-building/SKILL.md +243 -0
- package/.claude/skills/agent-building/references/architecture-patterns.md +446 -0
- package/.claude/skills/agent-building/references/code-examples.md +587 -0
- package/.claude/skills/agent-building/references/implementation-guide.md +619 -0
- package/.claude/skills/app-api/SKILL.md +219 -0
- package/.claude/skills/app-api/references/app-endpoints.md +759 -0
- package/.claude/skills/building-hailer-apps-skill/SKILL.md +548 -0
- package/.claude/skills/create-app-skill/SKILL.md +1101 -0
- package/.claude/skills/create-insight-skill/SKILL.md +1317 -0
- package/.claude/skills/get-insight-data-skill/SKILL.md +1053 -0
- package/.claude/skills/hailer-api/SKILL.md +283 -0
- package/.claude/skills/hailer-api/references/activities.md +620 -0
- package/.claude/skills/hailer-api/references/authentication.md +216 -0
- package/.claude/skills/hailer-api/references/datasets.md +437 -0
- package/.claude/skills/hailer-api/references/files.md +301 -0
- package/.claude/skills/hailer-api/references/insights.md +469 -0
- package/.claude/skills/hailer-api/references/workflows.md +720 -0
- package/.claude/skills/hailer-api/references/workspaces-users.md +445 -0
- package/.claude/skills/insight-api/SKILL.md +185 -0
- package/.claude/skills/insight-api/references/insight-endpoints.md +514 -0
- package/.claude/skills/install-workflow-skill/SKILL.md +1056 -0
- package/.claude/skills/list-apps-skill/SKILL.md +1010 -0
- package/.claude/skills/list-workflows-minimal-skill/SKILL.md +992 -0
- package/.claude/skills/local-first-skill/SKILL.md +570 -0
- package/.claude/skills/mcp-tools/SKILL.md +419 -0
- package/.claude/skills/mcp-tools/references/api-endpoints.md +499 -0
- package/.claude/skills/mcp-tools/references/data-structures.md +554 -0
- package/.claude/skills/mcp-tools/references/implementation-patterns.md +717 -0
- package/.claude/skills/preview-insight-skill/SKILL.md +1290 -0
- package/.claude/skills/publish-hailer-app-skill/SKILL.md +453 -0
- package/.claude/skills/remove-app-member-skill/SKILL.md +671 -0
- package/.claude/skills/remove-app-skill/SKILL.md +985 -0
- package/.claude/skills/remove-insight-skill/SKILL.md +1011 -0
- package/.claude/skills/remove-workflow-skill/SKILL.md +920 -0
- package/.claude/skills/scaffold-hailer-app-skill/SKILL.md +1034 -0
- package/.claude/skills/skill-testing/README.md +137 -0
- package/.claude/skills/skill-testing/SKILL.md +348 -0
- package/.claude/skills/skill-testing/references/test-patterns.md +705 -0
- package/.claude/skills/skill-testing/references/testing-guide.md +603 -0
- package/.claude/skills/skill-testing/references/validation-checklist.md +537 -0
- package/.claude/skills/tool-builder/SKILL.md +328 -0
- package/.claude/skills/update-app-skill/SKILL.md +970 -0
- package/.claude/skills/update-workflow-field-skill/SKILL.md +1098 -0
- package/.env.example +81 -0
- package/.mcp.json +13 -0
- package/README.md +297 -0
- package/dist/app.d.ts +4 -0
- package/dist/app.js +74 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +5 -0
- package/dist/client/adaptive-documentation-bot.d.ts +108 -0
- package/dist/client/adaptive-documentation-bot.js +475 -0
- package/dist/client/adaptive-documentation-types.d.ts +66 -0
- package/dist/client/adaptive-documentation-types.js +9 -0
- package/dist/client/agent-activity-bot.d.ts +51 -0
- package/dist/client/agent-activity-bot.js +166 -0
- package/dist/client/agent-tracker.d.ts +499 -0
- package/dist/client/agent-tracker.js +659 -0
- package/dist/client/description-updater.d.ts +56 -0
- package/dist/client/description-updater.js +259 -0
- package/dist/client/log-parser.d.ts +72 -0
- package/dist/client/log-parser.js +387 -0
- package/dist/client/mcp-client.d.ts +50 -0
- package/dist/client/mcp-client.js +532 -0
- package/dist/client/message-processor.d.ts +35 -0
- package/dist/client/message-processor.js +352 -0
- package/dist/client/multi-bot-manager.d.ts +24 -0
- package/dist/client/multi-bot-manager.js +74 -0
- package/dist/client/providers/anthropic-provider.d.ts +19 -0
- package/dist/client/providers/anthropic-provider.js +631 -0
- package/dist/client/providers/llm-provider.d.ts +47 -0
- package/dist/client/providers/llm-provider.js +367 -0
- package/dist/client/providers/openai-provider.d.ts +23 -0
- package/dist/client/providers/openai-provider.js +621 -0
- package/dist/client/simple-llm-caller.d.ts +19 -0
- package/dist/client/simple-llm-caller.js +100 -0
- package/dist/client/skill-generator.d.ts +81 -0
- package/dist/client/skill-generator.js +386 -0
- package/dist/client/test-adaptive-bot.d.ts +9 -0
- package/dist/client/test-adaptive-bot.js +82 -0
- package/dist/client/token-pricing.d.ts +38 -0
- package/dist/client/token-pricing.js +127 -0
- package/dist/client/token-tracker.d.ts +232 -0
- package/dist/client/token-tracker.js +457 -0
- package/dist/client/token-usage-bot.d.ts +53 -0
- package/dist/client/token-usage-bot.js +153 -0
- package/dist/client/tool-executor.d.ts +69 -0
- package/dist/client/tool-executor.js +159 -0
- package/dist/client/tool-schema-loader.d.ts +60 -0
- package/dist/client/tool-schema-loader.js +178 -0
- package/dist/client/types.d.ts +69 -0
- package/dist/client/types.js +7 -0
- package/dist/config.d.ts +162 -0
- package/dist/config.js +296 -0
- package/dist/core.d.ts +26 -0
- package/dist/core.js +147 -0
- package/dist/lib/context-manager.d.ts +111 -0
- package/dist/lib/context-manager.js +431 -0
- package/dist/lib/logger.d.ts +74 -0
- package/dist/lib/logger.js +277 -0
- package/dist/lib/materialize.d.ts +3 -0
- package/dist/lib/materialize.js +101 -0
- package/dist/lib/normalizedName.d.ts +7 -0
- package/dist/lib/normalizedName.js +48 -0
- package/dist/lib/prompt-length-manager.d.ts +81 -0
- package/dist/lib/prompt-length-manager.js +457 -0
- package/dist/lib/terminal-prompt.d.ts +9 -0
- package/dist/lib/terminal-prompt.js +108 -0
- package/dist/mcp/UserContextCache.d.ts +56 -0
- package/dist/mcp/UserContextCache.js +163 -0
- package/dist/mcp/auth.d.ts +2 -0
- package/dist/mcp/auth.js +29 -0
- package/dist/mcp/hailer-clients.d.ts +42 -0
- package/dist/mcp/hailer-clients.js +246 -0
- package/dist/mcp/signal-handler.d.ts +45 -0
- package/dist/mcp/signal-handler.js +317 -0
- package/dist/mcp/tool-registry.d.ts +100 -0
- package/dist/mcp/tool-registry.js +306 -0
- package/dist/mcp/tools/activity.d.ts +15 -0
- package/dist/mcp/tools/activity.js +955 -0
- package/dist/mcp/tools/app.d.ts +20 -0
- package/dist/mcp/tools/app.js +1488 -0
- package/dist/mcp/tools/discussion.d.ts +19 -0
- package/dist/mcp/tools/discussion.js +950 -0
- package/dist/mcp/tools/file.d.ts +15 -0
- package/dist/mcp/tools/file.js +119 -0
- package/dist/mcp/tools/insight.d.ts +17 -0
- package/dist/mcp/tools/insight.js +806 -0
- package/dist/mcp/tools/skill.d.ts +10 -0
- package/dist/mcp/tools/skill.js +279 -0
- package/dist/mcp/tools/user.d.ts +10 -0
- package/dist/mcp/tools/user.js +108 -0
- package/dist/mcp/tools/workflow-template.d.ts +19 -0
- package/dist/mcp/tools/workflow-template.js +822 -0
- package/dist/mcp/tools/workflow.d.ts +18 -0
- package/dist/mcp/tools/workflow.js +1362 -0
- package/dist/mcp/utils/api-errors.d.ts +45 -0
- package/dist/mcp/utils/api-errors.js +160 -0
- package/dist/mcp/utils/data-transformers.d.ts +102 -0
- package/dist/mcp/utils/data-transformers.js +194 -0
- package/dist/mcp/utils/file-upload.d.ts +33 -0
- package/dist/mcp/utils/file-upload.js +148 -0
- package/dist/mcp/utils/hailer-api-client.d.ts +120 -0
- package/dist/mcp/utils/hailer-api-client.js +323 -0
- package/dist/mcp/utils/index.d.ts +13 -0
- package/dist/mcp/utils/index.js +39 -0
- package/dist/mcp/utils/logger.d.ts +42 -0
- package/dist/mcp/utils/logger.js +103 -0
- package/dist/mcp/utils/types.d.ts +286 -0
- package/dist/mcp/utils/types.js +7 -0
- package/dist/mcp/workspace-cache.d.ts +42 -0
- package/dist/mcp/workspace-cache.js +97 -0
- package/dist/mcp-server.d.ts +42 -0
- package/dist/mcp-server.js +280 -0
- package/package.json +56 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MCPServerService - Handles Express app, routes, and HTTP server management
|
|
4
|
+
*
|
|
5
|
+
* Implements JSON-RPC 2.0 MCP protocol over HTTP with Server-Sent Events (SSE)
|
|
6
|
+
* for LLM clients (Claude Desktop, etc.)
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.MCPServerService = void 0;
|
|
13
|
+
const express_1 = __importDefault(require("express"));
|
|
14
|
+
const cors_1 = __importDefault(require("cors"));
|
|
15
|
+
const logger_1 = require("./lib/logger");
|
|
16
|
+
const config_1 = require("./config");
|
|
17
|
+
const UserContextCache_1 = require("./mcp/UserContextCache");
|
|
18
|
+
const tool_registry_1 = require("./mcp/tool-registry");
|
|
19
|
+
class MCPServerService {
|
|
20
|
+
app;
|
|
21
|
+
server;
|
|
22
|
+
logger;
|
|
23
|
+
config;
|
|
24
|
+
toolRegistry; // ← Injected
|
|
25
|
+
constructor(config) {
|
|
26
|
+
this.config = config;
|
|
27
|
+
this.toolRegistry = config.toolRegistry;
|
|
28
|
+
this.logger = (0, logger_1.createLogger)({
|
|
29
|
+
component: 'mcp-server',
|
|
30
|
+
service: 'hailer-mcp-server'
|
|
31
|
+
});
|
|
32
|
+
this.app = (0, express_1.default)();
|
|
33
|
+
this.setupMiddleware();
|
|
34
|
+
this.setupRoutes();
|
|
35
|
+
this.logger.info('MCP Server initialized', {
|
|
36
|
+
port: config.port,
|
|
37
|
+
corsOrigins: config.corsOrigins
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
setupMiddleware() {
|
|
41
|
+
// Configure CORS - empty array means allow all origins (like original cors())
|
|
42
|
+
if (this.config.corsOrigins.length === 0) {
|
|
43
|
+
this.app.use((0, cors_1.default)());
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
this.app.use((0, cors_1.default)({
|
|
47
|
+
origin: this.config.corsOrigins
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
this.app.use(express_1.default.json());
|
|
51
|
+
// Request logging middleware (skip health endpoint to reduce noise)
|
|
52
|
+
this.app.use((req, res, next) => {
|
|
53
|
+
const isHealthCheck = req.path === '/health';
|
|
54
|
+
const start = Date.now();
|
|
55
|
+
const requestLogger = this.logger.child({
|
|
56
|
+
requestId: `req-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
|
|
57
|
+
method: req.method,
|
|
58
|
+
path: req.path
|
|
59
|
+
});
|
|
60
|
+
if (!isHealthCheck) {
|
|
61
|
+
requestLogger.debug('Incoming request', {
|
|
62
|
+
url: req.url,
|
|
63
|
+
headers: req.headers['content-type'],
|
|
64
|
+
userAgent: req.headers['user-agent']
|
|
65
|
+
});
|
|
66
|
+
res.on('finish', () => {
|
|
67
|
+
const duration = Date.now() - start;
|
|
68
|
+
requestLogger.info('Request completed', {
|
|
69
|
+
statusCode: res.statusCode,
|
|
70
|
+
duration
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
// Add logger to request for route handlers
|
|
75
|
+
req.logger = requestLogger;
|
|
76
|
+
next();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
setupRoutes() {
|
|
80
|
+
const appConfig = (0, config_1.createApplicationConfig)();
|
|
81
|
+
// Health check endpoint (no logging - too noisy)
|
|
82
|
+
this.app.get('/health', (_, res) => {
|
|
83
|
+
const health = {
|
|
84
|
+
status: 'ok',
|
|
85
|
+
timestamp: new Date().toISOString(),
|
|
86
|
+
service: 'hailer-mcp-server',
|
|
87
|
+
version: '0.1.0'
|
|
88
|
+
};
|
|
89
|
+
res.json(health);
|
|
90
|
+
});
|
|
91
|
+
// MCP Protocol endpoint - JSON-RPC 2.0 over SSE
|
|
92
|
+
this.app.post('/api/mcp', async (req, res) => {
|
|
93
|
+
req.logger.debug('MCP request received', { method: req.body?.method });
|
|
94
|
+
try {
|
|
95
|
+
const apiKey = req.query.apiKey;
|
|
96
|
+
const mcpRequest = req.body;
|
|
97
|
+
let result;
|
|
98
|
+
if (mcpRequest.method === 'tools/list') {
|
|
99
|
+
req.logger.debug('Handling tools/list request');
|
|
100
|
+
// Get agent configuration for filtering
|
|
101
|
+
let filterConfig;
|
|
102
|
+
if (apiKey) {
|
|
103
|
+
try {
|
|
104
|
+
const agentConfig = appConfig.getClientConfig(apiKey);
|
|
105
|
+
if (agentConfig.allowedTools || agentConfig.allowedGroups) {
|
|
106
|
+
filterConfig = {
|
|
107
|
+
allowedTools: agentConfig.allowedTools,
|
|
108
|
+
allowedGroups: agentConfig.allowedGroups
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
req.logger.debug('No config found for apiKey, returning all tools');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Apply NUCLEAR tools blocking if NOT explicitly enabled
|
|
117
|
+
if (!config_1.environment.ENABLE_NUCLEAR_TOOLS) {
|
|
118
|
+
if (!filterConfig) {
|
|
119
|
+
// No filter yet - create one excluding NUCLEAR
|
|
120
|
+
filterConfig = {
|
|
121
|
+
allowedGroups: [tool_registry_1.ToolGroup.READ, tool_registry_1.ToolGroup.WRITE, tool_registry_1.ToolGroup.PLAYGROUND]
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
else if (filterConfig.allowedGroups) {
|
|
125
|
+
// Filter has groups - remove NUCLEAR if present
|
|
126
|
+
filterConfig.allowedGroups = filterConfig.allowedGroups.filter(g => g !== tool_registry_1.ToolGroup.NUCLEAR);
|
|
127
|
+
}
|
|
128
|
+
// Note: If filter has explicit allowedTools list, NUCLEAR tools won't be in it anyway
|
|
129
|
+
req.logger.debug('NUCLEAR tools blocked (not explicitly enabled)');
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
req.logger.debug('NUCLEAR tools enabled by environment variable');
|
|
133
|
+
}
|
|
134
|
+
result = {
|
|
135
|
+
tools: this.toolRegistry.getToolDefinitions(filterConfig)
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
else if (mcpRequest.method === 'tools/get_schema') {
|
|
139
|
+
const toolName = mcpRequest.params?.name;
|
|
140
|
+
req.logger.debug('Handling tools/get_schema request', { toolName });
|
|
141
|
+
if (!toolName) {
|
|
142
|
+
return this.sendMcpError(res, mcpRequest.id, -32602, 'Tool name required in params.name', 400);
|
|
143
|
+
}
|
|
144
|
+
const schema = this.toolRegistry.getToolSchema(toolName);
|
|
145
|
+
if (!schema) {
|
|
146
|
+
return this.sendMcpError(res, mcpRequest.id, -32602, `Tool not found: ${toolName}`, 404);
|
|
147
|
+
}
|
|
148
|
+
result = schema;
|
|
149
|
+
}
|
|
150
|
+
else if (mcpRequest.method === 'tools/call') {
|
|
151
|
+
if (!apiKey) {
|
|
152
|
+
return this.sendMcpError(res, mcpRequest.id, -32602, 'API key required for tools/call', 400);
|
|
153
|
+
}
|
|
154
|
+
const { name, arguments: args = {} } = mcpRequest.params;
|
|
155
|
+
req.logger.debug('Handling tools/call request', { toolName: name });
|
|
156
|
+
// Check access control
|
|
157
|
+
if (!this.canAccessTool(name, apiKey, appConfig)) {
|
|
158
|
+
return this.sendMcpError(res, mcpRequest.id, -32603, `Access denied to tool: ${name}`, 403);
|
|
159
|
+
}
|
|
160
|
+
const userContext = await UserContextCache_1.UserContextCache.getContext(apiKey);
|
|
161
|
+
result = await this.toolRegistry.executeTool(name, args, userContext);
|
|
162
|
+
}
|
|
163
|
+
else if (mcpRequest.method === 'initialize') {
|
|
164
|
+
req.logger.info('MCP initialize request received');
|
|
165
|
+
const sessionId = `session-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
166
|
+
res.setHeader('Mcp-Session-Id', sessionId);
|
|
167
|
+
result = {
|
|
168
|
+
protocolVersion: '2024-11-05',
|
|
169
|
+
capabilities: { tools: {} },
|
|
170
|
+
serverInfo: {
|
|
171
|
+
name: 'hailer-mcp-server',
|
|
172
|
+
version: '1.0.0'
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
else if (mcpRequest.method === 'notifications/initialized') {
|
|
177
|
+
req.logger.info('MCP handshake completed - client initialized');
|
|
178
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
179
|
+
res.status(204).end();
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
return this.sendMcpError(res, mcpRequest.id, -32601, `Method not found: ${mcpRequest.method}`, 400);
|
|
184
|
+
}
|
|
185
|
+
// Send success response
|
|
186
|
+
const response = {
|
|
187
|
+
jsonrpc: '2.0',
|
|
188
|
+
result,
|
|
189
|
+
id: mcpRequest.id
|
|
190
|
+
};
|
|
191
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
192
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
193
|
+
res.setHeader('Connection', 'keep-alive');
|
|
194
|
+
res.write(`data: ${JSON.stringify(response)}\n\n`);
|
|
195
|
+
res.end();
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
req.logger.error('MCP handler error', error, { apiKey: req.query.apiKey });
|
|
199
|
+
this.sendMcpError(res, req.body?.id || null, -32000, `Server error: ${error instanceof Error ? error.message : String(error)}`, 500);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
this.logger.info('Routes configured', {
|
|
203
|
+
routes: [
|
|
204
|
+
'/health - Server health check',
|
|
205
|
+
'/api/mcp - MCP protocol (JSON-RPC 2.0)'
|
|
206
|
+
]
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Check if agent has access to a specific tool
|
|
211
|
+
*/
|
|
212
|
+
canAccessTool(toolName, apiKey, appConfig) {
|
|
213
|
+
try {
|
|
214
|
+
const agentConfig = appConfig.getClientConfig(apiKey);
|
|
215
|
+
// Explicit tool whitelist (takes precedence)
|
|
216
|
+
if (agentConfig.allowedTools) {
|
|
217
|
+
return agentConfig.allowedTools.includes(toolName);
|
|
218
|
+
}
|
|
219
|
+
// Group-based access control
|
|
220
|
+
if (agentConfig.allowedGroups) {
|
|
221
|
+
const tool = this.toolRegistry.getTool(toolName);
|
|
222
|
+
return tool ? agentConfig.allowedGroups.includes(tool.group) : false;
|
|
223
|
+
}
|
|
224
|
+
// Default: allow all (backward compatible)
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Send MCP error response
|
|
233
|
+
*/
|
|
234
|
+
sendMcpError(res, id, code, message, httpStatus) {
|
|
235
|
+
const errorResponse = {
|
|
236
|
+
jsonrpc: '2.0',
|
|
237
|
+
error: { code, message },
|
|
238
|
+
id
|
|
239
|
+
};
|
|
240
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
241
|
+
res.status(httpStatus).write(`data: ${JSON.stringify(errorResponse)}\n\n`);
|
|
242
|
+
res.end();
|
|
243
|
+
}
|
|
244
|
+
async start() {
|
|
245
|
+
const { port } = this.config;
|
|
246
|
+
return new Promise((resolve, reject) => {
|
|
247
|
+
this.server = this.app.listen(port, () => {
|
|
248
|
+
this.logger.info('MCP Server started', {
|
|
249
|
+
port: port,
|
|
250
|
+
healthCheck: `http://localhost:${port}/health`,
|
|
251
|
+
mcpEndpoint: `http://localhost:${port}/api/mcp`
|
|
252
|
+
});
|
|
253
|
+
resolve();
|
|
254
|
+
});
|
|
255
|
+
this.server.on('error', (error) => {
|
|
256
|
+
this.logger.error('MCP Server error', error);
|
|
257
|
+
reject(error);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
async stop() {
|
|
262
|
+
if (this.server) {
|
|
263
|
+
const server = this.server;
|
|
264
|
+
return new Promise((resolve) => {
|
|
265
|
+
server.close(() => {
|
|
266
|
+
this.logger.info('MCP Server stopped gracefully');
|
|
267
|
+
resolve();
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
getApp() {
|
|
273
|
+
return this.app;
|
|
274
|
+
}
|
|
275
|
+
isRunning() {
|
|
276
|
+
return !!this.server?.listening;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
exports.MCPServerService = MCPServerService;
|
|
280
|
+
//# sourceMappingURL=mcp-server.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hailer/mcp",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"config": {
|
|
5
|
+
"docker": {
|
|
6
|
+
"registry": "registry.gitlab.com/hailer-repos/hailer-mcp"
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "tsx watch src/app.ts",
|
|
11
|
+
"claude-code-mcp": "DISABLE_CLIENT=true tsx src/app.ts",
|
|
12
|
+
"start-mcp-only": "DISABLE_CLIENT=true tsx src/app.ts",
|
|
13
|
+
"start-client-only": "DISABLE_MCP_SERVER=true tsx src/app.ts",
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"start": "node dist/app.js",
|
|
16
|
+
"lint": "eslint src/",
|
|
17
|
+
"build-dev-push": "rm -rf build/docker-dev && docker build --target artifacts --output build/docker-dev . -f Dockerfile.build-dev && docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs)-dev -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):dev -f ./Dockerfile.dev .",
|
|
18
|
+
"build-debug-push": "docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs)-debug -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):debug -f ./Dockerfile.debug .",
|
|
19
|
+
"build-prod-push": "rm -rf build/docker-prod && docker build --target artifacts --output build/docker-prod . -f Dockerfile.build-prod && docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs) -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):prod -f ./Dockerfile.prod .",
|
|
20
|
+
"build-k3d": "docker build -f Dockerfile.debug . -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs) && k3d image import $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs) -c hailer",
|
|
21
|
+
"build-k3d-dummy": "docker build --target artifacts --output build/docker-dev . -f Dockerfile.build-dev && docker build -f Dockerfile.dev . -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs)-dev && k3d image import $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs)-dev -c hailer",
|
|
22
|
+
"mcp-server": "hailer-mcp"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@anthropic-ai/sdk": "^0.54.0",
|
|
26
|
+
"@hailer/cli": "^1.1.10",
|
|
27
|
+
"@modelcontextprotocol/sdk": "^1.11.5",
|
|
28
|
+
"@opentelemetry/api-logs": "^0.57.0",
|
|
29
|
+
"@opentelemetry/exporter-logs-otlp-proto": "^0.57.0",
|
|
30
|
+
"@opentelemetry/resources": "^1.28.0",
|
|
31
|
+
"@opentelemetry/sdk-logs": "^0.57.0",
|
|
32
|
+
"@opentelemetry/sdk-node": "^0.57.0",
|
|
33
|
+
"@opentelemetry/semantic-conventions": "^1.36.0",
|
|
34
|
+
"cors": "^2.8.5",
|
|
35
|
+
"dotenv": "^16.5.0",
|
|
36
|
+
"express": "^4.21.2",
|
|
37
|
+
"form-data": "^4.0.4",
|
|
38
|
+
"openai": "^5.5.1",
|
|
39
|
+
"zod": "^3.24.1"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@eslint/js": "^9.29.0",
|
|
43
|
+
"@types/cors": "^2.8.17",
|
|
44
|
+
"@types/express": "^5.0.0",
|
|
45
|
+
"@types/node": "^20.19.1",
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^8.34.1",
|
|
47
|
+
"@typescript-eslint/parser": "^8.34.1",
|
|
48
|
+
"eslint": "^9.29.0",
|
|
49
|
+
"globals": "^16.2.0",
|
|
50
|
+
"tsx": "^4.19.2",
|
|
51
|
+
"typescript": "^5"
|
|
52
|
+
},
|
|
53
|
+
"bin": {
|
|
54
|
+
"hailer-mcp": "dist/cli.js"
|
|
55
|
+
}
|
|
56
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2022"],
|
|
5
|
+
"module": "CommonJS",
|
|
6
|
+
"moduleResolution": "node",
|
|
7
|
+
"types": ["node"],
|
|
8
|
+
"outDir": "./dist",
|
|
9
|
+
"rootDir": "./src",
|
|
10
|
+
"strict": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"forceConsistentCasingInFileNames": true,
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"allowSyntheticDefaultImports": true,
|
|
16
|
+
"declaration": true,
|
|
17
|
+
"declarationMap": true,
|
|
18
|
+
"sourceMap": true,
|
|
19
|
+
"baseUrl": "."
|
|
20
|
+
},
|
|
21
|
+
"include": ["src/**/*"],
|
|
22
|
+
"exclude": ["node_modules", "dist"]
|
|
23
|
+
}
|