@houtini/lm 1.0.13 → 2.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/README.md +67 -237
- package/dist/index.d.ts +5 -3
- package/dist/index.js +149 -213
- package/dist/index.js.map +1 -1
- package/package.json +23 -32
- package/server.json +44 -0
- package/CHANGELOG.md +0 -282
- package/dist/cache/analysis-cache.d.ts +0 -33
- package/dist/cache/analysis-cache.d.ts.map +0 -1
- package/dist/cache/analysis-cache.js +0 -56
- package/dist/cache/analysis-cache.js.map +0 -1
- package/dist/cache/cache-manager.d.ts +0 -29
- package/dist/cache/cache-manager.d.ts.map +0 -1
- package/dist/cache/cache-manager.js +0 -85
- package/dist/cache/cache-manager.js.map +0 -1
- package/dist/cache/index.d.ts +0 -16
- package/dist/cache/index.d.ts.map +0 -1
- package/dist/cache/index.js +0 -17
- package/dist/cache/index.js.map +0 -1
- package/dist/cache/prompt-cache.d.ts +0 -33
- package/dist/cache/prompt-cache.d.ts.map +0 -1
- package/dist/cache/prompt-cache.js +0 -61
- package/dist/cache/prompt-cache.js.map +0 -1
- package/dist/config.d.ts +0 -41
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -71
- package/dist/config.js.map +0 -1
- package/dist/core/ThreeStagePromptManager.d.ts +0 -23
- package/dist/core/ThreeStagePromptManager.d.ts.map +0 -1
- package/dist/core/ThreeStagePromptManager.js +0 -118
- package/dist/core/ThreeStagePromptManager.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/plugins/base-plugin.d.ts +0 -55
- package/dist/plugins/base-plugin.d.ts.map +0 -1
- package/dist/plugins/base-plugin.js +0 -120
- package/dist/plugins/base-plugin.js.map +0 -1
- package/dist/plugins/index.d.ts +0 -58
- package/dist/plugins/index.d.ts.map +0 -1
- package/dist/plugins/index.js +0 -162
- package/dist/plugins/index.js.map +0 -1
- package/dist/plugins/types.d.ts +0 -5
- package/dist/plugins/types.d.ts.map +0 -1
- package/dist/plugins/types.js +0 -5
- package/dist/plugins/types.js.map +0 -1
- package/dist/prompts/analyze/code-quality.d.ts +0 -116
- package/dist/prompts/analyze/code-quality.d.ts.map +0 -1
- package/dist/prompts/analyze/code-quality.js +0 -437
- package/dist/prompts/analyze/code-quality.js.map +0 -1
- package/dist/prompts/analyze/compare-integration.d.ts +0 -130
- package/dist/prompts/analyze/compare-integration.d.ts.map +0 -1
- package/dist/prompts/analyze/compare-integration.js +0 -547
- package/dist/prompts/analyze/compare-integration.js.map +0 -1
- package/dist/prompts/analyze/count-files.d.ts +0 -109
- package/dist/prompts/analyze/count-files.d.ts.map +0 -1
- package/dist/prompts/analyze/count-files.js +0 -403
- package/dist/prompts/analyze/count-files.js.map +0 -1
- package/dist/prompts/analyze/database-queries.d.ts +0 -156
- package/dist/prompts/analyze/database-queries.d.ts.map +0 -1
- package/dist/prompts/analyze/database-queries.js +0 -763
- package/dist/prompts/analyze/database-queries.js.map +0 -1
- package/dist/prompts/analyze/dependencies.d.ts +0 -97
- package/dist/prompts/analyze/dependencies.d.ts.map +0 -1
- package/dist/prompts/analyze/dependencies.js +0 -337
- package/dist/prompts/analyze/dependencies.js.map +0 -1
- package/dist/prompts/analyze/diff-signatures.d.ts +0 -139
- package/dist/prompts/analyze/diff-signatures.d.ts.map +0 -1
- package/dist/prompts/analyze/diff-signatures.js +0 -708
- package/dist/prompts/analyze/diff-signatures.js.map +0 -1
- package/dist/prompts/analyze/find-patterns.d.ts +0 -128
- package/dist/prompts/analyze/find-patterns.d.ts.map +0 -1
- package/dist/prompts/analyze/find-patterns.js +0 -524
- package/dist/prompts/analyze/find-patterns.js.map +0 -1
- package/dist/prompts/analyze/find-unused-css.d.ts +0 -151
- package/dist/prompts/analyze/find-unused-css.d.ts.map +0 -1
- package/dist/prompts/analyze/find-unused-css.js +0 -760
- package/dist/prompts/analyze/find-unused-css.js.map +0 -1
- package/dist/prompts/analyze/n8n-workflow.d.ts +0 -137
- package/dist/prompts/analyze/n8n-workflow.d.ts.map +0 -1
- package/dist/prompts/analyze/n8n-workflow.js +0 -533
- package/dist/prompts/analyze/n8n-workflow.js.map +0 -1
- package/dist/prompts/analyze/project-structure.d.ts +0 -126
- package/dist/prompts/analyze/project-structure.d.ts.map +0 -1
- package/dist/prompts/analyze/project-structure.js +0 -573
- package/dist/prompts/analyze/project-structure.js.map +0 -1
- package/dist/prompts/analyze/security-audit.d.ts +0 -142
- package/dist/prompts/analyze/security-audit.d.ts.map +0 -1
- package/dist/prompts/analyze/security-audit.js +0 -641
- package/dist/prompts/analyze/security-audit.js.map +0 -1
- package/dist/prompts/analyze/single-file.d.ts +0 -162
- package/dist/prompts/analyze/single-file.d.ts.map +0 -1
- package/dist/prompts/analyze/single-file.js +0 -669
- package/dist/prompts/analyze/single-file.js.map +0 -1
- package/dist/prompts/analyze/trace-execution.d.ts +0 -126
- package/dist/prompts/analyze/trace-execution.d.ts.map +0 -1
- package/dist/prompts/analyze/trace-execution.js +0 -613
- package/dist/prompts/analyze/trace-execution.js.map +0 -1
- package/dist/prompts/analyze/wordpress-plugin-audit.d.ts +0 -116
- package/dist/prompts/analyze/wordpress-plugin-audit.d.ts.map +0 -1
- package/dist/prompts/analyze/wordpress-plugin-audit.js +0 -456
- package/dist/prompts/analyze/wordpress-plugin-audit.js.map +0 -1
- package/dist/prompts/analyze/wordpress-plugin-readiness.d.ts +0 -103
- package/dist/prompts/analyze/wordpress-plugin-readiness.d.ts.map +0 -1
- package/dist/prompts/analyze/wordpress-plugin-readiness.js +0 -506
- package/dist/prompts/analyze/wordpress-plugin-readiness.js.map +0 -1
- package/dist/prompts/analyze/wordpress-security.d.ts +0 -146
- package/dist/prompts/analyze/wordpress-security.d.ts.map +0 -1
- package/dist/prompts/analyze/wordpress-security.js +0 -702
- package/dist/prompts/analyze/wordpress-security.js.map +0 -1
- package/dist/prompts/analyze/wordpress-theme-audit.d.ts +0 -114
- package/dist/prompts/analyze/wordpress-theme-audit.d.ts.map +0 -1
- package/dist/prompts/analyze/wordpress-theme-audit.js +0 -540
- package/dist/prompts/analyze/wordpress-theme-audit.js.map +0 -1
- package/dist/prompts/custom/custom-prompt.d.ts +0 -135
- package/dist/prompts/custom/custom-prompt.d.ts.map +0 -1
- package/dist/prompts/custom/custom-prompt.js +0 -421
- package/dist/prompts/custom/custom-prompt.js.map +0 -1
- package/dist/prompts/fun/arcade-game.d.ts +0 -152
- package/dist/prompts/fun/arcade-game.d.ts.map +0 -1
- package/dist/prompts/fun/arcade-game.js +0 -657
- package/dist/prompts/fun/arcade-game.js.map +0 -1
- package/dist/prompts/fun/create_text_adventure.d.ts +0 -100
- package/dist/prompts/fun/create_text_adventure.d.ts.map +0 -1
- package/dist/prompts/fun/create_text_adventure.js +0 -401
- package/dist/prompts/fun/create_text_adventure.js.map +0 -1
- package/dist/prompts/fun/css-art-generator.d.ts +0 -168
- package/dist/prompts/fun/css-art-generator.d.ts.map +0 -1
- package/dist/prompts/fun/css-art-generator.js +0 -831
- package/dist/prompts/fun/css-art-generator.js.map +0 -1
- package/dist/prompts/generate/project-documentation.d.ts +0 -137
- package/dist/prompts/generate/project-documentation.d.ts.map +0 -1
- package/dist/prompts/generate/project-documentation.js +0 -670
- package/dist/prompts/generate/project-documentation.js.map +0 -1
- package/dist/prompts/generate/refactoring.d.ts +0 -164
- package/dist/prompts/generate/refactoring.d.ts.map +0 -1
- package/dist/prompts/generate/refactoring.js +0 -625
- package/dist/prompts/generate/refactoring.js.map +0 -1
- package/dist/prompts/generate/responsive-component.d.ts +0 -147
- package/dist/prompts/generate/responsive-component.d.ts.map +0 -1
- package/dist/prompts/generate/responsive-component.js +0 -957
- package/dist/prompts/generate/responsive-component.js.map +0 -1
- package/dist/prompts/generate/typescript-conversion.d.ts +0 -144
- package/dist/prompts/generate/typescript-conversion.d.ts.map +0 -1
- package/dist/prompts/generate/typescript-conversion.js +0 -531
- package/dist/prompts/generate/typescript-conversion.js.map +0 -1
- package/dist/prompts/generate/unit-tests.d.ts +0 -139
- package/dist/prompts/generate/unit-tests.d.ts.map +0 -1
- package/dist/prompts/generate/unit-tests.js +0 -582
- package/dist/prompts/generate/unit-tests.js.map +0 -1
- package/dist/prompts/generate/wordpress-plugin.d.ts +0 -179
- package/dist/prompts/generate/wordpress-plugin.d.ts.map +0 -1
- package/dist/prompts/generate/wordpress-plugin.js +0 -767
- package/dist/prompts/generate/wordpress-plugin.js.map +0 -1
- package/dist/prompts/generate/wordpress-theme-from-static.d.ts +0 -177
- package/dist/prompts/generate/wordpress-theme-from-static.d.ts.map +0 -1
- package/dist/prompts/generate/wordpress-theme-from-static.js +0 -699
- package/dist/prompts/generate/wordpress-theme-from-static.js.map +0 -1
- package/dist/prompts/shared/cache-manager.d.ts +0 -45
- package/dist/prompts/shared/cache-manager.d.ts.map +0 -1
- package/dist/prompts/shared/cache-manager.js +0 -129
- package/dist/prompts/shared/cache-manager.js.map +0 -1
- package/dist/prompts/shared/helpers.d.ts +0 -39
- package/dist/prompts/shared/helpers.d.ts.map +0 -1
- package/dist/prompts/shared/helpers.js +0 -151
- package/dist/prompts/shared/helpers.js.map +0 -1
- package/dist/prompts/shared/templates.d.ts +0 -35
- package/dist/prompts/shared/templates.d.ts.map +0 -1
- package/dist/prompts/shared/templates.js +0 -77
- package/dist/prompts/shared/templates.js.map +0 -1
- package/dist/prompts/shared/types.d.ts +0 -112
- package/dist/prompts/shared/types.d.ts.map +0 -1
- package/dist/prompts/shared/types.js +0 -5
- package/dist/prompts/shared/types.js.map +0 -1
- package/dist/prompts/system/find-unused-files.d.ts +0 -106
- package/dist/prompts/system/find-unused-files.d.ts.map +0 -1
- package/dist/prompts/system/find-unused-files.js +0 -357
- package/dist/prompts/system/find-unused-files.js.map +0 -1
- package/dist/security/index.d.ts +0 -39
- package/dist/security/index.d.ts.map +0 -1
- package/dist/security/index.js +0 -46
- package/dist/security/index.js.map +0 -1
- package/dist/security/integration-helpers.d.ts +0 -121
- package/dist/security/integration-helpers.d.ts.map +0 -1
- package/dist/security/integration-helpers.js +0 -190
- package/dist/security/integration-helpers.js.map +0 -1
- package/dist/security/output-encoder.d.ts +0 -94
- package/dist/security/output-encoder.d.ts.map +0 -1
- package/dist/security/output-encoder.js +0 -295
- package/dist/security/output-encoder.js.map +0 -1
- package/dist/security/prompt-injection-guard.d.ts +0 -59
- package/dist/security/prompt-injection-guard.d.ts.map +0 -1
- package/dist/security/prompt-injection-guard.js +0 -249
- package/dist/security/prompt-injection-guard.js.map +0 -1
- package/dist/security/sanitisation.d.ts +0 -67
- package/dist/security/sanitisation.d.ts.map +0 -1
- package/dist/security/sanitisation.js +0 -398
- package/dist/security/sanitisation.js.map +0 -1
- package/dist/security/security-service.d.ts +0 -103
- package/dist/security/security-service.d.ts.map +0 -1
- package/dist/security/security-service.js +0 -303
- package/dist/security/security-service.js.map +0 -1
- package/dist/security-config.d.ts +0 -45
- package/dist/security-config.d.ts.map +0 -1
- package/dist/security-config.js +0 -63
- package/dist/security-config.js.map +0 -1
- package/dist/system/function-list.d.ts +0 -61
- package/dist/system/function-list.d.ts.map +0 -1
- package/dist/system/function-list.js +0 -111
- package/dist/system/function-list.js.map +0 -1
- package/dist/system/function-registry.d.ts +0 -23
- package/dist/system/function-registry.d.ts.map +0 -1
- package/dist/system/function-registry.js +0 -136
- package/dist/system/function-registry.js.map +0 -1
- package/dist/system/health-check.d.ts +0 -33
- package/dist/system/health-check.d.ts.map +0 -1
- package/dist/system/health-check.js +0 -98
- package/dist/system/health-check.js.map +0 -1
- package/dist/system/path-resolver.d.ts +0 -55
- package/dist/system/path-resolver.d.ts.map +0 -1
- package/dist/system/path-resolver.js +0 -90
- package/dist/system/path-resolver.js.map +0 -1
- package/dist/templates/plugin-template.d.ts +0 -121
- package/dist/templates/plugin-template.d.ts.map +0 -1
- package/dist/templates/plugin-template.js +0 -454
- package/dist/templates/plugin-template.js.map +0 -1
- package/dist/types/chunking-types.d.ts +0 -88
- package/dist/types/chunking-types.d.ts.map +0 -1
- package/dist/types/chunking-types.js +0 -18
- package/dist/types/chunking-types.js.map +0 -1
- package/dist/types/prompt-stages.d.ts +0 -30
- package/dist/types/prompt-stages.d.ts.map +0 -1
- package/dist/types/prompt-stages.js +0 -6
- package/dist/types/prompt-stages.js.map +0 -1
- package/dist/types.d.ts +0 -45
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -6
- package/dist/types.js.map +0 -1
- package/dist/utils/css-parser.d.ts +0 -26
- package/dist/utils/css-parser.d.ts.map +0 -1
- package/dist/utils/css-parser.js +0 -117
- package/dist/utils/css-parser.js.map +0 -1
- package/dist/utils/path-resolver.d.ts +0 -13
- package/dist/utils/path-resolver.d.ts.map +0 -1
- package/dist/utils/path-resolver.js +0 -78
- package/dist/utils/path-resolver.js.map +0 -1
- package/dist/utils/plugin-utilities.d.ts +0 -176
- package/dist/utils/plugin-utilities.d.ts.map +0 -1
- package/dist/utils/plugin-utilities.js +0 -269
- package/dist/utils/plugin-utilities.js.map +0 -1
- package/dist/utils/streamHandler.d.ts +0 -3
- package/dist/utils/streamHandler.d.ts.map +0 -1
- package/dist/utils/streamHandler.js +0 -137
- package/dist/utils/streamHandler.js.map +0 -1
- package/dist/validation/output-validator.d.ts +0 -136
- package/dist/validation/output-validator.d.ts.map +0 -1
- package/dist/validation/output-validator.js +0 -262
- package/dist/validation/output-validator.js.map +0 -1
- package/dist/validation/response-factory.d.ts +0 -44
- package/dist/validation/response-factory.d.ts.map +0 -1
- package/dist/validation/response-factory.js +0 -202
- package/dist/validation/response-factory.js.map +0 -1
- package/dist/validation/schemas.d.ts +0 -519
- package/dist/validation/schemas.d.ts.map +0 -1
- package/dist/validation/schemas.js +0 -6
- package/dist/validation/schemas.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,242 +1,178 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Houtini LM MCP Server
|
|
4
|
-
*
|
|
3
|
+
* Houtini LM — MCP Server for Local LLMs via OpenAI-compatible API
|
|
4
|
+
*
|
|
5
|
+
* Connects to LM Studio (or any OpenAI-compatible endpoint) and exposes
|
|
6
|
+
* chat, custom prompts, and model info as MCP tools.
|
|
5
7
|
*/
|
|
6
8
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
7
9
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
8
|
-
import { CallToolRequestSchema, ListToolsRequestSchema,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
tools: {
|
|
30
|
-
description: 'Context preservation through local processing - use for routine tasks, save Claude for strategy'
|
|
31
|
-
},
|
|
32
|
-
resources: {
|
|
33
|
-
description: 'Local LM Studio integration with unlimited processing'
|
|
34
|
-
},
|
|
35
|
-
prompts: {
|
|
36
|
-
description: 'Three-stage prompting system with expert personas'
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
// Note: Security validation will be done during server start
|
|
41
|
-
this.lmStudioClient = new LMStudioClient({
|
|
42
|
-
baseUrl: config.lmStudioUrl,
|
|
43
|
-
});
|
|
44
|
-
this.pluginLoader = PluginRegistry.getInstance();
|
|
45
|
-
this.setupHandlers();
|
|
46
|
-
// Error handling
|
|
47
|
-
this.server.onerror = (error) => {
|
|
48
|
-
// Silent error handling for MCP protocol compliance
|
|
49
|
-
};
|
|
50
|
-
process.on('SIGINT', async () => {
|
|
51
|
-
await this.server.close();
|
|
52
|
-
process.exit(0);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Validate security configuration at startup
|
|
57
|
-
* Fails fast if environment variables are not properly configured
|
|
58
|
-
*/
|
|
59
|
-
async validateSecurityConfiguration() {
|
|
60
|
-
try {
|
|
61
|
-
const { securityConfig } = await import('./security-config.js');
|
|
62
|
-
const allowedDirs = securityConfig.getAllowedDirectories();
|
|
63
|
-
// Validate each directory exists and is accessible
|
|
64
|
-
const fs = await import('fs');
|
|
65
|
-
for (const dir of allowedDirs) {
|
|
66
|
-
try {
|
|
67
|
-
const stat = fs.statSync(dir);
|
|
68
|
-
if (!stat.isDirectory()) {
|
|
69
|
-
console.warn(`[WARNING] Allowed path is not a directory: ${dir}`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
catch (error) {
|
|
73
|
-
console.warn(`[WARNING] Cannot access allowed directory: ${dir} (${error.message})`);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
catch (error) {
|
|
78
|
-
console.error('SECURITY CONFIGURATION ERROR:', error.message);
|
|
79
|
-
console.error('Please set the LLM_MCP_ALLOWED_DIRS environment variable in your Claude Desktop configuration.');
|
|
80
|
-
console.error('Example: "LLM_MCP_ALLOWED_DIRS": "C:\\\\MCP,C:\\\\dev,C:\\\\Users\\\\YourName\\\\Documents"');
|
|
81
|
-
process.exit(1);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Initialize plugins from directories
|
|
86
|
-
*/
|
|
87
|
-
async initializePlugins() {
|
|
88
|
-
if (this.pluginsInitialized)
|
|
89
|
-
return;
|
|
90
|
-
try {
|
|
91
|
-
console.error('DEBUG: Starting plugin initialization...');
|
|
92
|
-
// Load plugins from prompts directory
|
|
93
|
-
const promptsDir = path.join(__dirname, 'prompts');
|
|
94
|
-
console.error('DEBUG: Loading from:', promptsDir);
|
|
95
|
-
await this.pluginLoader.loadPlugins(promptsDir);
|
|
96
|
-
// Load system plugins
|
|
97
|
-
await this.loadSystemPlugins();
|
|
98
|
-
this.pluginsInitialized = true;
|
|
99
|
-
console.error('DEBUG: Plugins initialized successfully');
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
// Silent error handling to avoid JSON-RPC interference
|
|
103
|
-
throw error;
|
|
104
|
-
}
|
|
10
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
11
|
+
const LM_BASE_URL = process.env.LM_STUDIO_URL || 'http://localhost:1234';
|
|
12
|
+
const LM_MODEL = process.env.LM_STUDIO_MODEL || '';
|
|
13
|
+
const LM_PASSWORD = process.env.LM_STUDIO_PASSWORD || '';
|
|
14
|
+
const DEFAULT_MAX_TOKENS = 4096;
|
|
15
|
+
const DEFAULT_TEMPERATURE = 0.3;
|
|
16
|
+
function apiHeaders() {
|
|
17
|
+
const h = { 'Content-Type': 'application/json' };
|
|
18
|
+
if (LM_PASSWORD)
|
|
19
|
+
h['Authorization'] = `Bearer ${LM_PASSWORD}`;
|
|
20
|
+
return h;
|
|
21
|
+
}
|
|
22
|
+
async function chatCompletion(messages, options = {}) {
|
|
23
|
+
const body = {
|
|
24
|
+
messages,
|
|
25
|
+
temperature: options.temperature ?? DEFAULT_TEMPERATURE,
|
|
26
|
+
max_tokens: options.maxTokens ?? DEFAULT_MAX_TOKENS,
|
|
27
|
+
stream: false,
|
|
28
|
+
};
|
|
29
|
+
if (options.model || LM_MODEL) {
|
|
30
|
+
body.model = options.model || LM_MODEL;
|
|
105
31
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (file.endsWith('.js')) { // Only load .js files, skip .d.ts
|
|
115
|
-
const filePath = path.join(systemDir, file);
|
|
116
|
-
await this.loadSystemPlugin(filePath);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
// Silent error handling to avoid JSON-RPC interference
|
|
122
|
-
// console.error('[Plugin Server] Error loading system plugins:', error);
|
|
123
|
-
}
|
|
32
|
+
const res = await fetch(`${LM_BASE_URL}/v1/chat/completions`, {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: apiHeaders(),
|
|
35
|
+
body: JSON.stringify(body),
|
|
36
|
+
});
|
|
37
|
+
if (!res.ok) {
|
|
38
|
+
const text = await res.text().catch(() => '');
|
|
39
|
+
throw new Error(`LM Studio API error ${res.status}: ${text}`);
|
|
124
40
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
41
|
+
return res.json();
|
|
42
|
+
}
|
|
43
|
+
async function listModels() {
|
|
44
|
+
const res = await fetch(`${LM_BASE_URL}/v1/models`, { headers: apiHeaders() });
|
|
45
|
+
if (!res.ok)
|
|
46
|
+
throw new Error(`Failed to list models: ${res.status}`);
|
|
47
|
+
const data = (await res.json());
|
|
48
|
+
return data.data.map((m) => m.id);
|
|
49
|
+
}
|
|
50
|
+
// ── MCP Tool definitions ─────────────────────────────────────────────
|
|
51
|
+
const TOOLS = [
|
|
52
|
+
{
|
|
53
|
+
name: 'chat',
|
|
54
|
+
description: 'Send a message to the local LLM and get a response. Useful for offloading routine analysis to a local model and preserving Claude context.',
|
|
55
|
+
inputSchema: {
|
|
56
|
+
type: 'object',
|
|
57
|
+
properties: {
|
|
58
|
+
message: { type: 'string', description: 'User message to send' },
|
|
59
|
+
system: { type: 'string', description: 'Optional system prompt' },
|
|
60
|
+
temperature: { type: 'number', description: 'Sampling temperature (0–2, default 0.3)' },
|
|
61
|
+
max_tokens: { type: 'number', description: 'Max tokens in response (default 4096)' },
|
|
62
|
+
},
|
|
63
|
+
required: ['message'],
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'custom_prompt',
|
|
68
|
+
description: 'Run a structured prompt with system message, context, and instruction against the local LLM.',
|
|
69
|
+
inputSchema: {
|
|
70
|
+
type: 'object',
|
|
71
|
+
properties: {
|
|
72
|
+
system: { type: 'string', description: 'System prompt / persona' },
|
|
73
|
+
context: { type: 'string', description: 'Background context or data to analyse' },
|
|
74
|
+
instruction: { type: 'string', description: 'What to do with the context' },
|
|
75
|
+
temperature: { type: 'number', description: 'Sampling temperature (default 0.3)' },
|
|
76
|
+
max_tokens: { type: 'number', description: 'Max tokens (default 4096)' },
|
|
77
|
+
},
|
|
78
|
+
required: ['instruction'],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'list_models',
|
|
83
|
+
description: 'List models currently loaded in LM Studio.',
|
|
84
|
+
inputSchema: { type: 'object', properties: {} },
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'health_check',
|
|
88
|
+
description: 'Check connectivity to the local LM Studio instance.',
|
|
89
|
+
inputSchema: { type: 'object', properties: {} },
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
// ── MCP Server ───────────────────────────────────────────────────────
|
|
93
|
+
const server = new Server({ name: 'houtini-lm', version: '2.0.1' }, { capabilities: { tools: {} } });
|
|
94
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
95
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
96
|
+
const { name, arguments: args } = request.params;
|
|
97
|
+
try {
|
|
98
|
+
switch (name) {
|
|
99
|
+
case 'chat': {
|
|
100
|
+
const { message, system, temperature, max_tokens } = args;
|
|
101
|
+
const messages = [];
|
|
102
|
+
if (system)
|
|
103
|
+
messages.push({ role: 'system', content: system });
|
|
104
|
+
messages.push({ role: 'user', content: message });
|
|
105
|
+
const resp = await chatCompletion(messages, {
|
|
106
|
+
temperature,
|
|
107
|
+
maxTokens: max_tokens,
|
|
108
|
+
});
|
|
109
|
+
const reply = resp.choices[0]?.message?.content ?? '';
|
|
110
|
+
const usage = resp.usage
|
|
111
|
+
? `\n\n---\nModel: ${resp.model} | Tokens: ${resp.usage.prompt_tokens}→${resp.usage.completion_tokens}`
|
|
112
|
+
: '';
|
|
113
|
+
return { content: [{ type: 'text', text: reply + usage }] };
|
|
153
114
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if (!this.pluginsInitialized) {
|
|
171
|
-
await this.initializePlugins();
|
|
115
|
+
case 'custom_prompt': {
|
|
116
|
+
const { system, context, instruction, temperature, max_tokens } = args;
|
|
117
|
+
const messages = [];
|
|
118
|
+
if (system)
|
|
119
|
+
messages.push({ role: 'system', content: system });
|
|
120
|
+
let userContent = instruction;
|
|
121
|
+
if (context)
|
|
122
|
+
userContent = `Context:\n${context}\n\nInstruction:\n${instruction}`;
|
|
123
|
+
messages.push({ role: 'user', content: userContent });
|
|
124
|
+
const resp = await chatCompletion(messages, {
|
|
125
|
+
temperature,
|
|
126
|
+
maxTokens: max_tokens,
|
|
127
|
+
});
|
|
128
|
+
return {
|
|
129
|
+
content: [{ type: 'text', text: resp.choices[0]?.message?.content ?? '' }],
|
|
130
|
+
};
|
|
172
131
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const pluginName = toolName.replace(/^houtini-lm:/, '');
|
|
176
|
-
// Execute plugin
|
|
177
|
-
const result = await this.pluginLoader.executePlugin(pluginName, args, this.lmStudioClient);
|
|
178
|
-
// Silent success - no console output
|
|
179
|
-
// Return standardized MCP response
|
|
132
|
+
case 'list_models': {
|
|
133
|
+
const models = await listModels();
|
|
180
134
|
return {
|
|
181
135
|
content: [
|
|
182
136
|
{
|
|
183
137
|
type: 'text',
|
|
184
|
-
text:
|
|
185
|
-
|
|
186
|
-
|
|
138
|
+
text: models.length
|
|
139
|
+
? `Loaded models:\n${models.map((m) => ` • ${m}`).join('\n')}`
|
|
140
|
+
: 'No models currently loaded.',
|
|
141
|
+
},
|
|
142
|
+
],
|
|
187
143
|
};
|
|
188
144
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
145
|
+
case 'health_check': {
|
|
146
|
+
const start = Date.now();
|
|
147
|
+
const models = await listModels();
|
|
148
|
+
const ms = Date.now() - start;
|
|
192
149
|
return {
|
|
193
150
|
content: [
|
|
194
151
|
{
|
|
195
152
|
type: 'text',
|
|
196
|
-
text:
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
tool: toolName,
|
|
200
|
-
timestamp: new Date().toISOString()
|
|
201
|
-
}, null, 2)
|
|
202
|
-
}
|
|
203
|
-
]
|
|
153
|
+
text: `Connected to ${LM_BASE_URL} (${ms}ms)\nAuth: ${LM_PASSWORD ? 'enabled' : 'none'}\nModels loaded: ${models.length}${models.length ? '\n' + models.join(', ') : ''}`,
|
|
154
|
+
},
|
|
155
|
+
],
|
|
204
156
|
};
|
|
205
157
|
}
|
|
206
|
-
|
|
158
|
+
default:
|
|
159
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
160
|
+
}
|
|
207
161
|
}
|
|
208
|
-
|
|
209
|
-
* Get plugin statistics
|
|
210
|
-
*/
|
|
211
|
-
getPluginStats() {
|
|
212
|
-
const plugins = this.pluginLoader.getPlugins();
|
|
213
|
-
const categories = {
|
|
214
|
-
analyze: this.pluginLoader.getPluginsByCategory('analyze').length,
|
|
215
|
-
generate: this.pluginLoader.getPluginsByCategory('generate').length,
|
|
216
|
-
system: this.pluginLoader.getPluginsByCategory('system').length
|
|
217
|
-
};
|
|
162
|
+
catch (error) {
|
|
218
163
|
return {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
pluginNames: plugins.map(p => p.name)
|
|
164
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
|
|
165
|
+
isError: true,
|
|
222
166
|
};
|
|
223
167
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
await this.validateSecurityConfiguration();
|
|
230
|
-
// Silent startup after security validation - no console output to avoid JSON-RPC interference
|
|
231
|
-
const transport = new StdioServerTransport();
|
|
232
|
-
await this.server.connect(transport);
|
|
233
|
-
// Server started silently
|
|
234
|
-
}
|
|
168
|
+
});
|
|
169
|
+
async function main() {
|
|
170
|
+
const transport = new StdioServerTransport();
|
|
171
|
+
await server.connect(transport);
|
|
172
|
+
process.stderr.write(`Houtini LM server running (${LM_BASE_URL})\n`);
|
|
235
173
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
server.start().catch((error) => {
|
|
239
|
-
// Silent error handling - only exit on critical startup failure
|
|
174
|
+
main().catch((error) => {
|
|
175
|
+
process.stderr.write(`Fatal error: ${error}\n`);
|
|
240
176
|
process.exit(1);
|
|
241
177
|
});
|
|
242
178
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,38 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@houtini/lm",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "MCP server for local LLMs — connects to LM Studio or any OpenAI-compatible endpoint",
|
|
6
|
+
"mcpName": "io.github.houtini-ai/lm",
|
|
6
7
|
"main": "dist/index.js",
|
|
7
8
|
"bin": {
|
|
8
9
|
"houtini-lm": "dist/index.js"
|
|
9
10
|
},
|
|
10
11
|
"scripts": {
|
|
11
12
|
"build": "tsc && node add-shebang.mjs",
|
|
12
|
-
"clean": "rimraf dist",
|
|
13
|
-
"rebuild": "npm run clean && npm run build",
|
|
14
|
-
"start": "node dist/index.js",
|
|
15
13
|
"dev": "tsc --watch",
|
|
16
|
-
"
|
|
17
|
-
"test:integration": "node tests/integration.test.mjs",
|
|
18
|
-
"test:tools": "node tests/tools.test.mjs",
|
|
19
|
-
"test:core": "jest tests/core.test.ts",
|
|
20
|
-
"test": "npm run test:connection && npm run test:tools && npm run test:core",
|
|
21
|
-
"diagnose": "node diagnostics/run-diagnostics.mjs",
|
|
22
|
-
"check:processes": "node diagnostics/check-claude-processes.mjs"
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
23
15
|
},
|
|
24
16
|
"keywords": [
|
|
25
|
-
"houtini",
|
|
26
|
-
"local-lm",
|
|
27
17
|
"mcp",
|
|
28
18
|
"model-context-protocol",
|
|
29
|
-
"
|
|
19
|
+
"mcp-server",
|
|
30
20
|
"lm-studio",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"local-
|
|
21
|
+
"ollama",
|
|
22
|
+
"vllm",
|
|
23
|
+
"openai",
|
|
24
|
+
"openai-compatible",
|
|
25
|
+
"local-llm",
|
|
26
|
+
"claude",
|
|
27
|
+
"ai-tools",
|
|
28
|
+
"llama-cpp",
|
|
29
|
+
"ai",
|
|
30
|
+
"llm"
|
|
36
31
|
],
|
|
37
32
|
"author": "Richard Baxter <richard@richardbaxter.co> (https://richardbaxter.co)",
|
|
38
33
|
"license": "MIT",
|
|
@@ -44,28 +39,24 @@
|
|
|
44
39
|
"bugs": {
|
|
45
40
|
"url": "https://github.com/houtini-ai/lm/issues"
|
|
46
41
|
},
|
|
42
|
+
"funding": {
|
|
43
|
+
"type": "github",
|
|
44
|
+
"url": "https://github.com/sponsors/houtini-ai"
|
|
45
|
+
},
|
|
47
46
|
"dependencies": {
|
|
48
|
-
"@
|
|
49
|
-
"@modelcontextprotocol/sdk": "^1.17.3",
|
|
50
|
-
"puppeteer": "^21.11.0",
|
|
51
|
-
"css-tree": "^2.3.1"
|
|
47
|
+
"@modelcontextprotocol/sdk": "^1.26.0"
|
|
52
48
|
},
|
|
53
49
|
"devDependencies": {
|
|
54
|
-
"@types/node": "^
|
|
55
|
-
"
|
|
56
|
-
"jest": "^29.7.0",
|
|
57
|
-
"ts-jest": "^29.1.1",
|
|
58
|
-
"rimraf": "^6.0.1",
|
|
59
|
-
"typescript": "^5.3.3",
|
|
60
|
-
"@types/css-tree": "^2.3.8"
|
|
50
|
+
"@types/node": "^22.0.0",
|
|
51
|
+
"typescript": "^5.7.0"
|
|
61
52
|
},
|
|
62
53
|
"engines": {
|
|
63
54
|
"node": ">=18.0.0"
|
|
64
55
|
},
|
|
65
56
|
"files": [
|
|
66
57
|
"dist/**/*",
|
|
58
|
+
"server.json",
|
|
67
59
|
"README.md",
|
|
68
|
-
"CHANGELOG.md",
|
|
69
60
|
"LICENSE"
|
|
70
61
|
],
|
|
71
62
|
"publishConfig": {
|
package/server.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "Houtini LM",
|
|
4
|
+
"description": "MCP server that connects Claude to any OpenAI-compatible LLM endpoint. Offload routine analysis to a local model and preserve your Claude context window.",
|
|
5
|
+
"icon": "https://houtini.ai/favicon.ico",
|
|
6
|
+
"repository": {
|
|
7
|
+
"url": "https://github.com/houtini-ai/lm",
|
|
8
|
+
"source": "github"
|
|
9
|
+
},
|
|
10
|
+
"version": "2.0.1",
|
|
11
|
+
"packages": [
|
|
12
|
+
{
|
|
13
|
+
"registryType": "npm",
|
|
14
|
+
"identifier": "@houtini/lm",
|
|
15
|
+
"version": "2.0.1",
|
|
16
|
+
"transport": [
|
|
17
|
+
{
|
|
18
|
+
"type": "stdio"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"environmentVariables": [
|
|
22
|
+
{
|
|
23
|
+
"name": "LM_STUDIO_URL",
|
|
24
|
+
"description": "Base URL of the OpenAI-compatible API endpoint",
|
|
25
|
+
"isRequired": false,
|
|
26
|
+
"format": "url"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "LM_STUDIO_MODEL",
|
|
30
|
+
"description": "Model identifier to use for requests (auto-detected if not set)",
|
|
31
|
+
"isRequired": false,
|
|
32
|
+
"format": "string"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "LM_STUDIO_PASSWORD",
|
|
36
|
+
"description": "Bearer token for API authentication (no auth if blank)",
|
|
37
|
+
"isRequired": false,
|
|
38
|
+
"isSecret": true,
|
|
39
|
+
"format": "string"
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|