@hailer/mcp 1.1.9 → 1.1.11

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.
@@ -1 +1 @@
1
- {"sessionId":"a3f80f7e-ef83-490b-8222-5edd12bd0654","toolCalls":2,"compactCount":0,"lastWarning":"none","stopBlocks":0}
1
+ {"sessionId":"ae9be9bf-7163-49a4-9e0f-153584c7bedf","toolCalls":1,"compactCount":0,"lastWarning":"none","stopBlocks":0}
@@ -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/inbox/usage.jsonl CHANGED
@@ -1,3 +1,4 @@
1
1
  {"ts":"2026-02-13T08:23:26.264Z","agent":"general-purpose","status":"unknown","project":"hailer-mcp","description":"Convert new agents to OpenCode"}
2
2
  {"ts":"2026-02-16T05:26:20.980Z","agent":"agent-svetlana-code-review","status":"unknown","project":"hailer-mcp","description":"Check bot date handling code"}
3
3
  {"ts":"2026-02-16T05:32:29.203Z","agent":"agent-giuseppe-app-builder","status":"error","project":"hailer-mcp","description":"Add date validation to bot+tools"}
4
+ {"ts":"2026-02-24T12:50:03.634Z","agent":"agent-gunther-mcp-tools","status":"unknown","project":"hailer-mcp","description":"Find removed MCP tools"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hailer/mcp",
3
- "version": "1.1.9",
3
+ "version": "1.1.11",
4
4
  "config": {
5
5
  "docker": {
6
6
  "registry": "registry.gitlab.com/hailer-repos/hailer-mcp"
@@ -25,7 +25,8 @@
25
25
  "release:patch": "npm version patch -m 'chore: release v%s' && git push && git push --tags && npm run build && npm publish --access public",
26
26
  "release:minor": "npm version minor -m 'chore: release v%s' && git push && git push --tags && npm run build && npm publish --access public",
27
27
  "release:major": "npm version major -m 'chore: release v%s' && git push && git push --tags && npm run build && npm publish --access public",
28
- "seed-config": "tsx src/commands/seed-config.ts"
28
+ "seed-config": "tsx src/commands/seed-config.ts",
29
+ "postinstall": "node scripts/postinstall.cjs"
29
30
  },
30
31
  "dependencies": {
31
32
  "@anthropic-ai/sdk": "^0.54.0",
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * postinstall: Copies .claude/ (agents, skills, hooks) to the project root.
4
+ * Runs automatically after `npm install @hailer/mcp`.
5
+ * Skips when installing in the hailer-mcp repo itself (development).
6
+ */
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+ // Find the project root by walking up from node_modules/@hailer/mcp/
11
+ function findProjectRoot() {
12
+ let dir = __dirname;
13
+ // Walk up until we find a package.json that isn't ours
14
+ for (let i = 0; i < 10; i++) {
15
+ dir = path.dirname(dir);
16
+ const pkgPath = path.join(dir, 'package.json');
17
+ if (fs.existsSync(pkgPath)) {
18
+ try {
19
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
20
+ // Skip if this is our own package.json
21
+ if (pkg.name === '@hailer/mcp') continue;
22
+ return dir;
23
+ } catch { continue; }
24
+ }
25
+ }
26
+ return null;
27
+ }
28
+
29
+ function copyDir(src, dest) {
30
+ if (!fs.existsSync(src)) return;
31
+ fs.mkdirSync(dest, { recursive: true });
32
+
33
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
34
+ const srcPath = path.join(src, entry.name);
35
+ const destPath = path.join(dest, entry.name);
36
+
37
+ if (entry.isDirectory()) {
38
+ copyDir(srcPath, destPath);
39
+ } else {
40
+ // Don't overwrite user's local settings
41
+ if (entry.name === 'settings.local.json' && fs.existsSync(destPath)) continue;
42
+ fs.copyFileSync(srcPath, destPath);
43
+ }
44
+ }
45
+ }
46
+
47
+ const projectRoot = findProjectRoot();
48
+
49
+ // Skip if we can't find a project root or if running in dev (our own repo)
50
+ if (!projectRoot) {
51
+ console.log('@hailer/mcp: skipping agent install (no project root found)');
52
+ process.exit(0);
53
+ }
54
+
55
+ const src = path.join(__dirname, '..', '.claude');
56
+ const dest = path.join(projectRoot, '.claude');
57
+
58
+ if (!fs.existsSync(src)) {
59
+ console.log('@hailer/mcp: no .claude/ directory in package, skipping');
60
+ process.exit(0);
61
+ }
62
+
63
+ copyDir(src, dest);
64
+ console.log(`@hailer/mcp: agents installed to ${dest}`);