@leanmcp/elicitation 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -352
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -1,16 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img
|
|
3
|
+
src="https://raw.githubusercontent.com/LeanMCP/leanmcp-sdk/refs/heads/main/assets/logo.png"
|
|
4
|
+
alt="LeanMCP Logo"
|
|
5
|
+
width="400"
|
|
6
|
+
/>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<strong>@leanmcp/elicitation</strong><br/>
|
|
11
|
+
Structured user input collection for MCP tools using the elicitation protocol.
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="https://www.npmjs.com/package/@leanmcp/elicitation">
|
|
16
|
+
<img src="https://img.shields.io/npm/v/@leanmcp/elicitation" alt="npm version" />
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://www.npmjs.com/package/@leanmcp/elicitation">
|
|
19
|
+
<img src="https://img.shields.io/npm/dm/@leanmcp/elicitation" alt="npm downloads" />
|
|
20
|
+
</a>
|
|
21
|
+
<a href="https://docs.leanmcp.com/sdk/elicitation">
|
|
22
|
+
<img src="https://img.shields.io/badge/Docs-leanmcp-0A66C2?" />
|
|
23
|
+
</a>
|
|
24
|
+
<a href="https://discord.com/invite/DsRcA3GwPy">
|
|
25
|
+
<img src="https://img.shields.io/badge/Discord-Join-5865F2?logo=discord&logoColor=white" />
|
|
26
|
+
</a>
|
|
27
|
+
<a href="https://x.com/LeanMcp">
|
|
28
|
+
<img src="https://img.shields.io/badge/@LeanMCP-f5f5f5?logo=x&logoColor=000000" />
|
|
29
|
+
</a>
|
|
30
|
+
</p>
|
|
4
31
|
|
|
5
32
|
## Features
|
|
6
33
|
|
|
7
|
-
- **@Elicitation
|
|
8
|
-
- **
|
|
9
|
-
- **Multiple
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **Conditional elicitation** - Only ask for inputs when needed
|
|
13
|
-
- **Type-safe** - Full TypeScript support with type inference
|
|
34
|
+
- **@Elicitation Decorator** — Automatically collect missing user inputs before tool execution
|
|
35
|
+
- **Fluent Builder API** — Programmatic form creation with `ElicitationFormBuilder`
|
|
36
|
+
- **Multiple Strategies** — Form and multi-step elicitation
|
|
37
|
+
- **Built-in Validation** — min/max, pattern matching, custom validators
|
|
38
|
+
- **Conditional Elicitation** — Only ask for inputs when needed
|
|
14
39
|
|
|
15
40
|
## Installation
|
|
16
41
|
|
|
@@ -20,7 +45,7 @@ npm install @leanmcp/elicitation @leanmcp/core
|
|
|
20
45
|
|
|
21
46
|
## Quick Start
|
|
22
47
|
|
|
23
|
-
###
|
|
48
|
+
### Simple Form Elicitation
|
|
24
49
|
|
|
25
50
|
```typescript
|
|
26
51
|
import { Tool } from "@leanmcp/core";
|
|
@@ -51,15 +76,81 @@ class SlackService {
|
|
|
51
76
|
]
|
|
52
77
|
})
|
|
53
78
|
async createChannel(args: { channelName: string; isPrivate: boolean }) {
|
|
54
|
-
// Implementation
|
|
55
79
|
return { success: true, channelName: args.channelName };
|
|
56
80
|
}
|
|
57
81
|
}
|
|
58
82
|
```
|
|
59
83
|
|
|
60
|
-
###
|
|
84
|
+
### How It Works
|
|
85
|
+
|
|
86
|
+
1. **Client calls tool** with missing required fields
|
|
87
|
+
2. **Decorator intercepts** and checks for missing fields
|
|
88
|
+
3. **Elicitation request returned** with form definition
|
|
89
|
+
4. **Client displays form** to collect user input
|
|
90
|
+
5. **Client calls tool again** with complete arguments
|
|
91
|
+
6. **Method executes** normally
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Fluent Builder API
|
|
96
|
+
|
|
97
|
+
For more complex forms, use `ElicitationFormBuilder`:
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import { Tool } from "@leanmcp/core";
|
|
101
|
+
import { Elicitation, ElicitationFormBuilder, validation } from "@leanmcp/elicitation";
|
|
102
|
+
|
|
103
|
+
class UserService {
|
|
104
|
+
@Tool({ description: "Create user account" })
|
|
105
|
+
@Elicitation({
|
|
106
|
+
builder: () => new ElicitationFormBuilder()
|
|
107
|
+
.title("User Registration")
|
|
108
|
+
.description("Create a new user account")
|
|
109
|
+
.addEmailField("email", "Email Address", { required: true })
|
|
110
|
+
.addTextField("username", "Username", {
|
|
111
|
+
required: true,
|
|
112
|
+
validation: validation()
|
|
113
|
+
.minLength(3)
|
|
114
|
+
.maxLength(20)
|
|
115
|
+
.pattern("^[a-zA-Z0-9_]+$")
|
|
116
|
+
.build()
|
|
117
|
+
})
|
|
118
|
+
.addSelectField("role", "Role", [
|
|
119
|
+
{ label: "Admin", value: "admin" },
|
|
120
|
+
{ label: "User", value: "user" }
|
|
121
|
+
])
|
|
122
|
+
.build()
|
|
123
|
+
})
|
|
124
|
+
async createUser(args: any) {
|
|
125
|
+
return { success: true, email: args.email };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Builder Methods
|
|
61
131
|
|
|
62
|
-
|
|
132
|
+
| Method | Description |
|
|
133
|
+
|--------|-------------|
|
|
134
|
+
| `title(string)` | Set form title |
|
|
135
|
+
| `description(string)` | Set form description |
|
|
136
|
+
| `condition(fn)` | Set condition for elicitation |
|
|
137
|
+
| `addTextField(name, label, opts?)` | Add text input |
|
|
138
|
+
| `addTextAreaField(name, label, opts?)` | Add textarea |
|
|
139
|
+
| `addNumberField(name, label, opts?)` | Add number input |
|
|
140
|
+
| `addBooleanField(name, label, opts?)` | Add checkbox |
|
|
141
|
+
| `addSelectField(name, label, options, opts?)` | Add dropdown |
|
|
142
|
+
| `addMultiSelectField(name, label, options, opts?)` | Add multi-select |
|
|
143
|
+
| `addEmailField(name, label, opts?)` | Add email input |
|
|
144
|
+
| `addUrlField(name, label, opts?)` | Add URL input |
|
|
145
|
+
| `addDateField(name, label, opts?)` | Add date picker |
|
|
146
|
+
| `addCustomField(field)` | Add custom field |
|
|
147
|
+
| `build()` | Build final config |
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Conditional Elicitation
|
|
152
|
+
|
|
153
|
+
Only ask for inputs when needed:
|
|
63
154
|
|
|
64
155
|
```typescript
|
|
65
156
|
@Tool({ description: "Send message to Slack" })
|
|
@@ -84,41 +175,11 @@ async sendMessage(args: { channelId?: string; message: string }) {
|
|
|
84
175
|
}
|
|
85
176
|
```
|
|
86
177
|
|
|
87
|
-
|
|
178
|
+
---
|
|
88
179
|
|
|
89
|
-
|
|
180
|
+
## Multi-Step Elicitation
|
|
90
181
|
|
|
91
|
-
|
|
92
|
-
import { ElicitationFormBuilder, validation } from "@leanmcp/elicitation";
|
|
93
|
-
|
|
94
|
-
@Tool({ description: "Create user account" })
|
|
95
|
-
@Elicitation({
|
|
96
|
-
builder: () => new ElicitationFormBuilder()
|
|
97
|
-
.title("User Registration")
|
|
98
|
-
.description("Create a new user account")
|
|
99
|
-
.addEmailField("email", "Email Address", { required: true })
|
|
100
|
-
.addTextField("username", "Username", {
|
|
101
|
-
required: true,
|
|
102
|
-
validation: validation()
|
|
103
|
-
.minLength(3)
|
|
104
|
-
.maxLength(20)
|
|
105
|
-
.pattern("^[a-zA-Z0-9_]+$")
|
|
106
|
-
.build()
|
|
107
|
-
})
|
|
108
|
-
.addSelectField("role", "Role", [
|
|
109
|
-
{ label: "Admin", value: "admin" },
|
|
110
|
-
{ label: "User", value: "user" }
|
|
111
|
-
])
|
|
112
|
-
.build()
|
|
113
|
-
})
|
|
114
|
-
async createUser(args: any) {
|
|
115
|
-
// Implementation
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### 4. Multi-Step Elicitation
|
|
120
|
-
|
|
121
|
-
Break input collection into multiple steps:
|
|
182
|
+
Break input collection into sequential steps:
|
|
122
183
|
|
|
123
184
|
```typescript
|
|
124
185
|
@Tool({ description: "Deploy application" })
|
|
@@ -159,123 +220,27 @@ async deployApp(args: any) {
|
|
|
159
220
|
}
|
|
160
221
|
```
|
|
161
222
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
### Text Fields
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
{
|
|
168
|
-
name: "description",
|
|
169
|
-
label: "Description",
|
|
170
|
-
type: "text",
|
|
171
|
-
placeholder: "Enter description...",
|
|
172
|
-
validation: {
|
|
173
|
-
minLength: 10,
|
|
174
|
-
maxLength: 500
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Textarea
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
{
|
|
183
|
-
name: "content",
|
|
184
|
-
label: "Content",
|
|
185
|
-
type: "textarea",
|
|
186
|
-
placeholder: "Enter long text..."
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Number
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
{
|
|
194
|
-
name: "age",
|
|
195
|
-
label: "Age",
|
|
196
|
-
type: "number",
|
|
197
|
-
validation: {
|
|
198
|
-
min: 18,
|
|
199
|
-
max: 120
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### Boolean (Checkbox)
|
|
205
|
-
|
|
206
|
-
```typescript
|
|
207
|
-
{
|
|
208
|
-
name: "agree",
|
|
209
|
-
label: "I agree to terms",
|
|
210
|
-
type: "boolean",
|
|
211
|
-
defaultValue: false
|
|
212
|
-
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### Select (Dropdown)
|
|
216
|
-
|
|
217
|
-
```typescript
|
|
218
|
-
{
|
|
219
|
-
name: "country",
|
|
220
|
-
label: "Country",
|
|
221
|
-
type: "select",
|
|
222
|
-
options: [
|
|
223
|
-
{ label: "United States", value: "US" },
|
|
224
|
-
{ label: "Canada", value: "CA" }
|
|
225
|
-
]
|
|
226
|
-
}
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### Multi-Select
|
|
223
|
+
---
|
|
230
224
|
|
|
231
|
-
|
|
232
|
-
{
|
|
233
|
-
name: "tags",
|
|
234
|
-
label: "Tags",
|
|
235
|
-
type: "multiselect",
|
|
236
|
-
options: [
|
|
237
|
-
{ label: "JavaScript", value: "js" },
|
|
238
|
-
{ label: "TypeScript", value: "ts" },
|
|
239
|
-
{ label: "Python", value: "py" }
|
|
240
|
-
]
|
|
241
|
-
}
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### Email
|
|
245
|
-
|
|
246
|
-
```typescript
|
|
247
|
-
{
|
|
248
|
-
name: "email",
|
|
249
|
-
label: "Email",
|
|
250
|
-
type: "email",
|
|
251
|
-
required: true
|
|
252
|
-
}
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### URL
|
|
256
|
-
|
|
257
|
-
```typescript
|
|
258
|
-
{
|
|
259
|
-
name: "website",
|
|
260
|
-
label: "Website",
|
|
261
|
-
type: "url",
|
|
262
|
-
placeholder: "https://example.com"
|
|
263
|
-
}
|
|
264
|
-
```
|
|
225
|
+
## Field Types
|
|
265
226
|
|
|
266
|
-
|
|
227
|
+
| Type | Description |
|
|
228
|
+
|------|-------------|
|
|
229
|
+
| `text` | Single-line text input |
|
|
230
|
+
| `textarea` | Multi-line text area |
|
|
231
|
+
| `number` | Numeric input |
|
|
232
|
+
| `boolean` | Checkbox |
|
|
233
|
+
| `select` | Dropdown (single choice) |
|
|
234
|
+
| `multiselect` | Multi-select |
|
|
235
|
+
| `email` | Email input |
|
|
236
|
+
| `url` | URL input |
|
|
237
|
+
| `date` | Date picker |
|
|
267
238
|
|
|
268
|
-
|
|
269
|
-
{
|
|
270
|
-
name: "birthdate",
|
|
271
|
-
label: "Birth Date",
|
|
272
|
-
type: "date"
|
|
273
|
-
}
|
|
274
|
-
```
|
|
239
|
+
---
|
|
275
240
|
|
|
276
241
|
## Validation
|
|
277
242
|
|
|
278
|
-
### Built-in
|
|
243
|
+
### Built-in Validation
|
|
279
244
|
|
|
280
245
|
```typescript
|
|
281
246
|
{
|
|
@@ -291,29 +256,6 @@ async deployApp(args: any) {
|
|
|
291
256
|
}
|
|
292
257
|
```
|
|
293
258
|
|
|
294
|
-
### Custom Validators
|
|
295
|
-
|
|
296
|
-
```typescript
|
|
297
|
-
{
|
|
298
|
-
name: "password",
|
|
299
|
-
label: "Password",
|
|
300
|
-
type: "text",
|
|
301
|
-
validation: {
|
|
302
|
-
customValidator: (value) => {
|
|
303
|
-
const hasUpper = /[A-Z]/.test(value);
|
|
304
|
-
const hasLower = /[a-z]/.test(value);
|
|
305
|
-
const hasNumber = /[0-9]/.test(value);
|
|
306
|
-
|
|
307
|
-
if (!hasUpper || !hasLower || !hasNumber) {
|
|
308
|
-
return "Password must contain uppercase, lowercase, and numbers";
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
return true; // Valid
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
```
|
|
316
|
-
|
|
317
259
|
### Using ValidationBuilder
|
|
318
260
|
|
|
319
261
|
```typescript
|
|
@@ -328,103 +270,7 @@ validation()
|
|
|
328
270
|
.build()
|
|
329
271
|
```
|
|
330
272
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
1. **Client calls tool** with missing required fields
|
|
334
|
-
2. **Decorator intercepts** the method call before execution
|
|
335
|
-
3. **Elicitation check** determines if required fields are missing
|
|
336
|
-
4. **Elicitation request returned** if fields are missing
|
|
337
|
-
5. **Client displays form** to collect user input
|
|
338
|
-
6. **Client calls tool again** with complete arguments
|
|
339
|
-
7. **Method executes** normally with all required fields
|
|
340
|
-
|
|
341
|
-
**Key Benefits:**
|
|
342
|
-
- **Automatic interception** - No need to modify `@leanmcp/core`
|
|
343
|
-
- **Clean separation** - Elicitation logic separate from business logic
|
|
344
|
-
- **MCP compliant** - Follows MCP elicitation protocol
|
|
345
|
-
- **Type-safe** - Full TypeScript support
|
|
346
|
-
|
|
347
|
-
## Strategies
|
|
348
|
-
|
|
349
|
-
### Form Strategy (Default)
|
|
350
|
-
|
|
351
|
-
Collect all fields at once:
|
|
352
|
-
|
|
353
|
-
```typescript
|
|
354
|
-
@Elicitation({
|
|
355
|
-
strategy: "form", // or omit, form is default
|
|
356
|
-
title: "User Information",
|
|
357
|
-
fields: [/* ... */]
|
|
358
|
-
})
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
### Multi-Step Strategy
|
|
362
|
-
|
|
363
|
-
Break input collection into sequential steps:
|
|
364
|
-
|
|
365
|
-
```typescript
|
|
366
|
-
@Elicitation({
|
|
367
|
-
strategy: "multi-step",
|
|
368
|
-
builder: () => [
|
|
369
|
-
{
|
|
370
|
-
title: "Step 1: Basic Info",
|
|
371
|
-
fields: [/* step 1 fields */]
|
|
372
|
-
},
|
|
373
|
-
{
|
|
374
|
-
title: "Step 2: Details",
|
|
375
|
-
fields: [/* step 2 fields */],
|
|
376
|
-
condition: (prev) => prev.needsDetails === true
|
|
377
|
-
}
|
|
378
|
-
]
|
|
379
|
-
})
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
## Elicitation Flow
|
|
383
|
-
|
|
384
|
-
### Request/Response Cycle
|
|
385
|
-
|
|
386
|
-
**First Call (Missing Fields):**
|
|
387
|
-
```json
|
|
388
|
-
// Request
|
|
389
|
-
{
|
|
390
|
-
"method": "tools/call",
|
|
391
|
-
"params": {
|
|
392
|
-
"name": "createChannel",
|
|
393
|
-
"arguments": {}
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
// Response (Elicitation Request)
|
|
398
|
-
{
|
|
399
|
-
"content": [{
|
|
400
|
-
"type": "text",
|
|
401
|
-
"text": "{\n \"type\": \"elicitation\",\n \"title\": \"Create Channel\",\n \"fields\": [...]\n}"
|
|
402
|
-
}]
|
|
403
|
-
}
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
**Second Call (Complete Fields):**
|
|
407
|
-
```json
|
|
408
|
-
// Request
|
|
409
|
-
{
|
|
410
|
-
"method": "tools/call",
|
|
411
|
-
"params": {
|
|
412
|
-
"name": "createChannel",
|
|
413
|
-
"arguments": {
|
|
414
|
-
"channelName": "my-channel",
|
|
415
|
-
"isPrivate": false
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
// Response (Tool Result)
|
|
421
|
-
{
|
|
422
|
-
"content": [{
|
|
423
|
-
"type": "text",
|
|
424
|
-
"text": "{\"success\": true, \"channelId\": \"C123\"}"
|
|
425
|
-
}]
|
|
426
|
-
}
|
|
427
|
-
```
|
|
273
|
+
---
|
|
428
274
|
|
|
429
275
|
## API Reference
|
|
430
276
|
|
|
@@ -472,92 +318,33 @@ interface FieldValidation {
|
|
|
472
318
|
}
|
|
473
319
|
```
|
|
474
320
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
See [examples/slack-with-elicitation](../../examples/slack-with-elicitation) for a complete working example.
|
|
478
|
-
|
|
479
|
-
```typescript
|
|
480
|
-
import { createHTTPServer, MCPServer, Tool } from "@leanmcp/core";
|
|
481
|
-
import { Elicitation, ElicitationFormBuilder, validation } from "@leanmcp/elicitation";
|
|
321
|
+
---
|
|
482
322
|
|
|
483
|
-
|
|
484
|
-
@Tool({ description: "Create a new Slack channel" })
|
|
485
|
-
@Elicitation({
|
|
486
|
-
title: "Create Channel",
|
|
487
|
-
description: "Please provide channel details",
|
|
488
|
-
fields: [
|
|
489
|
-
{
|
|
490
|
-
name: "channelName",
|
|
491
|
-
label: "Channel Name",
|
|
492
|
-
type: "text",
|
|
493
|
-
required: true,
|
|
494
|
-
validation: {
|
|
495
|
-
pattern: "^[a-z0-9-]+$",
|
|
496
|
-
errorMessage: "Must be lowercase alphanumeric with hyphens"
|
|
497
|
-
}
|
|
498
|
-
},
|
|
499
|
-
{
|
|
500
|
-
name: "isPrivate",
|
|
501
|
-
label: "Private Channel",
|
|
502
|
-
type: "boolean",
|
|
503
|
-
defaultValue: false
|
|
504
|
-
}
|
|
505
|
-
]
|
|
506
|
-
})
|
|
507
|
-
async createChannel(args: { channelName: string; isPrivate: boolean }) {
|
|
508
|
-
return {
|
|
509
|
-
success: true,
|
|
510
|
-
channelId: `C${Date.now()}`,
|
|
511
|
-
channelName: args.channelName
|
|
512
|
-
};
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// Start server
|
|
517
|
-
const serverFactory = () => {
|
|
518
|
-
const server = new MCPServer({ name: "slack-server", version: "1.0.0" });
|
|
519
|
-
server.registerService(new SlackService());
|
|
520
|
-
return server.getServer();
|
|
521
|
-
};
|
|
522
|
-
|
|
523
|
-
await createHTTPServer(serverFactory, { port: 3000 });
|
|
524
|
-
```
|
|
525
|
-
|
|
526
|
-
## Error Handling
|
|
323
|
+
## Best Practices
|
|
527
324
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
console.error('Tool execution failed:', error);
|
|
534
|
-
}
|
|
535
|
-
```
|
|
325
|
+
1. **Use conditional elicitation** — Only ask when truly needed
|
|
326
|
+
2. **Provide sensible defaults** — Reduce user input burden
|
|
327
|
+
3. **Clear field labels** — Make fields self-explanatory
|
|
328
|
+
4. **Validate early** — Catch errors before submission
|
|
329
|
+
5. **Use builder for complex forms** — Fluent API is more maintainable
|
|
536
330
|
|
|
537
|
-
|
|
331
|
+
---
|
|
538
332
|
|
|
539
|
-
##
|
|
333
|
+
## Documentation
|
|
540
334
|
|
|
541
|
-
|
|
542
|
-
2. **Provide sensible defaults** - Reduce user input burden
|
|
543
|
-
3. **Clear field labels** - Make fields self-explanatory
|
|
544
|
-
4. **Validate early** - Catch errors before submission
|
|
545
|
-
5. **Group related fields** - Use multi-step for complex forms
|
|
546
|
-
6. **Test thoroughly** - Test both elicitation and execution paths
|
|
547
|
-
7. **Use builder for complex forms** - Fluent API is more maintainable
|
|
548
|
-
8. **Add help text** - Guide users with helpful descriptions
|
|
335
|
+
- [Full Documentation](https://docs.leanmcp.com/sdk/elicitation)
|
|
549
336
|
|
|
550
337
|
## Related Packages
|
|
551
338
|
|
|
552
|
-
- [@leanmcp/core](
|
|
553
|
-
- [@leanmcp/auth](
|
|
554
|
-
- [@leanmcp/
|
|
339
|
+
- [@leanmcp/core](https://www.npmjs.com/package/@leanmcp/core) — Core MCP server functionality
|
|
340
|
+
- [@leanmcp/auth](https://www.npmjs.com/package/@leanmcp/auth) — Authentication decorators
|
|
341
|
+
- [@leanmcp/cli](https://www.npmjs.com/package/@leanmcp/cli) — CLI for project scaffolding
|
|
555
342
|
|
|
556
343
|
## Links
|
|
557
344
|
|
|
558
345
|
- [GitHub Repository](https://github.com/LeanMCP/leanmcp-sdk)
|
|
559
|
-
- [
|
|
560
|
-
- [
|
|
346
|
+
- [NPM Package](https://www.npmjs.com/package/@leanmcp/elicitation)
|
|
347
|
+
- [MCP Specification](https://spec.modelcontextprotocol.io/)
|
|
561
348
|
|
|
562
349
|
## License
|
|
563
350
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leanmcp/elicitation",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Elicitation support for LeanMCP - structured user input collection",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -21,12 +21,18 @@
|
|
|
21
21
|
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
22
22
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
23
23
|
"clean": "rm -rf dist",
|
|
24
|
-
"test": "jest",
|
|
24
|
+
"test": "jest --passWithNoTests",
|
|
25
25
|
"lint": "eslint src"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"reflect-metadata": "^0.2.0"
|
|
29
29
|
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/jest": "^29.5.0",
|
|
32
|
+
"@types/node": "^20.0.0",
|
|
33
|
+
"jest": "^29.7.0",
|
|
34
|
+
"ts-jest": "^29.1.0"
|
|
35
|
+
},
|
|
30
36
|
"peerDependencies": {
|
|
31
37
|
"@leanmcp/core": "*"
|
|
32
38
|
},
|
|
@@ -55,4 +61,4 @@
|
|
|
55
61
|
"publishConfig": {
|
|
56
62
|
"access": "public"
|
|
57
63
|
}
|
|
58
|
-
}
|
|
64
|
+
}
|