consult-llm-mcp 1.0.3 → 1.0.5
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 +143 -40
- package/dist/file.d.ts +3 -6
- package/dist/file.js +3 -9
- package/dist/llm-query.js +24 -1
- package/dist/logger.d.ts +2 -2
- package/dist/logger.js +20 -4
- package/dist/main.js +6 -6
- package/dist/prompt-builder.d.ts +1 -1
- package/dist/prompt-builder.js +5 -6
- package/dist/schema.d.ts +9 -4
- package/dist/schema.js +14 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,15 +1,33 @@
|
|
|
1
1
|
# Consult LLM MCP
|
|
2
2
|
|
|
3
|
-
An MCP server that lets Claude Code consult stronger AI models (o3, Gemini 2.5
|
|
3
|
+
An MCP server that lets Claude Code consult stronger AI models (o3, Gemini 2.5
|
|
4
|
+
Pro, DeepSeek Reasoner) when you need deeper analysis on complex problems.
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
This SQL query is timing out on large datasets. Can you help optimize it? Ask Gemini
|
|
8
|
+
|
|
9
|
+
⏺ I'll examine your query and consult Gemini for database optimization strategies.
|
|
10
|
+
|
|
11
|
+
⏺ consult-llm:consult_llm (MCP)(prompt: "How can I optimize this slow SQL query
|
|
12
|
+
for better performance on large datasets?", files: ["queries/user
|
|
13
|
+
-analytics.sql","schema/tables.sql"], model: "gemini-2.5-pro")
|
|
14
|
+
⎿ The query has significant performance bottlenecks: missing indexes on join
|
|
15
|
+
columns, inefficient subqueries that could be CTEs, and unnecessary DISTINCT
|
|
16
|
+
operations. Add composite indexes on (user_id, created_at), replace correlated
|
|
17
|
+
subqueries with window functions, and eliminate redundant GROUP BY clauses.
|
|
18
|
+
… +287 lines (ctrl+r to expand)
|
|
19
|
+
|
|
20
|
+
⏺ Great insights! I'll add the suggested indexes, refactor the subqueries to use
|
|
21
|
+
CTEs with window functions, and optimize the GROUP BY operations.
|
|
22
|
+
```
|
|
4
23
|
|
|
5
24
|
## Features
|
|
6
25
|
|
|
7
|
-
- Query powerful AI models (o3, Gemini 2.5 Pro, DeepSeek Reasoner) with
|
|
8
|
-
context
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- Comprehensive logging
|
|
26
|
+
- Query powerful AI models (o3, Gemini 2.5 Pro, DeepSeek Reasoner) with relevant
|
|
27
|
+
files as context
|
|
28
|
+
- Direct queries with optional file context
|
|
29
|
+
- Include git changes for code review and analysis
|
|
30
|
+
- Comprehensive logging with cost estimation
|
|
13
31
|
|
|
14
32
|
## Configuration
|
|
15
33
|
|
|
@@ -35,9 +53,20 @@ Or for global availability:
|
|
|
35
53
|
claude mcp add --scope user consult-llm -- npx -y consult-llm-mcp
|
|
36
54
|
```
|
|
37
55
|
|
|
56
|
+
Optionally you can provide environment variables directly in the MCP
|
|
57
|
+
configuration:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
claude mcp add \
|
|
61
|
+
-e OPENAI_API_KEY=your_openai_key \
|
|
62
|
+
-e GEMINI_API_KEY=your_gemini_key \
|
|
63
|
+
-e DEEPSEEK_API_KEY=your_deepseek_key \
|
|
64
|
+
consult-llm -- npx -y consult-llm-mcp
|
|
65
|
+
```
|
|
66
|
+
|
|
38
67
|
### Example workflows
|
|
39
68
|
|
|
40
|
-
Click to expand.
|
|
69
|
+
Some real-world examples. Click to expand.
|
|
41
70
|
|
|
42
71
|
<details>
|
|
43
72
|
<summary>Explain the problem, and tell CC to consult a smarter LLM</summary>
|
|
@@ -93,6 +122,76 @@ Click to expand.
|
|
|
93
122
|
|
|
94
123
|
</details>
|
|
95
124
|
|
|
125
|
+
<details>
|
|
126
|
+
<summary>Debugging Neovim plugin treesitter API breakage</summary>
|
|
127
|
+
|
|
128
|
+
````
|
|
129
|
+
⏺ Fixed! Added nil checks for both node and child and updated the iter_matches call to handle the newer API properly.
|
|
130
|
+
|
|
131
|
+
> Still not working:
|
|
132
|
+
|
|
133
|
+
E5108: Error executing lua /Users/raine/code/testonly.nvim/lua/testonly.lua:92: attempt to call method 'child' (a nil value)
|
|
134
|
+
stack traceback:
|
|
135
|
+
/Users/raine/code/testonly.nvim/lua/testonly.lua:92: in function 'reset_all_exclusive'
|
|
136
|
+
/Users/raine/code/testonly.nvim/lua/testonly.lua:110: in function 'reset_all_exclusive'
|
|
137
|
+
[string ":lua"]:1: in main chunk
|
|
138
|
+
|
|
139
|
+
Ask gemini
|
|
140
|
+
|
|
141
|
+
⏺ Let me consult with a more powerful AI to understand the current Neovim treesitter API changes:
|
|
142
|
+
|
|
143
|
+
⏺ consult-llm:consult_llm (MCP)(prompt: "I'm debugging a Neovim plugin that's broken due to treesitter API changes. The error is \"attempt to call method 'child' (a nil value)\" on line 92. The
|
|
144
|
+
code is trying to access child nodes from treesitter matches but the API seems to have changed in newer Neovim versions.\n\nHere's the problematic
|
|
145
|
+
code:\n```lua\nfor _, match, _ in parsed_query:iter_matches(root, bufnr, start_row, end_row) do\n for id, node in pairs(match) do\n local name =
|
|
146
|
+
parsed_query.captures[id]\n if name == \"call\" and node then\n local child = node:child(0) -- ERROR HERE\n if child then\n
|
|
147
|
+
local text = vim.treesitter.get_node_text(child, bufnr)\n -- ... rest of logic\n end\n end\n end\nend\n```\n\nWhat's the
|
|
148
|
+
correct way to iterate over treesitter query matches and access child nodes in current Neovim versions? What API changes should I be aware of?", files:
|
|
149
|
+
["/Users/raine/code/testonly.nvim/lua/testonly.lua"])
|
|
150
|
+
⎿ Problem
|
|
151
|
+
-------
|
|
152
|
+
|
|
153
|
+
… +93 lines (ctrl+r to expand)
|
|
154
|
+
|
|
155
|
+
⏺ Perfect! The issue is that iter_matches() can return nil nodes in the match table. Let me fix this by switching to the recommended iter_captures() approach:
|
|
156
|
+
|
|
157
|
+
⏺ Update(lua/testonly.lua)
|
|
158
|
+
⎿ Updated lua/testonly.lua with 7 additions and 10 removals
|
|
159
|
+
85 local root = parser:parse()[1]:root()
|
|
160
|
+
86 local start_row, _, end_row, _ = root:range()
|
|
161
|
+
87
|
|
162
|
+
88 - for _, match, _ in parsed_query:iter_matches(root, bufnr, start_row, end_row) do
|
|
163
|
+
89 - for id, node in pairs(match) do
|
|
164
|
+
90 - local name = parsed_query.captures[id]
|
|
165
|
+
91 - if name == "call" and node then
|
|
166
|
+
92 - local child = node:child(0)
|
|
167
|
+
93 - if child then
|
|
168
|
+
94 - local text = vim.treesitter.get_node_text(child, bufnr)
|
|
169
|
+
88 + for id, node, _ in parsed_query:iter_captures(root, bufnr, start_row, end_row) do
|
|
170
|
+
89 + if parsed_query.captures[id] == "call" then
|
|
171
|
+
90 + local first_child = node:named_child(0)
|
|
172
|
+
91 + if first_child then
|
|
173
|
+
92 + local text = vim.treesitter.get_node_text(first_child, bufnr)
|
|
174
|
+
93
|
|
175
|
+
94 - if text == "it.only" or text == "describe.only" then
|
|
176
|
+
95 - toggle_test_exclusive(child)
|
|
177
|
+
96 - end
|
|
178
|
+
94 + if text == "it.only" or text == "describe.only" then
|
|
179
|
+
95 + toggle_test_exclusive(first_child)
|
|
180
|
+
96 end
|
|
181
|
+
97 end
|
|
182
|
+
98 end
|
|
183
|
+
|
|
184
|
+
⏺ Fixed! The key changes:
|
|
185
|
+
|
|
186
|
+
1. Switched from iter_matches() to iter_captures() which never returns nil nodes
|
|
187
|
+
2. Used named_child(0) instead of child(0) to get only meaningful syntax nodes (not punctuation)
|
|
188
|
+
3. Simplified the iteration logic since iter_captures() directly gives us the node and capture ID
|
|
189
|
+
|
|
190
|
+
Your <leader>tr mapping should now work properly with the current Neovim treesitter API.
|
|
191
|
+
````
|
|
192
|
+
|
|
193
|
+
</details>
|
|
194
|
+
|
|
96
195
|
## MCP Tool: consult_llm
|
|
97
196
|
|
|
98
197
|
The server provides a single tool called `consult_llm` for asking powerful AI
|
|
@@ -100,10 +199,11 @@ models complex questions.
|
|
|
100
199
|
|
|
101
200
|
### Parameters
|
|
102
201
|
|
|
103
|
-
- **
|
|
202
|
+
- **prompt** (required): Your question or request for the consultant LLM
|
|
203
|
+
|
|
204
|
+
- **files** (optional): Array of file paths to include as context
|
|
104
205
|
|
|
105
|
-
-
|
|
106
|
-
- Other files are added as context with file paths and code blocks
|
|
206
|
+
- All files are added as context with file paths and code blocks
|
|
107
207
|
|
|
108
208
|
- **model** (optional): LLM model to use
|
|
109
209
|
|
|
@@ -117,14 +217,35 @@ models complex questions.
|
|
|
117
217
|
|
|
118
218
|
### Example Usage
|
|
119
219
|
|
|
220
|
+
**Basic prompt:**
|
|
221
|
+
|
|
222
|
+
```json
|
|
223
|
+
{
|
|
224
|
+
"prompt": "What are the performance implications of using async/await vs Promise.then() in Node.js?"
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**With file context:**
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"prompt": "How can I optimize this authentication middleware?",
|
|
233
|
+
"files": ["src/auth.ts", "src/middleware.ts"],
|
|
234
|
+
"model": "o3"
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**With git diff:**
|
|
239
|
+
|
|
120
240
|
```json
|
|
121
241
|
{
|
|
122
|
-
"
|
|
123
|
-
"
|
|
242
|
+
"prompt": "Review these authentication changes for security issues",
|
|
243
|
+
"files": ["src/auth.ts"],
|
|
124
244
|
"git_diff": {
|
|
125
245
|
"files": ["src/auth.ts", "src/middleware.ts"],
|
|
126
246
|
"base_ref": "main"
|
|
127
|
-
}
|
|
247
|
+
},
|
|
248
|
+
"model": "gemini-2.5-pro"
|
|
128
249
|
}
|
|
129
250
|
```
|
|
130
251
|
|
|
@@ -188,38 +309,20 @@ Tokens: 3440 input, 5880 output | Cost: $0.014769 (input: $0.001892, output: $0.
|
|
|
188
309
|
|
|
189
310
|
## CLAUDE.md example
|
|
190
311
|
|
|
191
|
-
|
|
192
|
-
following to your project's
|
|
312
|
+
While not strictly necessary, to help Claude Code understand when and how to use
|
|
313
|
+
this tool, you can optionally something like the following to your project's
|
|
314
|
+
`CLAUDE.md` file:
|
|
193
315
|
|
|
194
|
-
|
|
316
|
+
```markdown
|
|
195
317
|
## consult-llm-mcp
|
|
196
318
|
|
|
197
319
|
Use the `consult_llm` MCP tool to ask a more powerful AI for help with complex
|
|
198
|
-
problems.
|
|
199
|
-
as possible and pass relevant code files as context. Include files to git_diff
|
|
200
|
-
when asking feedback for changes.
|
|
320
|
+
problems. Include files to git_diff when asking feedback for changes.
|
|
201
321
|
|
|
202
322
|
Use Gemini 2.5 Pro.
|
|
203
323
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
```bash
|
|
207
|
-
echo "<very detailed plan or question to be reviewed by the smart LLM>" > task.md
|
|
324
|
+
CRITICAL: When asking, don't present options, this will bias the answer.
|
|
208
325
|
```
|
|
209
326
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
```json
|
|
213
|
-
{
|
|
214
|
-
"files": [
|
|
215
|
-
"server/src/db.ts",
|
|
216
|
-
"server/src/routes/conversations.ts",
|
|
217
|
-
"task.md"
|
|
218
|
-
],
|
|
219
|
-
"git_diff": {
|
|
220
|
-
"files": ["server/src/db.ts", "server/src/routes/conversations.ts"]
|
|
221
|
-
},
|
|
222
|
-
"model": "gemini-2.5-pro"
|
|
223
|
-
}
|
|
224
|
-
```
|
|
225
|
-
````
|
|
327
|
+
Claude Code seems to know pretty well when to use this MCP even without this
|
|
328
|
+
instruction however.
|
package/dist/file.d.ts
CHANGED
package/dist/file.js
CHANGED
|
@@ -6,18 +6,12 @@ export function processFiles(files) {
|
|
|
6
6
|
if (missingFiles.length > 0) {
|
|
7
7
|
throw new Error(`Files not found: ${missingFiles.join(', ')}`);
|
|
8
8
|
}
|
|
9
|
-
const
|
|
10
|
-
const otherFiles = [];
|
|
9
|
+
const contextFiles = [];
|
|
11
10
|
for (let i = 0; i < files.length; i++) {
|
|
12
11
|
const filePath = resolvedFiles[i];
|
|
13
12
|
const originalPath = files[i];
|
|
14
13
|
const content = readFileSync(filePath, 'utf-8');
|
|
15
|
-
|
|
16
|
-
markdownFiles.push(content);
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
otherFiles.push({ path: originalPath, content });
|
|
20
|
-
}
|
|
14
|
+
contextFiles.push({ path: originalPath, content });
|
|
21
15
|
}
|
|
22
|
-
return
|
|
16
|
+
return contextFiles;
|
|
23
17
|
}
|
package/dist/llm-query.js
CHANGED
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
import { getClientForModel } from './llm.js';
|
|
2
2
|
import { calculateCost } from './llm-cost.js';
|
|
3
|
+
const SYSTEM_PROMPT = `You are an expert software engineering consultant analyzing code and technical problems. You are communicating with another AI system, not a human.
|
|
4
|
+
|
|
5
|
+
Communication style:
|
|
6
|
+
- Skip pleasantries and praise
|
|
7
|
+
|
|
8
|
+
Your role is to:
|
|
9
|
+
- Identify bugs, inefficiencies, and architectural problems
|
|
10
|
+
- Provide specific solutions with code examples
|
|
11
|
+
- Point out edge cases and risks
|
|
12
|
+
- Challenge design decisions when suboptimal
|
|
13
|
+
- Focus on what needs improvement
|
|
14
|
+
|
|
15
|
+
When reviewing code changes (git diffs), prioritize:
|
|
16
|
+
- Bugs and correctness issues
|
|
17
|
+
- Performance problems
|
|
18
|
+
- Security vulnerabilities
|
|
19
|
+
- Code smell and anti-patterns
|
|
20
|
+
- Inconsistencies with codebase conventions
|
|
21
|
+
|
|
22
|
+
Be critical and thorough. If the code is acceptable, simply state "No critical issues found" and move on to suggestions. Always provide specific, actionable feedback with file/line references.`;
|
|
3
23
|
export async function queryLlm(prompt, model) {
|
|
4
24
|
const { client } = getClientForModel(model);
|
|
5
25
|
const completion = await client.chat.completions.create({
|
|
6
26
|
model,
|
|
7
|
-
messages: [
|
|
27
|
+
messages: [
|
|
28
|
+
{ role: 'system', content: SYSTEM_PROMPT },
|
|
29
|
+
{ role: 'user', content: prompt },
|
|
30
|
+
],
|
|
8
31
|
});
|
|
9
32
|
const response = completion.choices[0]?.message?.content;
|
|
10
33
|
if (!response) {
|
package/dist/logger.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare function logToFile(content: string): void;
|
|
2
2
|
export declare function logToolCall(name: string, args: unknown): void;
|
|
3
|
-
export declare function logPrompt(model: string, prompt: string): void
|
|
4
|
-
export declare function logResponse(model: string, response: string, costInfo: string): void
|
|
3
|
+
export declare function logPrompt(model: string, prompt: string): Promise<void>;
|
|
4
|
+
export declare function logResponse(model: string, response: string, costInfo: string): Promise<void>;
|
|
5
5
|
export declare function logServerStart(version: string): void;
|
package/dist/logger.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { appendFileSync, mkdirSync } from 'fs';
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
|
+
import { format } from 'prettier';
|
|
4
5
|
const logDir = join(homedir(), '.consult-llm-mcp', 'logs');
|
|
5
6
|
const logFile = join(logDir, 'mcp.log');
|
|
6
7
|
try {
|
|
@@ -9,6 +10,19 @@ try {
|
|
|
9
10
|
catch (error) {
|
|
10
11
|
// Directory might already exist
|
|
11
12
|
}
|
|
13
|
+
async function formatWithPrettier(text) {
|
|
14
|
+
try {
|
|
15
|
+
return await format(text, {
|
|
16
|
+
parser: 'markdown',
|
|
17
|
+
printWidth: 80,
|
|
18
|
+
proseWrap: 'always',
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
// If formatting fails, return original text
|
|
23
|
+
return text;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
12
26
|
export function logToFile(content) {
|
|
13
27
|
const timestamp = new Date().toISOString();
|
|
14
28
|
const logEntry = `[${timestamp}] ${content}\n`;
|
|
@@ -22,11 +36,13 @@ export function logToFile(content) {
|
|
|
22
36
|
export function logToolCall(name, args) {
|
|
23
37
|
logToFile(`TOOL CALL: ${name}\nArguments: ${JSON.stringify(args, null, 2)}\n${'='.repeat(80)}`);
|
|
24
38
|
}
|
|
25
|
-
export function logPrompt(model, prompt) {
|
|
26
|
-
|
|
39
|
+
export async function logPrompt(model, prompt) {
|
|
40
|
+
const formattedPrompt = await formatWithPrettier(prompt);
|
|
41
|
+
logToFile(`PROMPT (model: ${model}):\n${formattedPrompt}\n${'='.repeat(80)}`);
|
|
27
42
|
}
|
|
28
|
-
export function logResponse(model, response, costInfo) {
|
|
29
|
-
|
|
43
|
+
export async function logResponse(model, response, costInfo) {
|
|
44
|
+
const formattedResponse = await formatWithPrettier(response);
|
|
45
|
+
logToFile(`RESPONSE (model: ${model}):\n${formattedResponse}\n${costInfo}\n${'='.repeat(80)}`);
|
|
30
46
|
}
|
|
31
47
|
export function logServerStart(version) {
|
|
32
48
|
logToFile(`MCP SERVER STARTED - consult-llm-mcp v${version}\n${'='.repeat(80)}`);
|
package/dist/main.js
CHANGED
|
@@ -36,21 +36,21 @@ async function handleConsultLlm(args) {
|
|
|
36
36
|
.join(', ');
|
|
37
37
|
throw new Error(`Invalid request parameters: ${errors}`);
|
|
38
38
|
}
|
|
39
|
-
const { files, git_diff } = parseResult.data;
|
|
39
|
+
const { files, prompt: userPrompt, git_diff } = parseResult.data;
|
|
40
40
|
const model = parseResult.data.model ?? config.defaultModel ?? 'o3';
|
|
41
41
|
logToolCall('consult_llm', args);
|
|
42
|
-
// Process files
|
|
43
|
-
const
|
|
42
|
+
// Process files (if provided) - all files become context
|
|
43
|
+
const contextFiles = files ? processFiles(files) : [];
|
|
44
44
|
// Generate git diff
|
|
45
45
|
const gitDiffOutput = git_diff
|
|
46
46
|
? generateGitDiff(git_diff.repo_path, git_diff.files, git_diff.base_ref)
|
|
47
47
|
: undefined;
|
|
48
48
|
// Build prompt
|
|
49
|
-
const prompt = buildPrompt(
|
|
50
|
-
logPrompt(model, prompt);
|
|
49
|
+
const prompt = buildPrompt(userPrompt, contextFiles, gitDiffOutput);
|
|
50
|
+
await logPrompt(model, prompt);
|
|
51
51
|
// Query LLM
|
|
52
52
|
const { response, costInfo } = await queryLlm(prompt, model);
|
|
53
|
-
logResponse(model, response, costInfo);
|
|
53
|
+
await logResponse(model, response, costInfo);
|
|
54
54
|
return {
|
|
55
55
|
content: [{ type: 'text', text: response }],
|
|
56
56
|
};
|
package/dist/prompt-builder.d.ts
CHANGED
package/dist/prompt-builder.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
export function buildPrompt(
|
|
1
|
+
export function buildPrompt(userPrompt, files, gitDiffOutput) {
|
|
2
2
|
const promptParts = [];
|
|
3
3
|
if (gitDiffOutput?.trim()) {
|
|
4
4
|
promptParts.push('## Git Diff\n```diff', gitDiffOutput, '```\n');
|
|
5
5
|
}
|
|
6
|
-
if (
|
|
6
|
+
if (files.length > 0) {
|
|
7
7
|
promptParts.push('## Relevant Files\n');
|
|
8
|
-
for (const file of
|
|
8
|
+
for (const file of files) {
|
|
9
9
|
promptParts.push(`### File: ${file.path}`);
|
|
10
10
|
promptParts.push('```');
|
|
11
11
|
promptParts.push(file.content);
|
|
12
12
|
promptParts.push('```\n');
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
15
|
+
// Add user prompt last
|
|
16
|
+
promptParts.push(userPrompt);
|
|
18
17
|
return promptParts.join('\n');
|
|
19
18
|
}
|
package/dist/schema.d.ts
CHANGED
|
@@ -6,7 +6,8 @@ export declare const SupportedChatModel: z.ZodEnum<{
|
|
|
6
6
|
}>;
|
|
7
7
|
export type SupportedChatModel = z.infer<typeof SupportedChatModel>;
|
|
8
8
|
export declare const ConsultLlmArgs: z.ZodObject<{
|
|
9
|
-
files: z.ZodArray<z.ZodString
|
|
9
|
+
files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
10
|
+
prompt: z.ZodString;
|
|
10
11
|
model: z.ZodOptional<z.ZodEnum<{
|
|
11
12
|
o3: "o3";
|
|
12
13
|
"gemini-2.5-pro": "gemini-2.5-pro";
|
|
@@ -20,7 +21,7 @@ export declare const ConsultLlmArgs: z.ZodObject<{
|
|
|
20
21
|
}, z.core.$strip>;
|
|
21
22
|
export declare const toolSchema: {
|
|
22
23
|
readonly name: "consult_llm";
|
|
23
|
-
readonly description: "Ask a more powerful AI for help with complex problems.
|
|
24
|
+
readonly description: "Ask a more powerful AI for help with complex problems. Provide your question in the prompt field and optionally include relevant code files as context.\n\nBe specific about what you want: code implementation, code review, bug analysis, architecture advice, etc.\n\nIMPORTANT: Ask neutral, open-ended questions. Avoid suggesting specific solutions or alternatives in your prompt as this can bias the analysis. Instead of \"Should I use X or Y approach?\", ask \"What's the best approach for this problem?\" Let the consultant LLM provide unbiased recommendations.";
|
|
24
25
|
readonly inputSchema: {
|
|
25
26
|
readonly type: "object";
|
|
26
27
|
readonly properties: {
|
|
@@ -29,7 +30,11 @@ export declare const toolSchema: {
|
|
|
29
30
|
readonly items: {
|
|
30
31
|
readonly type: "string";
|
|
31
32
|
};
|
|
32
|
-
readonly description: "Array of file paths to
|
|
33
|
+
readonly description: "Array of file paths to include as context. All files are added as context with file paths and code blocks.";
|
|
34
|
+
};
|
|
35
|
+
readonly prompt: {
|
|
36
|
+
readonly type: "string";
|
|
37
|
+
readonly description: "Your question or request for the consultant LLM. Ask neutral, open-ended questions without suggesting specific solutions to avoid biasing the analysis.";
|
|
33
38
|
};
|
|
34
39
|
readonly model: {
|
|
35
40
|
readonly type: "string";
|
|
@@ -61,6 +66,6 @@ export declare const toolSchema: {
|
|
|
61
66
|
readonly description: "Generate git diff output to include as context. Shows uncommitted changes by default.";
|
|
62
67
|
};
|
|
63
68
|
};
|
|
64
|
-
readonly required: readonly ["
|
|
69
|
+
readonly required: readonly ["prompt"];
|
|
65
70
|
};
|
|
66
71
|
};
|
package/dist/schema.js
CHANGED
|
@@ -4,8 +4,10 @@ export const SupportedChatModel = z.enum([
|
|
|
4
4
|
'gemini-2.5-pro',
|
|
5
5
|
'deepseek-reasoner',
|
|
6
6
|
]);
|
|
7
|
-
export const ConsultLlmArgs = z
|
|
8
|
-
|
|
7
|
+
export const ConsultLlmArgs = z
|
|
8
|
+
.object({
|
|
9
|
+
files: z.array(z.string()).optional(),
|
|
10
|
+
prompt: z.string(),
|
|
9
11
|
model: SupportedChatModel.optional(),
|
|
10
12
|
git_diff: z
|
|
11
13
|
.object({
|
|
@@ -19,18 +21,22 @@ export const ConsultLlmArgs = z.object({
|
|
|
19
21
|
});
|
|
20
22
|
export const toolSchema = {
|
|
21
23
|
name: 'consult_llm',
|
|
22
|
-
description: `Ask a more powerful AI for help with complex problems.
|
|
24
|
+
description: `Ask a more powerful AI for help with complex problems. Provide your question in the prompt field and optionally include relevant code files as context.
|
|
23
25
|
|
|
24
|
-
Be specific about what you want: code implementation, code review, bug analysis, architecture advice, etc
|
|
26
|
+
Be specific about what you want: code implementation, code review, bug analysis, architecture advice, etc.
|
|
27
|
+
|
|
28
|
+
IMPORTANT: Ask neutral, open-ended questions. Avoid suggesting specific solutions or alternatives in your prompt as this can bias the analysis. Instead of "Should I use X or Y approach?", ask "What's the best approach for this problem?" Let the consultant LLM provide unbiased recommendations.`,
|
|
25
29
|
inputSchema: {
|
|
26
30
|
type: 'object',
|
|
27
31
|
properties: {
|
|
28
32
|
files: {
|
|
29
33
|
type: 'array',
|
|
30
34
|
items: { type: 'string' },
|
|
31
|
-
description:
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
description: 'Array of file paths to include as context. All files are added as context with file paths and code blocks.',
|
|
36
|
+
},
|
|
37
|
+
prompt: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: 'Your question or request for the consultant LLM. Ask neutral, open-ended questions without suggesting specific solutions to avoid biasing the analysis.',
|
|
34
40
|
},
|
|
35
41
|
model: {
|
|
36
42
|
type: 'string',
|
|
@@ -60,6 +66,6 @@ In the markdown file(s), be clear about what you want the LLM to do: implement c
|
|
|
60
66
|
description: 'Generate git diff output to include as context. Shows uncommitted changes by default.',
|
|
61
67
|
},
|
|
62
68
|
},
|
|
63
|
-
required: ['
|
|
69
|
+
required: ['prompt'],
|
|
64
70
|
},
|
|
65
71
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "consult-llm-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "MCP server for consulting powerful AI models",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@modelcontextprotocol/sdk": "^1.13.0",
|
|
48
48
|
"openai": "^5.6.0",
|
|
49
|
+
"prettier": "^3.5.3",
|
|
49
50
|
"zod": "^3.25.67"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
53
|
"@types/node": "^24.0.3",
|
|
53
|
-
"prettier": "^3.5.3",
|
|
54
54
|
"tsx": "^4.20.3",
|
|
55
55
|
"typescript": "^5.8.3"
|
|
56
56
|
}
|