prompt-clarifier-mcp 2.0.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 +182 -0
- package/dist/clarifier.d.ts +5 -0
- package/dist/clarifier.d.ts.map +1 -0
- package/dist/clarifier.js +72 -0
- package/dist/clarifier.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +124 -0
- package/dist/index.js.map +1 -0
- package/dist/session.d.ts +17 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +72 -0
- package/dist/session.js.map +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Prompt Clarifier — MCP Agent
|
|
2
|
+
|
|
3
|
+
> Arrête le ping-pong avec ton LLM. Cet agent te pose les bonnes questions avant d'exécuter ta demande.
|
|
4
|
+
|
|
5
|
+
## Comment ça marche
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Tu écris : "Crée un modèle ONNX sans opset"
|
|
9
|
+
↓
|
|
10
|
+
Prompt Clarifier pose des questions ciblées
|
|
11
|
+
↓
|
|
12
|
+
Tu réponds (ou tu écris "go" pour arrêter)
|
|
13
|
+
↓
|
|
14
|
+
Un prompt enrichi et précis est généré
|
|
15
|
+
↓
|
|
16
|
+
Ton LLM produit exactement ce que tu voulais — du premier coup
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
### Prérequis — Clé API Anthropic
|
|
24
|
+
|
|
25
|
+
Cet agent utilise Claude Haiku pour générer ses questions. Tu as besoin d'une clé API Anthropic :
|
|
26
|
+
- Crée-en une sur [console.anthropic.com](https://console.anthropic.com)
|
|
27
|
+
- Ajoute-la dans la config MCP de ton outil (voir exemples ci-dessous)
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
### Cursor
|
|
32
|
+
|
|
33
|
+
Ouvre `~/.cursor/mcp.json` (crée-le s'il n'existe pas) :
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"mcpServers": {
|
|
38
|
+
"prompt-clarifier": {
|
|
39
|
+
"command": "npx",
|
|
40
|
+
"args": ["-y", "prompt-clarifier-mcp"],
|
|
41
|
+
"env": {
|
|
42
|
+
"ANTHROPIC_API_KEY": "sk-ant-..."
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Redémarre Cursor. L'outil `clarify` est maintenant disponible.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
### Claude Desktop
|
|
54
|
+
|
|
55
|
+
Ouvre le fichier de config :
|
|
56
|
+
- **Windows** : `%APPDATA%\Claude\claude_desktop_config.json`
|
|
57
|
+
- **macOS** : `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"mcpServers": {
|
|
62
|
+
"prompt-clarifier": {
|
|
63
|
+
"command": "npx",
|
|
64
|
+
"args": ["-y", "prompt-clarifier-mcp"],
|
|
65
|
+
"env": {
|
|
66
|
+
"ANTHROPIC_API_KEY": "sk-ant-..."
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Redémarre Claude Desktop.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### VS Code (avec GitHub Copilot ou Continue)
|
|
78
|
+
|
|
79
|
+
Crée ou ouvre `.vscode/mcp.json` à la racine de ton projet :
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"servers": {
|
|
84
|
+
"prompt-clarifier": {
|
|
85
|
+
"command": "npx",
|
|
86
|
+
"args": ["-y", "prompt-clarifier-mcp"],
|
|
87
|
+
"env": {
|
|
88
|
+
"ANTHROPIC_API_KEY": "sk-ant-..."
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### IntelliJ IDEA / PyCharm (version 2025.1+)
|
|
98
|
+
|
|
99
|
+
1. Ouvre `Settings` → `Tools` → `AI Assistant` → `Model Context Protocol (MCP)`
|
|
100
|
+
2. Clique sur `+` pour ajouter un nouveau serveur
|
|
101
|
+
3. Choisis **"Command"** comme type
|
|
102
|
+
4. Remplis :
|
|
103
|
+
- **Name** : `prompt-clarifier`
|
|
104
|
+
- **Command** : `npx`
|
|
105
|
+
- **Arguments** : `-y prompt-clarifier-mcp`
|
|
106
|
+
- **Environment variables** : `ANTHROPIC_API_KEY=sk-ant-...`
|
|
107
|
+
5. Clique `OK` et redémarre l'IDE
|
|
108
|
+
|
|
109
|
+
> ⚠️ Requiert IntelliJ IDEA / PyCharm 2025.1 ou supérieur avec AI Assistant activé.
|
|
110
|
+
> Active le mode **"Codebase"** dans le chat AI Assistant pour que les outils MCP soient disponibles.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
### Claude Code
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
claude mcp add prompt-clarifier npx -- -y prompt-clarifier-mcp
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Puis ajoute la clé API dans ton environnement ou dans `.claude/settings.json` :
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"env": {
|
|
124
|
+
"ANTHROPIC_API_KEY": "sk-ant-..."
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Utilisation
|
|
132
|
+
|
|
133
|
+
Dans n'importe quel chat de ton IDE, appelle l'outil `clarify` avec ton prompt :
|
|
134
|
+
|
|
135
|
+
**Exemple :**
|
|
136
|
+
```
|
|
137
|
+
Utilise l'outil clarify avec ce prompt : "Crée un modèle ONNX sans opset"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
L'agent va :
|
|
141
|
+
1. Détecter le domaine (ML/ONNX dans cet exemple)
|
|
142
|
+
2. Te poser des questions ciblées une par une
|
|
143
|
+
3. Générer un prompt enrichi quand tu as répondu (ou quand tu écris **"go"**)
|
|
144
|
+
|
|
145
|
+
**Pour arrêter les questions à tout moment**, écris simplement :
|
|
146
|
+
- `go` / `commence` / `lance-toi` / `c'est bon` / `assez` / `proceed`
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Prérequis
|
|
151
|
+
|
|
152
|
+
- Node.js 18 ou supérieur
|
|
153
|
+
- Un IDE avec support MCP (voir liste ci-dessus)
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Développement local
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
git clone https://github.com/dmi-agentix/prompt-clarifier
|
|
161
|
+
cd prompt-clarifier
|
|
162
|
+
npm install
|
|
163
|
+
npm run build
|
|
164
|
+
|
|
165
|
+
# Tester avec l'inspecteur MCP
|
|
166
|
+
npx @modelcontextprotocol/inspector node dist/index.js
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Contribuer
|
|
172
|
+
|
|
173
|
+
Les contributions sont les bienvenues ! En particulier :
|
|
174
|
+
- Nouvelles banques de questions par domaine (`src/clarifier.ts`)
|
|
175
|
+
- Nouveaux mots-clés "stop" dans d'autres langues
|
|
176
|
+
- Amélioration de la détection de domaine
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Licence
|
|
181
|
+
|
|
182
|
+
MIT — DMI Agentix
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { QA } from "./session.js";
|
|
2
|
+
export declare function isGoSignal(text: string): boolean;
|
|
3
|
+
export declare function getNextQuestion(initialPrompt: string, qaHistory: QA[]): Promise<string | null>;
|
|
4
|
+
export declare function buildEnrichedPrompt(initialPrompt: string, qaHistory: QA[]): string;
|
|
5
|
+
//# sourceMappingURL=clarifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clarifier.d.ts","sourceRoot":"","sources":["../src/clarifier.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAOlC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQhD;AAaD,wBAAsB,eAAe,CACnC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,EAAE,EAAE,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgCxB;AAED,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG,MAAM,CAelF"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.isGoSignal = isGoSignal;
|
|
7
|
+
exports.getNextQuestion = getNextQuestion;
|
|
8
|
+
exports.buildEnrichedPrompt = buildEnrichedPrompt;
|
|
9
|
+
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
10
|
+
const GO_KEYWORDS = [
|
|
11
|
+
"go", "commence", "start", "c'est bon", "lance toi", "lance-toi",
|
|
12
|
+
"démarre", "ok go", "assez", "enough", "proceed", "just do it",
|
|
13
|
+
];
|
|
14
|
+
function isGoSignal(text) {
|
|
15
|
+
const normalized = text.toLowerCase().trim();
|
|
16
|
+
return GO_KEYWORDS.some((kw) => normalized === kw ||
|
|
17
|
+
normalized.startsWith(kw + " ") ||
|
|
18
|
+
normalized.endsWith(" " + kw));
|
|
19
|
+
}
|
|
20
|
+
const client = new sdk_1.default();
|
|
21
|
+
const SYSTEM_PROMPT = `Tu es un agent expert en amélioration de prompts. Ton rôle est d'analyser un prompt utilisateur et l'historique des questions/réponses déjà échangées, puis de décider de la prochaine action.
|
|
22
|
+
|
|
23
|
+
Règles strictes :
|
|
24
|
+
1. Si des précisions importantes manquent encore pour bien exécuter la demande, pose UNE SEULE question — la plus pertinente selon le domaine et le contexte réel du prompt.
|
|
25
|
+
2. Si tu as suffisamment d'informations pour que le LLM puisse répondre précisément (ou après 5 questions maximum), réponds uniquement avec le mot : DONE
|
|
26
|
+
3. La question doit être concrète et adaptée au domaine détecté automatiquement (code, data science, design, rédaction, business, DevOps, etc.)
|
|
27
|
+
4. Ne pose jamais une question générique si le contexte est déjà clair. Chaque question doit débloquer une information réellement utile.
|
|
28
|
+
5. Réponds UNIQUEMENT avec la question ou le mot DONE — aucune explication, aucun préambule, aucune ponctuation superflue.`;
|
|
29
|
+
async function getNextQuestion(initialPrompt, qaHistory) {
|
|
30
|
+
if (qaHistory.length >= 5)
|
|
31
|
+
return null;
|
|
32
|
+
const historyText = qaHistory.length > 0
|
|
33
|
+
? qaHistory
|
|
34
|
+
.map((qa, i) => `Q${i + 1}: ${qa.question}\nR${i + 1}: ${qa.answer}`)
|
|
35
|
+
.join("\n\n")
|
|
36
|
+
: "Aucune question posée pour l'instant.";
|
|
37
|
+
const userMessage = `Prompt initial de l'utilisateur :
|
|
38
|
+
"${initialPrompt}"
|
|
39
|
+
|
|
40
|
+
Historique des questions/réponses :
|
|
41
|
+
${historyText}
|
|
42
|
+
|
|
43
|
+
Quelle est la prochaine question à poser, ou dois-tu répondre DONE ?`;
|
|
44
|
+
const response = await client.messages.create({
|
|
45
|
+
model: "claude-haiku-4-5-20251001",
|
|
46
|
+
max_tokens: 200,
|
|
47
|
+
system: SYSTEM_PROMPT,
|
|
48
|
+
messages: [{ role: "user", content: userMessage }],
|
|
49
|
+
});
|
|
50
|
+
const text = response.content[0].type === "text"
|
|
51
|
+
? response.content[0].text.trim()
|
|
52
|
+
: "";
|
|
53
|
+
if (text.toUpperCase() === "DONE" || text === "")
|
|
54
|
+
return null;
|
|
55
|
+
return text;
|
|
56
|
+
}
|
|
57
|
+
function buildEnrichedPrompt(initialPrompt, qaHistory) {
|
|
58
|
+
if (qaHistory.length === 0)
|
|
59
|
+
return initialPrompt;
|
|
60
|
+
const context = qaHistory
|
|
61
|
+
.map((qa) => `- ${qa.question}\n → ${qa.answer}`)
|
|
62
|
+
.join("\n");
|
|
63
|
+
return `${initialPrompt}
|
|
64
|
+
|
|
65
|
+
## Contexte additionnel recueilli
|
|
66
|
+
|
|
67
|
+
${context}
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
Prends en compte tout ce contexte pour répondre de façon précise et complète.`;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=clarifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clarifier.js","sourceRoot":"","sources":["../src/clarifier.ts"],"names":[],"mappings":";;;;;AAQA,gCAQC;AAaD,0CAmCC;AAED,kDAeC;AAjFD,4DAA0C;AAG1C,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW;IAChE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY;CAC/D,CAAC;AAEF,SAAgB,UAAU,CAAC,IAAY;IACrC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAC7C,OAAO,WAAW,CAAC,IAAI,CACrB,CAAC,EAAE,EAAE,EAAE,CACL,UAAU,KAAK,EAAE;QACjB,UAAU,CAAC,UAAU,CAAC,EAAE,GAAG,GAAG,CAAC;QAC/B,UAAU,CAAC,QAAQ,CAAC,GAAG,GAAG,EAAE,CAAC,CAChC,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,aAAS,EAAE,CAAC;AAE/B,MAAM,aAAa,GAAG;;;;;;;2HAOqG,CAAC;AAErH,KAAK,UAAU,eAAe,CACnC,aAAqB,EACrB,SAAe;IAEf,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvC,MAAM,WAAW,GACf,SAAS,CAAC,MAAM,GAAG,CAAC;QAClB,CAAC,CAAC,SAAS;aACN,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC;aACpE,IAAI,CAAC,MAAM,CAAC;QACjB,CAAC,CAAC,uCAAuC,CAAC;IAE9C,MAAM,WAAW,GAAG;GACnB,aAAa;;;EAGd,WAAW;;qEAEwD,CAAC;IAEpE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC5C,KAAK,EAAE,2BAA2B;QAClC,UAAU,EAAE,GAAG;QACf,MAAM,EAAE,aAAa;QACrB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;KACnD,CAAC,CAAC;IAEH,MAAM,IAAI,GACR,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM;QACjC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE;QACjC,CAAC,CAAC,EAAE,CAAC;IAET,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC9D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,mBAAmB,CAAC,aAAqB,EAAE,SAAe;IACxE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,aAAa,CAAC;IAEjD,MAAM,OAAO,GAAG,SAAS;SACtB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,SAAS,EAAE,CAAC,MAAM,EAAE,CAAC;SACjD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO,GAAG,aAAa;;;;EAIvB,OAAO;;;8EAGqE,CAAC;AAC/E,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
5
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
6
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
7
|
+
const session_js_1 = require("./session.js");
|
|
8
|
+
const clarifier_js_1 = require("./clarifier.js");
|
|
9
|
+
const server = new index_js_1.Server({ name: "prompt-clarifier", version: "2.0.0" }, { capabilities: { tools: {} } });
|
|
10
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
11
|
+
tools: [
|
|
12
|
+
{
|
|
13
|
+
name: "clarify",
|
|
14
|
+
description: "Affine un prompt utilisateur en posant des questions ciblées une par une, puis génère un prompt enrichi prêt à être exécuté par le LLM.",
|
|
15
|
+
inputSchema: {
|
|
16
|
+
type: "object",
|
|
17
|
+
properties: {
|
|
18
|
+
prompt: {
|
|
19
|
+
type: "string",
|
|
20
|
+
description: "Le prompt initial de l'utilisateur (requis au premier appel).",
|
|
21
|
+
},
|
|
22
|
+
session_id: {
|
|
23
|
+
type: "string",
|
|
24
|
+
description: "ID de session retourné par un appel précédent (pour continuer la conversation).",
|
|
25
|
+
},
|
|
26
|
+
answer: {
|
|
27
|
+
type: "string",
|
|
28
|
+
description: "Réponse de l'utilisateur à la dernière question posée par l'agent.",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
required: [],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
}));
|
|
36
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
37
|
+
if (request.params.name !== "clarify") {
|
|
38
|
+
return { content: [{ type: "text", text: `Outil inconnu : ${request.params.name}` }] };
|
|
39
|
+
}
|
|
40
|
+
const args = request.params.arguments;
|
|
41
|
+
// --- New session ---
|
|
42
|
+
if (!args.session_id) {
|
|
43
|
+
if (!args.prompt) {
|
|
44
|
+
return {
|
|
45
|
+
content: [{ type: "text", text: "Erreur : `prompt` est requis pour démarrer une session." }],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const session = (0, session_js_1.createSession)(args.prompt);
|
|
49
|
+
const firstQuestion = await (0, clarifier_js_1.getNextQuestion)(session.initialPrompt, []);
|
|
50
|
+
if (!firstQuestion) {
|
|
51
|
+
(0, session_js_1.deleteSession)(session.id);
|
|
52
|
+
return {
|
|
53
|
+
content: [{ type: "text", text: (0, clarifier_js_1.buildEnrichedPrompt)(session.initialPrompt, []) }],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
(0, session_js_1.saveSession)(session);
|
|
57
|
+
return {
|
|
58
|
+
content: [
|
|
59
|
+
{
|
|
60
|
+
type: "text",
|
|
61
|
+
text: JSON.stringify({
|
|
62
|
+
session_id: session.id,
|
|
63
|
+
question: firstQuestion,
|
|
64
|
+
instructions: "Réponds à cette question, puis rappelle l'outil clarify avec session_id et answer. Dis 'go' pour générer immédiatement le prompt final.",
|
|
65
|
+
}),
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// --- Continue existing session ---
|
|
71
|
+
const session = (0, session_js_1.loadSession)(args.session_id);
|
|
72
|
+
if (!session) {
|
|
73
|
+
return {
|
|
74
|
+
content: [{ type: "text", text: `Session introuvable : ${args.session_id}` }],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const answer = args.answer ?? "";
|
|
78
|
+
// User said "go" → generate final prompt now
|
|
79
|
+
if ((0, clarifier_js_1.isGoSignal)(answer)) {
|
|
80
|
+
const enriched = (0, clarifier_js_1.buildEnrichedPrompt)(session.initialPrompt, session.qaHistory);
|
|
81
|
+
(0, session_js_1.deleteSession)(session.id);
|
|
82
|
+
return { content: [{ type: "text", text: enriched }] };
|
|
83
|
+
}
|
|
84
|
+
// Record the answer to the last question asked
|
|
85
|
+
if (session.lastQuestion && answer.trim()) {
|
|
86
|
+
session.qaHistory.push({ question: session.lastQuestion, answer });
|
|
87
|
+
}
|
|
88
|
+
// Ask Claude for the next question
|
|
89
|
+
const nextQuestion = await (0, clarifier_js_1.getNextQuestion)(session.initialPrompt, session.qaHistory);
|
|
90
|
+
if (!nextQuestion) {
|
|
91
|
+
const enriched = (0, clarifier_js_1.buildEnrichedPrompt)(session.initialPrompt, session.qaHistory);
|
|
92
|
+
(0, session_js_1.deleteSession)(session.id);
|
|
93
|
+
return { content: [{ type: "text", text: enriched }] };
|
|
94
|
+
}
|
|
95
|
+
session.lastQuestion = nextQuestion;
|
|
96
|
+
(0, session_js_1.saveSession)(session);
|
|
97
|
+
return {
|
|
98
|
+
content: [
|
|
99
|
+
{
|
|
100
|
+
type: "text",
|
|
101
|
+
text: JSON.stringify({
|
|
102
|
+
session_id: session.id,
|
|
103
|
+
question: nextQuestion,
|
|
104
|
+
qa_so_far: session.qaHistory.length,
|
|
105
|
+
instructions: "Réponds à cette question, puis rappelle l'outil clarify avec session_id et answer. Dis 'go' pour générer immédiatement le prompt final.",
|
|
106
|
+
}),
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
async function main() {
|
|
112
|
+
if (!process.env.ANTHROPIC_API_KEY) {
|
|
113
|
+
process.stderr.write("Erreur : ANTHROPIC_API_KEY non définie.\n");
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
117
|
+
await server.connect(transport);
|
|
118
|
+
process.stderr.write("Prompt Clarifier MCP server v2.0 started (stdio)\n");
|
|
119
|
+
}
|
|
120
|
+
main().catch((err) => {
|
|
121
|
+
process.stderr.write(`Fatal: ${err}\n`);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface QA {
|
|
2
|
+
question: string;
|
|
3
|
+
answer: string;
|
|
4
|
+
}
|
|
5
|
+
export interface Session {
|
|
6
|
+
id: string;
|
|
7
|
+
initialPrompt: string;
|
|
8
|
+
qaHistory: QA[];
|
|
9
|
+
lastQuestion?: string;
|
|
10
|
+
status: "questioning" | "done";
|
|
11
|
+
createdAt: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function createSession(initialPrompt: string): Session;
|
|
14
|
+
export declare function loadSession(id: string): Session | null;
|
|
15
|
+
export declare function saveSession(session: Session): void;
|
|
16
|
+
export declare function deleteSession(id: string): void;
|
|
17
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,EAAE;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,EAAE,EAAE,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,wBAAgB,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAU5D;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAItD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAElD;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAG9C"}
|
package/dist/session.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.createSession = createSession;
|
|
37
|
+
exports.loadSession = loadSession;
|
|
38
|
+
exports.saveSession = saveSession;
|
|
39
|
+
exports.deleteSession = deleteSession;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const os = __importStar(require("os"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const crypto = __importStar(require("crypto"));
|
|
44
|
+
function sessionPath(id) {
|
|
45
|
+
return path.join(os.tmpdir(), `clarifier-session-${id}.json`);
|
|
46
|
+
}
|
|
47
|
+
function createSession(initialPrompt) {
|
|
48
|
+
const session = {
|
|
49
|
+
id: crypto.randomUUID(),
|
|
50
|
+
initialPrompt,
|
|
51
|
+
qaHistory: [],
|
|
52
|
+
status: "questioning",
|
|
53
|
+
createdAt: Date.now(),
|
|
54
|
+
};
|
|
55
|
+
fs.writeFileSync(sessionPath(session.id), JSON.stringify(session, null, 2));
|
|
56
|
+
return session;
|
|
57
|
+
}
|
|
58
|
+
function loadSession(id) {
|
|
59
|
+
const p = sessionPath(id);
|
|
60
|
+
if (!fs.existsSync(p))
|
|
61
|
+
return null;
|
|
62
|
+
return JSON.parse(fs.readFileSync(p, "utf8"));
|
|
63
|
+
}
|
|
64
|
+
function saveSession(session) {
|
|
65
|
+
fs.writeFileSync(sessionPath(session.id), JSON.stringify(session, null, 2));
|
|
66
|
+
}
|
|
67
|
+
function deleteSession(id) {
|
|
68
|
+
const p = sessionPath(id);
|
|
69
|
+
if (fs.existsSync(p))
|
|
70
|
+
fs.unlinkSync(p);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,sCAUC;AAED,kCAIC;AAED,kCAEC;AAED,sCAGC;AAhDD,uCAAyB;AACzB,uCAAyB;AACzB,2CAA6B;AAC7B,+CAAiC;AAgBjC,SAAS,WAAW,CAAC,EAAU;IAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,qBAAqB,EAAE,OAAO,CAAC,CAAC;AAChE,CAAC;AAED,SAAgB,aAAa,CAAC,aAAqB;IACjD,MAAM,OAAO,GAAY;QACvB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,aAAa;QACb,SAAS,EAAE,EAAE;QACb,MAAM,EAAE,aAAa;QACrB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;IACF,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5E,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAgB,WAAW,CAAC,EAAU;IACpC,MAAM,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC1B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAY,CAAC;AAC3D,CAAC;AAED,SAAgB,WAAW,CAAC,OAAgB;IAC1C,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,SAAgB,aAAa,CAAC,EAAU;IACtC,MAAM,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "prompt-clarifier-mcp",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "MCP agent that clarifies user prompts before sending them to any LLM — works in Cursor, VS Code, IntelliJ, PyCharm, Claude Desktop",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"prompt-clarifier-mcp": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsc --watch",
|
|
12
|
+
"start": "node dist/index.js",
|
|
13
|
+
"prepare": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"mcp",
|
|
17
|
+
"prompt",
|
|
18
|
+
"clarifier",
|
|
19
|
+
"agent",
|
|
20
|
+
"llm",
|
|
21
|
+
"cursor",
|
|
22
|
+
"vscode",
|
|
23
|
+
"intellij",
|
|
24
|
+
"jetbrains"
|
|
25
|
+
],
|
|
26
|
+
"author": "DMI Agentix",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@anthropic-ai/sdk": "^0.39.0",
|
|
30
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^20.0.0",
|
|
34
|
+
"typescript": "^5.0.0"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18.0.0"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist/",
|
|
41
|
+
"README.md"
|
|
42
|
+
]
|
|
43
|
+
}
|