@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.
Files changed (264) hide show
  1. package/README.md +67 -237
  2. package/dist/index.d.ts +5 -3
  3. package/dist/index.js +149 -213
  4. package/dist/index.js.map +1 -1
  5. package/package.json +23 -32
  6. package/server.json +44 -0
  7. package/CHANGELOG.md +0 -282
  8. package/dist/cache/analysis-cache.d.ts +0 -33
  9. package/dist/cache/analysis-cache.d.ts.map +0 -1
  10. package/dist/cache/analysis-cache.js +0 -56
  11. package/dist/cache/analysis-cache.js.map +0 -1
  12. package/dist/cache/cache-manager.d.ts +0 -29
  13. package/dist/cache/cache-manager.d.ts.map +0 -1
  14. package/dist/cache/cache-manager.js +0 -85
  15. package/dist/cache/cache-manager.js.map +0 -1
  16. package/dist/cache/index.d.ts +0 -16
  17. package/dist/cache/index.d.ts.map +0 -1
  18. package/dist/cache/index.js +0 -17
  19. package/dist/cache/index.js.map +0 -1
  20. package/dist/cache/prompt-cache.d.ts +0 -33
  21. package/dist/cache/prompt-cache.d.ts.map +0 -1
  22. package/dist/cache/prompt-cache.js +0 -61
  23. package/dist/cache/prompt-cache.js.map +0 -1
  24. package/dist/config.d.ts +0 -41
  25. package/dist/config.d.ts.map +0 -1
  26. package/dist/config.js +0 -71
  27. package/dist/config.js.map +0 -1
  28. package/dist/core/ThreeStagePromptManager.d.ts +0 -23
  29. package/dist/core/ThreeStagePromptManager.d.ts.map +0 -1
  30. package/dist/core/ThreeStagePromptManager.js +0 -118
  31. package/dist/core/ThreeStagePromptManager.js.map +0 -1
  32. package/dist/index.d.ts.map +0 -1
  33. package/dist/plugins/base-plugin.d.ts +0 -55
  34. package/dist/plugins/base-plugin.d.ts.map +0 -1
  35. package/dist/plugins/base-plugin.js +0 -120
  36. package/dist/plugins/base-plugin.js.map +0 -1
  37. package/dist/plugins/index.d.ts +0 -58
  38. package/dist/plugins/index.d.ts.map +0 -1
  39. package/dist/plugins/index.js +0 -162
  40. package/dist/plugins/index.js.map +0 -1
  41. package/dist/plugins/types.d.ts +0 -5
  42. package/dist/plugins/types.d.ts.map +0 -1
  43. package/dist/plugins/types.js +0 -5
  44. package/dist/plugins/types.js.map +0 -1
  45. package/dist/prompts/analyze/code-quality.d.ts +0 -116
  46. package/dist/prompts/analyze/code-quality.d.ts.map +0 -1
  47. package/dist/prompts/analyze/code-quality.js +0 -437
  48. package/dist/prompts/analyze/code-quality.js.map +0 -1
  49. package/dist/prompts/analyze/compare-integration.d.ts +0 -130
  50. package/dist/prompts/analyze/compare-integration.d.ts.map +0 -1
  51. package/dist/prompts/analyze/compare-integration.js +0 -547
  52. package/dist/prompts/analyze/compare-integration.js.map +0 -1
  53. package/dist/prompts/analyze/count-files.d.ts +0 -109
  54. package/dist/prompts/analyze/count-files.d.ts.map +0 -1
  55. package/dist/prompts/analyze/count-files.js +0 -403
  56. package/dist/prompts/analyze/count-files.js.map +0 -1
  57. package/dist/prompts/analyze/database-queries.d.ts +0 -156
  58. package/dist/prompts/analyze/database-queries.d.ts.map +0 -1
  59. package/dist/prompts/analyze/database-queries.js +0 -763
  60. package/dist/prompts/analyze/database-queries.js.map +0 -1
  61. package/dist/prompts/analyze/dependencies.d.ts +0 -97
  62. package/dist/prompts/analyze/dependencies.d.ts.map +0 -1
  63. package/dist/prompts/analyze/dependencies.js +0 -337
  64. package/dist/prompts/analyze/dependencies.js.map +0 -1
  65. package/dist/prompts/analyze/diff-signatures.d.ts +0 -139
  66. package/dist/prompts/analyze/diff-signatures.d.ts.map +0 -1
  67. package/dist/prompts/analyze/diff-signatures.js +0 -708
  68. package/dist/prompts/analyze/diff-signatures.js.map +0 -1
  69. package/dist/prompts/analyze/find-patterns.d.ts +0 -128
  70. package/dist/prompts/analyze/find-patterns.d.ts.map +0 -1
  71. package/dist/prompts/analyze/find-patterns.js +0 -524
  72. package/dist/prompts/analyze/find-patterns.js.map +0 -1
  73. package/dist/prompts/analyze/find-unused-css.d.ts +0 -151
  74. package/dist/prompts/analyze/find-unused-css.d.ts.map +0 -1
  75. package/dist/prompts/analyze/find-unused-css.js +0 -760
  76. package/dist/prompts/analyze/find-unused-css.js.map +0 -1
  77. package/dist/prompts/analyze/n8n-workflow.d.ts +0 -137
  78. package/dist/prompts/analyze/n8n-workflow.d.ts.map +0 -1
  79. package/dist/prompts/analyze/n8n-workflow.js +0 -533
  80. package/dist/prompts/analyze/n8n-workflow.js.map +0 -1
  81. package/dist/prompts/analyze/project-structure.d.ts +0 -126
  82. package/dist/prompts/analyze/project-structure.d.ts.map +0 -1
  83. package/dist/prompts/analyze/project-structure.js +0 -573
  84. package/dist/prompts/analyze/project-structure.js.map +0 -1
  85. package/dist/prompts/analyze/security-audit.d.ts +0 -142
  86. package/dist/prompts/analyze/security-audit.d.ts.map +0 -1
  87. package/dist/prompts/analyze/security-audit.js +0 -641
  88. package/dist/prompts/analyze/security-audit.js.map +0 -1
  89. package/dist/prompts/analyze/single-file.d.ts +0 -162
  90. package/dist/prompts/analyze/single-file.d.ts.map +0 -1
  91. package/dist/prompts/analyze/single-file.js +0 -669
  92. package/dist/prompts/analyze/single-file.js.map +0 -1
  93. package/dist/prompts/analyze/trace-execution.d.ts +0 -126
  94. package/dist/prompts/analyze/trace-execution.d.ts.map +0 -1
  95. package/dist/prompts/analyze/trace-execution.js +0 -613
  96. package/dist/prompts/analyze/trace-execution.js.map +0 -1
  97. package/dist/prompts/analyze/wordpress-plugin-audit.d.ts +0 -116
  98. package/dist/prompts/analyze/wordpress-plugin-audit.d.ts.map +0 -1
  99. package/dist/prompts/analyze/wordpress-plugin-audit.js +0 -456
  100. package/dist/prompts/analyze/wordpress-plugin-audit.js.map +0 -1
  101. package/dist/prompts/analyze/wordpress-plugin-readiness.d.ts +0 -103
  102. package/dist/prompts/analyze/wordpress-plugin-readiness.d.ts.map +0 -1
  103. package/dist/prompts/analyze/wordpress-plugin-readiness.js +0 -506
  104. package/dist/prompts/analyze/wordpress-plugin-readiness.js.map +0 -1
  105. package/dist/prompts/analyze/wordpress-security.d.ts +0 -146
  106. package/dist/prompts/analyze/wordpress-security.d.ts.map +0 -1
  107. package/dist/prompts/analyze/wordpress-security.js +0 -702
  108. package/dist/prompts/analyze/wordpress-security.js.map +0 -1
  109. package/dist/prompts/analyze/wordpress-theme-audit.d.ts +0 -114
  110. package/dist/prompts/analyze/wordpress-theme-audit.d.ts.map +0 -1
  111. package/dist/prompts/analyze/wordpress-theme-audit.js +0 -540
  112. package/dist/prompts/analyze/wordpress-theme-audit.js.map +0 -1
  113. package/dist/prompts/custom/custom-prompt.d.ts +0 -135
  114. package/dist/prompts/custom/custom-prompt.d.ts.map +0 -1
  115. package/dist/prompts/custom/custom-prompt.js +0 -421
  116. package/dist/prompts/custom/custom-prompt.js.map +0 -1
  117. package/dist/prompts/fun/arcade-game.d.ts +0 -152
  118. package/dist/prompts/fun/arcade-game.d.ts.map +0 -1
  119. package/dist/prompts/fun/arcade-game.js +0 -657
  120. package/dist/prompts/fun/arcade-game.js.map +0 -1
  121. package/dist/prompts/fun/create_text_adventure.d.ts +0 -100
  122. package/dist/prompts/fun/create_text_adventure.d.ts.map +0 -1
  123. package/dist/prompts/fun/create_text_adventure.js +0 -401
  124. package/dist/prompts/fun/create_text_adventure.js.map +0 -1
  125. package/dist/prompts/fun/css-art-generator.d.ts +0 -168
  126. package/dist/prompts/fun/css-art-generator.d.ts.map +0 -1
  127. package/dist/prompts/fun/css-art-generator.js +0 -831
  128. package/dist/prompts/fun/css-art-generator.js.map +0 -1
  129. package/dist/prompts/generate/project-documentation.d.ts +0 -137
  130. package/dist/prompts/generate/project-documentation.d.ts.map +0 -1
  131. package/dist/prompts/generate/project-documentation.js +0 -670
  132. package/dist/prompts/generate/project-documentation.js.map +0 -1
  133. package/dist/prompts/generate/refactoring.d.ts +0 -164
  134. package/dist/prompts/generate/refactoring.d.ts.map +0 -1
  135. package/dist/prompts/generate/refactoring.js +0 -625
  136. package/dist/prompts/generate/refactoring.js.map +0 -1
  137. package/dist/prompts/generate/responsive-component.d.ts +0 -147
  138. package/dist/prompts/generate/responsive-component.d.ts.map +0 -1
  139. package/dist/prompts/generate/responsive-component.js +0 -957
  140. package/dist/prompts/generate/responsive-component.js.map +0 -1
  141. package/dist/prompts/generate/typescript-conversion.d.ts +0 -144
  142. package/dist/prompts/generate/typescript-conversion.d.ts.map +0 -1
  143. package/dist/prompts/generate/typescript-conversion.js +0 -531
  144. package/dist/prompts/generate/typescript-conversion.js.map +0 -1
  145. package/dist/prompts/generate/unit-tests.d.ts +0 -139
  146. package/dist/prompts/generate/unit-tests.d.ts.map +0 -1
  147. package/dist/prompts/generate/unit-tests.js +0 -582
  148. package/dist/prompts/generate/unit-tests.js.map +0 -1
  149. package/dist/prompts/generate/wordpress-plugin.d.ts +0 -179
  150. package/dist/prompts/generate/wordpress-plugin.d.ts.map +0 -1
  151. package/dist/prompts/generate/wordpress-plugin.js +0 -767
  152. package/dist/prompts/generate/wordpress-plugin.js.map +0 -1
  153. package/dist/prompts/generate/wordpress-theme-from-static.d.ts +0 -177
  154. package/dist/prompts/generate/wordpress-theme-from-static.d.ts.map +0 -1
  155. package/dist/prompts/generate/wordpress-theme-from-static.js +0 -699
  156. package/dist/prompts/generate/wordpress-theme-from-static.js.map +0 -1
  157. package/dist/prompts/shared/cache-manager.d.ts +0 -45
  158. package/dist/prompts/shared/cache-manager.d.ts.map +0 -1
  159. package/dist/prompts/shared/cache-manager.js +0 -129
  160. package/dist/prompts/shared/cache-manager.js.map +0 -1
  161. package/dist/prompts/shared/helpers.d.ts +0 -39
  162. package/dist/prompts/shared/helpers.d.ts.map +0 -1
  163. package/dist/prompts/shared/helpers.js +0 -151
  164. package/dist/prompts/shared/helpers.js.map +0 -1
  165. package/dist/prompts/shared/templates.d.ts +0 -35
  166. package/dist/prompts/shared/templates.d.ts.map +0 -1
  167. package/dist/prompts/shared/templates.js +0 -77
  168. package/dist/prompts/shared/templates.js.map +0 -1
  169. package/dist/prompts/shared/types.d.ts +0 -112
  170. package/dist/prompts/shared/types.d.ts.map +0 -1
  171. package/dist/prompts/shared/types.js +0 -5
  172. package/dist/prompts/shared/types.js.map +0 -1
  173. package/dist/prompts/system/find-unused-files.d.ts +0 -106
  174. package/dist/prompts/system/find-unused-files.d.ts.map +0 -1
  175. package/dist/prompts/system/find-unused-files.js +0 -357
  176. package/dist/prompts/system/find-unused-files.js.map +0 -1
  177. package/dist/security/index.d.ts +0 -39
  178. package/dist/security/index.d.ts.map +0 -1
  179. package/dist/security/index.js +0 -46
  180. package/dist/security/index.js.map +0 -1
  181. package/dist/security/integration-helpers.d.ts +0 -121
  182. package/dist/security/integration-helpers.d.ts.map +0 -1
  183. package/dist/security/integration-helpers.js +0 -190
  184. package/dist/security/integration-helpers.js.map +0 -1
  185. package/dist/security/output-encoder.d.ts +0 -94
  186. package/dist/security/output-encoder.d.ts.map +0 -1
  187. package/dist/security/output-encoder.js +0 -295
  188. package/dist/security/output-encoder.js.map +0 -1
  189. package/dist/security/prompt-injection-guard.d.ts +0 -59
  190. package/dist/security/prompt-injection-guard.d.ts.map +0 -1
  191. package/dist/security/prompt-injection-guard.js +0 -249
  192. package/dist/security/prompt-injection-guard.js.map +0 -1
  193. package/dist/security/sanitisation.d.ts +0 -67
  194. package/dist/security/sanitisation.d.ts.map +0 -1
  195. package/dist/security/sanitisation.js +0 -398
  196. package/dist/security/sanitisation.js.map +0 -1
  197. package/dist/security/security-service.d.ts +0 -103
  198. package/dist/security/security-service.d.ts.map +0 -1
  199. package/dist/security/security-service.js +0 -303
  200. package/dist/security/security-service.js.map +0 -1
  201. package/dist/security-config.d.ts +0 -45
  202. package/dist/security-config.d.ts.map +0 -1
  203. package/dist/security-config.js +0 -63
  204. package/dist/security-config.js.map +0 -1
  205. package/dist/system/function-list.d.ts +0 -61
  206. package/dist/system/function-list.d.ts.map +0 -1
  207. package/dist/system/function-list.js +0 -111
  208. package/dist/system/function-list.js.map +0 -1
  209. package/dist/system/function-registry.d.ts +0 -23
  210. package/dist/system/function-registry.d.ts.map +0 -1
  211. package/dist/system/function-registry.js +0 -136
  212. package/dist/system/function-registry.js.map +0 -1
  213. package/dist/system/health-check.d.ts +0 -33
  214. package/dist/system/health-check.d.ts.map +0 -1
  215. package/dist/system/health-check.js +0 -98
  216. package/dist/system/health-check.js.map +0 -1
  217. package/dist/system/path-resolver.d.ts +0 -55
  218. package/dist/system/path-resolver.d.ts.map +0 -1
  219. package/dist/system/path-resolver.js +0 -90
  220. package/dist/system/path-resolver.js.map +0 -1
  221. package/dist/templates/plugin-template.d.ts +0 -121
  222. package/dist/templates/plugin-template.d.ts.map +0 -1
  223. package/dist/templates/plugin-template.js +0 -454
  224. package/dist/templates/plugin-template.js.map +0 -1
  225. package/dist/types/chunking-types.d.ts +0 -88
  226. package/dist/types/chunking-types.d.ts.map +0 -1
  227. package/dist/types/chunking-types.js +0 -18
  228. package/dist/types/chunking-types.js.map +0 -1
  229. package/dist/types/prompt-stages.d.ts +0 -30
  230. package/dist/types/prompt-stages.d.ts.map +0 -1
  231. package/dist/types/prompt-stages.js +0 -6
  232. package/dist/types/prompt-stages.js.map +0 -1
  233. package/dist/types.d.ts +0 -45
  234. package/dist/types.d.ts.map +0 -1
  235. package/dist/types.js +0 -6
  236. package/dist/types.js.map +0 -1
  237. package/dist/utils/css-parser.d.ts +0 -26
  238. package/dist/utils/css-parser.d.ts.map +0 -1
  239. package/dist/utils/css-parser.js +0 -117
  240. package/dist/utils/css-parser.js.map +0 -1
  241. package/dist/utils/path-resolver.d.ts +0 -13
  242. package/dist/utils/path-resolver.d.ts.map +0 -1
  243. package/dist/utils/path-resolver.js +0 -78
  244. package/dist/utils/path-resolver.js.map +0 -1
  245. package/dist/utils/plugin-utilities.d.ts +0 -176
  246. package/dist/utils/plugin-utilities.d.ts.map +0 -1
  247. package/dist/utils/plugin-utilities.js +0 -269
  248. package/dist/utils/plugin-utilities.js.map +0 -1
  249. package/dist/utils/streamHandler.d.ts +0 -3
  250. package/dist/utils/streamHandler.d.ts.map +0 -1
  251. package/dist/utils/streamHandler.js +0 -137
  252. package/dist/utils/streamHandler.js.map +0 -1
  253. package/dist/validation/output-validator.d.ts +0 -136
  254. package/dist/validation/output-validator.d.ts.map +0 -1
  255. package/dist/validation/output-validator.js +0 -262
  256. package/dist/validation/output-validator.js.map +0 -1
  257. package/dist/validation/response-factory.d.ts +0 -44
  258. package/dist/validation/response-factory.d.ts.map +0 -1
  259. package/dist/validation/response-factory.js +0 -202
  260. package/dist/validation/response-factory.js.map +0 -1
  261. package/dist/validation/schemas.d.ts +0 -519
  262. package/dist/validation/schemas.d.ts.map +0 -1
  263. package/dist/validation/schemas.js +0 -6
  264. 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 - Plugin Architecture v1.0
4
- * Complete plugin-based replacement of legacy switch-case system
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, ListResourcesRequestSchema, ListPromptsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
9
- import { LMStudioClient } from '@lmstudio/sdk';
10
- import path from 'path';
11
- import { fileURLToPath } from 'url';
12
- import { dirname } from 'path';
13
- import { pathToFileURL } from 'url';
14
- import fs from 'fs';
15
- import { config } from './config.js';
16
- import { PluginRegistry } from './plugins/index.js';
17
- // ES module __dirname equivalent
18
- const __filename = fileURLToPath(import.meta.url);
19
- const __dirname = dirname(__filename);
20
- class HoutiniLMServer {
21
- constructor() {
22
- this.pluginsInitialized = false;
23
- this.server = new Server({
24
- name: 'houtini-lm',
25
- version: '1.0.7',
26
- description: 'Local AI development companion - unlimited analysis and generation without API costs. Preserves Claude context by offloading routine tasks to local LM Studio.',
27
- }, {
28
- capabilities: {
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
- * Load system plugins from the system directory
108
- */
109
- async loadSystemPlugins() {
110
- try {
111
- const systemDir = path.join(__dirname, 'system');
112
- const files = fs.readdirSync(systemDir);
113
- for (const file of files) {
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
- * Load a single system plugin
127
- */
128
- async loadSystemPlugin(filePath) {
129
- try {
130
- // Use ES module dynamic import with proper URL
131
- const fileUrl = pathToFileURL(filePath).href;
132
- const module = await import(fileUrl);
133
- const PluginClass = module.default || module.HealthCheckPlugin || module.PathResolverPlugin || Object.values(module)[0];
134
- if (PluginClass && typeof PluginClass === 'function') {
135
- const plugin = new PluginClass();
136
- this.pluginLoader.registerPlugin(plugin);
137
- // Removed console.log to avoid JSON-RPC interference
138
- }
139
- }
140
- catch (error) {
141
- // Silent error handling to avoid JSON-RPC interference
142
- // console.error(`[Plugin Server] Error loading system plugin ${filePath}:`, error);
143
- }
144
- }
145
- /**
146
- * Setup MCP request handlers
147
- */
148
- setupHandlers() {
149
- // Tool listing handler - returns plugin-generated tool definitions
150
- this.server.setRequestHandler(ListToolsRequestSchema, async () => {
151
- if (!this.pluginsInitialized) {
152
- await this.initializePlugins();
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
- const tools = this.pluginLoader.getPlugins().map(plugin => plugin.getToolDefinition());
155
- // Silent operation - no console output
156
- return { tools };
157
- });
158
- // Resources handler (empty for now)
159
- this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
160
- resources: [],
161
- }));
162
- // Prompts handler (empty for now)
163
- this.server.setRequestHandler(ListPromptsRequestSchema, async () => ({
164
- prompts: [],
165
- }));
166
- // Main tool handler - routes all calls through plugin system
167
- this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
168
- const { name: toolName, arguments: args } = request.params;
169
- // Silent operation - no console output unless error
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
- try {
174
- // Strip the houtini-lm: prefix to get the actual plugin name
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: typeof result === 'string' ? result : JSON.stringify(result, null, 2)
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
- catch (error) {
190
- // Silent error handling - only return error response without logging
191
- // Return error as MCP response
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: JSON.stringify({
197
- error: true,
198
- message: error.message || 'Tool execution failed',
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
- totalPlugins: plugins.length,
220
- categories,
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
- * Start the server
226
- */
227
- async start() {
228
- // SECURITY: Validate configuration before starting server
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
- // Start the server
237
- const server = new HoutiniLMServer();
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":"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"}
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": "1.0.13",
3
+ "version": "2.0.1",
4
4
  "type": "module",
5
- "description": "Houtini LM - LM Studio MCP Server with Expert Prompt Library and Custom Prompting",
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
- "test:connection": "node test-connection.mjs",
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
- "claude-mcp",
19
+ "mcp-server",
30
20
  "lm-studio",
31
- "ai-development",
32
- "code-generation",
33
- "unlimited-tokens",
34
- "context-preservation",
35
- "local-ai"
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
- "@lmstudio/sdk": "^1.5.0",
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": "^20.11.0",
55
- "@jest/globals": "^29.7.0",
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
+ }