consult-llm-mcp 1.2.0 → 1.3.0

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 CHANGED
@@ -32,6 +32,7 @@ This SQL query is timing out on large datasets. Can you help optimize it? Ask Ge
32
32
  - Gemini can be used via
33
33
  [Gemini CLI](https://github.com/google-gemini/gemini-cli) to take advantage of
34
34
  [free quota](https://developers.google.com/gemini-code-assist/resources/quotas#quotas-for-agent-mode-gemini-cli)
35
+ - Web mode: Copy formatted prompts to clipboard for browser-based LLM services
35
36
  - Simple: provides just one MCP tool to not clutter the context
36
37
 
37
38
  ## Usage with Claude Code
@@ -120,6 +121,53 @@ Some real-world examples. Click to expand.
120
121
 
121
122
  </details>
122
123
 
124
+ <details>
125
+ <summary>Using web mode to copy prompts to clipboard for browser-based LLMs</summary>
126
+
127
+ ```
128
+ > I need help implementing a -b/--background flag for my Rust CLI. Use consult LLM with web mode
129
+
130
+ ⏺ I'll use web mode to copy the formatted prompt to your clipboard so you can
131
+ paste it into any browser-based LLM service.
132
+
133
+ ⏺ consult-llm:consult_llm (MCP)(prompt: "What is the best approach to implement a
134
+ -b/--background flag for the \"workmux add\" command that
135
+ creates a tmux window in the background without switching to
136
+ it?\n\nThe current implementation automatically switches to
137
+ the newly created window via `tmux::select_window()` in the
138
+ `setup_environment()` function. I need to make this behavior
139
+ conditional based on a flag passed from the
140
+ CLI.\n\nConsider:\n1. Where should the background flag be
141
+ threaded through the call chain?\n2. Should I modify the
142
+ existing SetupOptions struct or add a parameter?\n3. What's
143
+ the most maintainable approach given the codebase
144
+ structure?\n4. Are there any edge cases to consider (e.g.,
145
+ should select_pane also be conditional)?", files:
146
+ ["src/cli.rs","src/workflow.rs","src/tmux.rs"], web_mode:
147
+ true)
148
+ ⎿ ✓ Prompt copied to clipboard!
149
+
150
+ Please paste it into your browser-based LLM service and share the response
151
+ here before I proceed with any implementation.
152
+
153
+ Note: File paths were included:
154
+ - src/cli.rs
155
+ - src/workflow.rs
156
+ - src/tmux.rs
157
+
158
+ > [User pastes the response from the external LLM]
159
+
160
+ ⏺ Thank you! Based on the recommendations, I'll now implement the solution...
161
+ ```
162
+
163
+ This is useful when:
164
+
165
+ - You want to use a free browser-based LLM service instead of API credits
166
+ - You prefer a specific LLM's web interface
167
+ - You want to review the full prompt before submitting it
168
+
169
+ </details>
170
+
123
171
  <details>
124
172
  <summary>Debugging Neovim plugin treesitter API breakage</summary>
125
173
 
@@ -236,6 +284,13 @@ models complex questions.
236
284
 
237
285
  - Options: `o3` (default), `gemini-2.5-pro`, `deepseek-reasoner`
238
286
 
287
+ - **web_mode** (optional): Copy prompt to clipboard instead of querying LLM
288
+
289
+ - Default: `false`
290
+ - When `true`, the formatted prompt (including system prompt and file
291
+ contents) is copied to clipboard for manual pasting into browser-based LLM
292
+ services
293
+
239
294
  - **git_diff** (optional): Include git diff output as context
240
295
  - **files** (required): Specific files to include in diff
241
296
  - **repo_path** (optional): Path to git repository (defaults to current
@@ -0,0 +1 @@
1
+ export declare function copyToClipboard(text: string): Promise<void>;
@@ -0,0 +1,10 @@
1
+ import clipboard from 'clipboardy';
2
+ export async function copyToClipboard(text) {
3
+ try {
4
+ await clipboard.write(text);
5
+ }
6
+ catch (error) {
7
+ const message = error instanceof Error ? error.message : 'Unknown clipboard error';
8
+ throw new Error(`Failed to copy prompt to clipboard: ${message}`);
9
+ }
10
+ }
package/dist/main.js CHANGED
@@ -9,7 +9,8 @@ import { generateGitDiff } from './git.js';
9
9
  import { buildPrompt } from './prompt-builder.js';
10
10
  import { queryLlm } from './llm-query.js';
11
11
  import { logToolCall, logPrompt, logResponse, logServerStart, logConfiguration, } from './logger.js';
12
- import { DEFAULT_SYSTEM_PROMPT } from './system-prompt.js';
12
+ import { DEFAULT_SYSTEM_PROMPT, getSystemPrompt } from './system-prompt.js';
13
+ import { copyToClipboard } from './clipboard.js';
13
14
  import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
14
15
  import { dirname, join, resolve } from 'path';
15
16
  import { fileURLToPath } from 'url';
@@ -38,7 +39,7 @@ async function handleConsultLlm(args) {
38
39
  .join(', ');
39
40
  throw new Error(`Invalid request parameters: ${errors}`);
40
41
  }
41
- const { files, prompt: userPrompt, git_diff } = parseResult.data;
42
+ const { files, prompt: userPrompt, git_diff, web_mode } = parseResult.data;
42
43
  const model = parseResult.data.model ?? config.defaultModel ?? 'o3';
43
44
  logToolCall('consult_llm', args);
44
45
  // Check if we're using CLI mode for Gemini
@@ -68,6 +69,27 @@ async function handleConsultLlm(args) {
68
69
  prompt = buildPrompt(userPrompt, contextFiles, gitDiffOutput);
69
70
  }
70
71
  await logPrompt(model, prompt);
72
+ // Handle web mode - copy prompt to clipboard instead of querying LLM
73
+ if (web_mode) {
74
+ const systemPrompt = getSystemPrompt(isCliMode);
75
+ const fullPrompt = `# System Prompt
76
+
77
+ ${systemPrompt}
78
+
79
+ # User Prompt
80
+
81
+ ${prompt}`;
82
+ await copyToClipboard(fullPrompt);
83
+ let responseMessage = '✓ Prompt copied to clipboard!\n\n';
84
+ responseMessage +=
85
+ 'Please paste it into your browser-based LLM service and share the response here before I proceed with any implementation.';
86
+ if (filePaths && filePaths.length > 0) {
87
+ responseMessage += `\n\nNote: File paths were included:\n${filePaths.map((p) => ` - ${p}`).join('\n')}`;
88
+ }
89
+ return {
90
+ content: [{ type: 'text', text: responseMessage }],
91
+ };
92
+ }
71
93
  // Query LLM
72
94
  const { response, costInfo } = await queryLlm(prompt, model, filePaths);
73
95
  await logResponse(model, response, costInfo);
package/dist/schema.d.ts CHANGED
@@ -13,6 +13,7 @@ export declare const ConsultLlmArgs: z.ZodObject<{
13
13
  "gemini-2.5-pro": "gemini-2.5-pro";
14
14
  "deepseek-reasoner": "deepseek-reasoner";
15
15
  }>>;
16
+ web_mode: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
16
17
  git_diff: z.ZodOptional<z.ZodObject<{
17
18
  repo_path: z.ZodOptional<z.ZodString>;
18
19
  files: z.ZodArray<z.ZodString>;
@@ -42,6 +43,11 @@ export declare const toolSchema: {
42
43
  readonly default: "o3";
43
44
  readonly description: "LLM model to use";
44
45
  };
46
+ readonly web_mode: {
47
+ readonly type: "boolean";
48
+ readonly default: false;
49
+ readonly description: "Copy the formatted prompt to clipboard instead of querying the LLM. Use this to paste the prompt into browser-based LLM services. IMPORTANT: When true, wait for the user to provide the external LLM's response before proceeding with any implementation.";
50
+ };
45
51
  readonly git_diff: {
46
52
  readonly type: "object";
47
53
  readonly properties: {
package/dist/schema.js CHANGED
@@ -8,6 +8,7 @@ export const ConsultLlmArgs = z.object({
8
8
  files: z.array(z.string()).optional(),
9
9
  prompt: z.string(),
10
10
  model: SupportedChatModel.optional(),
11
+ web_mode: z.boolean().optional().default(false),
11
12
  git_diff: z
12
13
  .object({
13
14
  repo_path: z.string().optional(),
@@ -43,6 +44,11 @@ IMPORTANT: Ask neutral, open-ended questions. Avoid suggesting specific solution
43
44
  default: 'o3',
44
45
  description: 'LLM model to use',
45
46
  },
47
+ web_mode: {
48
+ type: 'boolean',
49
+ default: false,
50
+ description: "Copy the formatted prompt to clipboard instead of querying the LLM. Use this to paste the prompt into browser-based LLM services. IMPORTANT: When true, wait for the user to provide the external LLM's response before proceeding with any implementation.",
51
+ },
46
52
  git_diff: {
47
53
  type: 'object',
48
54
  properties: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "consult-llm-mcp",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "MCP server for consulting powerful AI models",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",
@@ -49,6 +49,7 @@
49
49
  "license": "MIT",
50
50
  "dependencies": {
51
51
  "@modelcontextprotocol/sdk": "^1.13.0",
52
+ "clipboardy": "^5.0.0",
52
53
  "openai": "^5.6.0",
53
54
  "prettier": "^3.5.3",
54
55
  "zod": "^3.25.67"