@gavdi/cap-mcp 0.9.9 → 0.10.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 +47 -0
- package/lib/annotations/constants.js +2 -0
- package/lib/annotations/parser.js +18 -2
- package/lib/annotations/structures.js +12 -1
- package/lib/annotations/utils.js +18 -0
- package/lib/mcp/elicited-input.js +162 -0
- package/lib/mcp/tools.js +20 -25
- package/lib/mcp/utils.js +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -120,6 +120,7 @@ This plugin transforms your annotated CAP services into a fully functional MCP s
|
|
|
120
120
|
- **🔧 Tools**: Convert CAP functions and actions into executable MCP tools
|
|
121
121
|
- **🧩 Entity Wrappers (optional)**: Expose CAP entities as tools (`query`, `get`, and optionally `create`, `update`) for LLM tool use while keeping resources intact
|
|
122
122
|
- **💡 Prompts**: Define reusable prompt templates for AI interactions
|
|
123
|
+
- **⚡ Elicitation**: Request user confirmation or input parameters before tool execution
|
|
123
124
|
- **🔄 Auto-generation**: Automatically creates MCP server endpoints based on annotations
|
|
124
125
|
- **⚙️ Flexible Configuration**: Support for custom parameter sets and descriptions
|
|
125
126
|
|
|
@@ -231,6 +232,52 @@ extend projection Books with actions {
|
|
|
231
232
|
}
|
|
232
233
|
```
|
|
233
234
|
|
|
235
|
+
#### Tool Elicitation
|
|
236
|
+
|
|
237
|
+
Request user confirmation or input before tool execution using the `elicit` property:
|
|
238
|
+
|
|
239
|
+
```cds
|
|
240
|
+
// Request user confirmation before execution
|
|
241
|
+
@mcp: {
|
|
242
|
+
name : 'book-recommendation',
|
|
243
|
+
description: 'Get a random book recommendation',
|
|
244
|
+
tool : true,
|
|
245
|
+
elicit : ['confirm']
|
|
246
|
+
}
|
|
247
|
+
function getBookRecommendation() returns String;
|
|
248
|
+
|
|
249
|
+
// Request user input for parameters
|
|
250
|
+
@mcp: {
|
|
251
|
+
name : 'get-author',
|
|
252
|
+
description: 'Gets the desired author',
|
|
253
|
+
tool : true,
|
|
254
|
+
elicit : ['input']
|
|
255
|
+
}
|
|
256
|
+
function getAuthor(id: String) returns String;
|
|
257
|
+
|
|
258
|
+
// Request both input and confirmation
|
|
259
|
+
@mcp: {
|
|
260
|
+
name : 'books-by-author',
|
|
261
|
+
description: 'Gets a list of books made by the author',
|
|
262
|
+
tool : true,
|
|
263
|
+
elicit : ['input', 'confirm']
|
|
264
|
+
}
|
|
265
|
+
function getBooksByAuthor(authorName: String) returns array of String;
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
> NOTE: Elicitation is only available for direct tools at this moment. Wrapped entities are not covered by this.
|
|
269
|
+
|
|
270
|
+
**Elicit Types:**
|
|
271
|
+
- **`confirm`**: Requests user confirmation before executing the tool with a yes/no prompt
|
|
272
|
+
- **`input`**: Prompts the user to provide values for the tool's parameters
|
|
273
|
+
- **Combined**: Use both `['input', 'confirm']` to first collect parameters, then ask for confirmation
|
|
274
|
+
|
|
275
|
+
**User Experience:**
|
|
276
|
+
- **Confirmation**: "Please confirm that you want to perform action 'Get a random book recommendation'"
|
|
277
|
+
- **Input**: "Please fill out the required parameters" with a form for each parameter
|
|
278
|
+
- **User Actions**: Accept, decline, or cancel the elicitation request
|
|
279
|
+
- **Early Exit**: Tools return appropriate messages if declined or cancelled
|
|
280
|
+
|
|
234
281
|
### Prompt Templates
|
|
235
282
|
|
|
236
283
|
Define reusable AI prompt templates:
|
|
@@ -27,6 +27,8 @@ exports.MCP_ANNOTATION_PROPS = {
|
|
|
27
27
|
MCP_PROMPT: "@mcp.prompts",
|
|
28
28
|
/** Wrapper configuration for exposing entities as tools */
|
|
29
29
|
MCP_WRAP: "@mcp.wrap",
|
|
30
|
+
/** Elicited user input annotation for tools in CAP services */
|
|
31
|
+
MCP_ELICIT: "@mcp.elicit",
|
|
30
32
|
};
|
|
31
33
|
/**
|
|
32
34
|
* Set of annotations used for CDS auth annotations
|
|
@@ -26,6 +26,13 @@ function parseDefinitions(model) {
|
|
|
26
26
|
if (!parsedAnnotations || !(0, utils_1.containsRequiredAnnotations)(parsedAnnotations)) {
|
|
27
27
|
continue; // This check must occur here, since we do want the bound operations even if the parent is not annotated
|
|
28
28
|
}
|
|
29
|
+
// Set the target in annotations for error reporting
|
|
30
|
+
if (parsedAnnotations) {
|
|
31
|
+
parsedAnnotations.target = key;
|
|
32
|
+
}
|
|
33
|
+
if (!(0, utils_1.containsRequiredElicitedParams)(parsedAnnotations)) {
|
|
34
|
+
continue; // Really doesn't do anything as the method will throw if the implementation is invalid
|
|
35
|
+
}
|
|
29
36
|
const verifiedAnnotations = parsedAnnotations;
|
|
30
37
|
switch (def.kind) {
|
|
31
38
|
case "entity":
|
|
@@ -97,6 +104,9 @@ function parseAnnotations(definition) {
|
|
|
97
104
|
// Wrapper container to expose resources as tools
|
|
98
105
|
annotations.wrap = v;
|
|
99
106
|
continue;
|
|
107
|
+
case constants_1.MCP_ANNOTATION_PROPS.MCP_ELICIT:
|
|
108
|
+
annotations.elicit = v;
|
|
109
|
+
continue;
|
|
100
110
|
case constants_1.CDS_AUTH_ANNOTATIONS.REQUIRES:
|
|
101
111
|
annotations.requires = v;
|
|
102
112
|
continue;
|
|
@@ -139,7 +149,7 @@ function constructToolAnnotation(serviceName, target, annotations, entityKey, ke
|
|
|
139
149
|
return undefined;
|
|
140
150
|
const { parameters, operationKind } = (0, utils_1.parseOperationElements)(annotations);
|
|
141
151
|
const restrictions = (0, utils_1.parseCdsRestrictions)(annotations.restrict, annotations.requires);
|
|
142
|
-
return new structures_1.McpToolAnnotation(annotations.name, annotations.description, target, serviceName, parameters, entityKey, operationKind, keyParams, restrictions);
|
|
152
|
+
return new structures_1.McpToolAnnotation(annotations.name, annotations.description, target, serviceName, parameters, entityKey, operationKind, keyParams, restrictions, annotations.elicit);
|
|
143
153
|
}
|
|
144
154
|
/**
|
|
145
155
|
* Constructs a prompt annotation from parsed annotation data
|
|
@@ -172,7 +182,13 @@ function parseBoundOperations(serviceName, entityKey, definition, resultRef) {
|
|
|
172
182
|
if (v.kind !== "function" && v.kind !== "action")
|
|
173
183
|
continue;
|
|
174
184
|
const parsedAnnotations = parseAnnotations(v);
|
|
175
|
-
|
|
185
|
+
// Set the target in annotations for error reporting
|
|
186
|
+
if (parsedAnnotations) {
|
|
187
|
+
parsedAnnotations.target = k;
|
|
188
|
+
}
|
|
189
|
+
if (!parsedAnnotations ||
|
|
190
|
+
!(0, utils_1.containsRequiredAnnotations)(parsedAnnotations) ||
|
|
191
|
+
!(0, utils_1.containsRequiredElicitedParams)(parsedAnnotations)) {
|
|
176
192
|
continue;
|
|
177
193
|
}
|
|
178
194
|
const verifiedAnnotations = parsedAnnotations;
|
|
@@ -142,6 +142,8 @@ class McpToolAnnotation extends McpAnnotation {
|
|
|
142
142
|
_operationKind;
|
|
143
143
|
/** Map of key field names to their types for bound operations */
|
|
144
144
|
_keyTypeMap;
|
|
145
|
+
/** Elicited user input object */
|
|
146
|
+
_elicits;
|
|
145
147
|
/**
|
|
146
148
|
* Creates a new MCP tool annotation
|
|
147
149
|
* @param name - Unique identifier for this tool
|
|
@@ -153,13 +155,15 @@ class McpToolAnnotation extends McpAnnotation {
|
|
|
153
155
|
* @param operationKind - Optional operation type ('function' or 'action')
|
|
154
156
|
* @param keyTypeMap - Optional map of key fields to types for bound operations
|
|
155
157
|
* @param restrictions - Optional restrictions based on CDS roles
|
|
158
|
+
* @param elicits - Optional elicited input requirement
|
|
156
159
|
*/
|
|
157
|
-
constructor(name, description, operation, serviceName, parameters, entityKey, operationKind, keyTypeMap, restrictions) {
|
|
160
|
+
constructor(name, description, operation, serviceName, parameters, entityKey, operationKind, keyTypeMap, restrictions, elicits) {
|
|
158
161
|
super(name, description, operation, serviceName, restrictions ?? []);
|
|
159
162
|
this._parameters = parameters;
|
|
160
163
|
this._entityKey = entityKey;
|
|
161
164
|
this._operationKind = operationKind;
|
|
162
165
|
this._keyTypeMap = keyTypeMap;
|
|
166
|
+
this._elicits = elicits;
|
|
163
167
|
}
|
|
164
168
|
/**
|
|
165
169
|
* Gets the map of function parameters to their CDS types
|
|
@@ -189,6 +193,13 @@ class McpToolAnnotation extends McpAnnotation {
|
|
|
189
193
|
get keyTypeMap() {
|
|
190
194
|
return this._keyTypeMap;
|
|
191
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* Gets the elicited user input if any is required for the tool
|
|
198
|
+
* @returns Elicited user input object
|
|
199
|
+
*/
|
|
200
|
+
get elicits() {
|
|
201
|
+
return this._elicits;
|
|
202
|
+
}
|
|
192
203
|
}
|
|
193
204
|
exports.McpToolAnnotation = McpToolAnnotation;
|
|
194
205
|
/**
|
package/lib/annotations/utils.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.splitDefinitionName = splitDefinitionName;
|
|
4
4
|
exports.containsMcpAnnotation = containsMcpAnnotation;
|
|
5
5
|
exports.containsRequiredAnnotations = containsRequiredAnnotations;
|
|
6
|
+
exports.containsRequiredElicitedParams = containsRequiredElicitedParams;
|
|
6
7
|
exports.isValidResourceAnnotation = isValidResourceAnnotation;
|
|
7
8
|
exports.isValidToolAnnotation = isValidToolAnnotation;
|
|
8
9
|
exports.isValidPromptsAnnotation = isValidPromptsAnnotation;
|
|
@@ -55,6 +56,21 @@ function containsRequiredAnnotations(annotations) {
|
|
|
55
56
|
}
|
|
56
57
|
return true;
|
|
57
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Validates that the required params for MCP elicited user input annotations are valid
|
|
61
|
+
* @param annotations - The annotation structure to validate
|
|
62
|
+
* @returns True if valid, throw error if invalid
|
|
63
|
+
* @throws Error if required annotations are missing
|
|
64
|
+
*/
|
|
65
|
+
function containsRequiredElicitedParams(annotations) {
|
|
66
|
+
if (!annotations.elicit)
|
|
67
|
+
return true;
|
|
68
|
+
const param = annotations.elicit;
|
|
69
|
+
if (!param || param?.length <= 0) {
|
|
70
|
+
throw new Error(`Invalid annotation '${annotations.target}' - Incomplete elicited user input`);
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
58
74
|
/**
|
|
59
75
|
* Validates a resource annotation structure
|
|
60
76
|
* @param annotations - The annotation structure to validate
|
|
@@ -181,6 +197,8 @@ function parseOperationElements(annotations) {
|
|
|
181
197
|
*/
|
|
182
198
|
function parseEntityKeys(definition) {
|
|
183
199
|
const result = new Map();
|
|
200
|
+
if (!definition?.elements)
|
|
201
|
+
return result; // If there is no defined elements, we exit early
|
|
184
202
|
for (const [k, v] of Object.entries(definition.elements)) {
|
|
185
203
|
if (!v.key)
|
|
186
204
|
continue;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isElicitInput = isElicitInput;
|
|
4
|
+
exports.constructElicitationFunctions = constructElicitationFunctions;
|
|
5
|
+
exports.handleElicitationRequests = handleElicitationRequests;
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
/**
|
|
8
|
+
* Message displayed to users when requesting input parameters
|
|
9
|
+
*/
|
|
10
|
+
const INPUT_MSG = "Please fill out the required parameters";
|
|
11
|
+
/**
|
|
12
|
+
* Checks if the elicited input array contains an 'input' requirement
|
|
13
|
+
* @param elicits - Array of elicit types or undefined
|
|
14
|
+
* @returns True if 'input' elicitation is required, false otherwise
|
|
15
|
+
*/
|
|
16
|
+
function isElicitInput(elicits) {
|
|
17
|
+
return elicits ? elicits.includes("input") : false;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Constructs elicitation request parameters based on the tool annotation's elicit requirements
|
|
21
|
+
* @param model - MCP tool annotation containing elicit configuration
|
|
22
|
+
* @param params - Parameter definitions for the tool
|
|
23
|
+
* @returns Array of elicit request parameters for MCP server
|
|
24
|
+
* @throws Error if invalid elicitation type is encountered
|
|
25
|
+
*/
|
|
26
|
+
function constructElicitationFunctions(model, params) {
|
|
27
|
+
const result = [];
|
|
28
|
+
for (const el of model.elicits ?? []) {
|
|
29
|
+
switch (el) {
|
|
30
|
+
case "input":
|
|
31
|
+
result.push(constructElicitInput(params));
|
|
32
|
+
continue;
|
|
33
|
+
case "confirm":
|
|
34
|
+
result.push(contructElicitConfirm(model));
|
|
35
|
+
continue;
|
|
36
|
+
default:
|
|
37
|
+
throw new Error("Invalid elicitation type");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Processes multiple elicitation requests sequentially and handles user responses
|
|
44
|
+
* @param requests - Array of elicit request parameters or undefined
|
|
45
|
+
* @param server - MCP server instance for making elicit calls
|
|
46
|
+
* @returns Promise resolving to elicitation response with early exit or data
|
|
47
|
+
*/
|
|
48
|
+
async function handleElicitationRequests(requests, server) {
|
|
49
|
+
if (!requests || requests.length <= 0) {
|
|
50
|
+
return { earlyResponse: undefined };
|
|
51
|
+
}
|
|
52
|
+
let data = undefined;
|
|
53
|
+
for (const req of requests) {
|
|
54
|
+
const res = await server.server.elicitInput(req);
|
|
55
|
+
const earlyResponse = handleElicitResponse(res);
|
|
56
|
+
if (earlyResponse) {
|
|
57
|
+
return { earlyResponse };
|
|
58
|
+
}
|
|
59
|
+
if (req.message === INPUT_MSG) {
|
|
60
|
+
data = res.content;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
earlyResponse: undefined,
|
|
65
|
+
data,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Converts elicit response action into appropriate MCP result
|
|
70
|
+
* @param elicitResponse - Result from MCP server elicit input call
|
|
71
|
+
* @returns MCP result for decline/cancel actions, undefined for accept
|
|
72
|
+
* @throws Error if invalid response action is received
|
|
73
|
+
*/
|
|
74
|
+
function handleElicitResponse(elicitResponse) {
|
|
75
|
+
switch (elicitResponse.action) {
|
|
76
|
+
case "accept":
|
|
77
|
+
return undefined;
|
|
78
|
+
case "decline":
|
|
79
|
+
return {
|
|
80
|
+
content: [
|
|
81
|
+
{
|
|
82
|
+
type: "text",
|
|
83
|
+
text: "Action was declined.",
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
};
|
|
87
|
+
case "cancel":
|
|
88
|
+
return {
|
|
89
|
+
content: [
|
|
90
|
+
{
|
|
91
|
+
type: "text",
|
|
92
|
+
text: "Action was cancelled",
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
default:
|
|
97
|
+
throw new Error("Invalid elicit response received");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Determines the schema type for elicit input based on Zod parameter type
|
|
102
|
+
* @param param - Zod schema parameter to analyze
|
|
103
|
+
* @returns Corresponding elicit schema type string
|
|
104
|
+
* @throws Error if parameter type is not supported for elicitation
|
|
105
|
+
*/
|
|
106
|
+
function determineSchemaType(param) {
|
|
107
|
+
if (param instanceof zod_1.z.ZodBoolean) {
|
|
108
|
+
return "boolean";
|
|
109
|
+
}
|
|
110
|
+
else if (param instanceof zod_1.z.ZodString) {
|
|
111
|
+
return "string";
|
|
112
|
+
}
|
|
113
|
+
else if (param instanceof zod_1.z.ZodNumber) {
|
|
114
|
+
return "number";
|
|
115
|
+
}
|
|
116
|
+
throw new Error("Unsupported elicitation input type");
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Constructs confirmation elicit request for tool execution
|
|
120
|
+
* @param model - MCP annotation model containing tool description
|
|
121
|
+
* @returns Elicit request parameters for user confirmation
|
|
122
|
+
*/
|
|
123
|
+
function contructElicitConfirm(model) {
|
|
124
|
+
return {
|
|
125
|
+
message: `Please confirm that you want to perform action '${model.description}'`,
|
|
126
|
+
requestedSchema: {
|
|
127
|
+
type: "object",
|
|
128
|
+
properties: {
|
|
129
|
+
confirm: {
|
|
130
|
+
type: "boolean",
|
|
131
|
+
title: "Confirmation",
|
|
132
|
+
description: "Please confirm the action",
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
required: ["confirm"],
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Constructs input elicit request for tool parameters
|
|
141
|
+
* @param params - Tool parameters definition with Zod schemas
|
|
142
|
+
* @returns Elicit request parameters for user input collection
|
|
143
|
+
*/
|
|
144
|
+
function constructElicitInput(params) {
|
|
145
|
+
const elicitSpec = {
|
|
146
|
+
message: INPUT_MSG,
|
|
147
|
+
requestedSchema: {
|
|
148
|
+
type: "object",
|
|
149
|
+
properties: {},
|
|
150
|
+
required: [],
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
for (const [key, zodType] of Object.entries(params)) {
|
|
154
|
+
elicitSpec.requestedSchema.required?.push(key);
|
|
155
|
+
elicitSpec.requestedSchema.properties[key] = {
|
|
156
|
+
type: determineSchemaType(zodType),
|
|
157
|
+
title: key,
|
|
158
|
+
description: key,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
return elicitSpec;
|
|
162
|
+
}
|
package/lib/mcp/tools.js
CHANGED
|
@@ -6,6 +6,7 @@ const logger_1 = require("../logger");
|
|
|
6
6
|
const constants_1 = require("./constants");
|
|
7
7
|
const zod_1 = require("zod");
|
|
8
8
|
const utils_2 = require("../auth/utils");
|
|
9
|
+
const elicited_input_1 = require("./elicited-input");
|
|
9
10
|
/* @ts-ignore */
|
|
10
11
|
const cds = global.cds || require("@sap/cds"); // This is a work around for missing cds context
|
|
11
12
|
/**
|
|
@@ -37,7 +38,12 @@ function assignBoundOperation(params, model, server, authEnabled) {
|
|
|
37
38
|
throw new Error("Bound operation cannot be assigned to tool list, missing keys");
|
|
38
39
|
}
|
|
39
40
|
const keys = buildToolParameters(model.keyTypeMap);
|
|
40
|
-
const
|
|
41
|
+
const useElicitInput = (0, elicited_input_1.isElicitInput)(model.elicits);
|
|
42
|
+
const inputSchema = buildZodSchema({
|
|
43
|
+
...keys,
|
|
44
|
+
...(useElicitInput ? {} : params),
|
|
45
|
+
});
|
|
46
|
+
const elicitationRequests = (0, elicited_input_1.constructElicitationFunctions)(model, params);
|
|
41
47
|
server.registerTool(model.name, {
|
|
42
48
|
title: model.name,
|
|
43
49
|
description: model.description,
|
|
@@ -69,11 +75,15 @@ function assignBoundOperation(params, model, server, authEnabled) {
|
|
|
69
75
|
continue;
|
|
70
76
|
operationInput[k] = v;
|
|
71
77
|
}
|
|
78
|
+
const elicitationResult = await (0, elicited_input_1.handleElicitationRequests)(elicitationRequests, server);
|
|
79
|
+
if (elicitationResult?.earlyResponse) {
|
|
80
|
+
return elicitationResult.earlyResponse;
|
|
81
|
+
}
|
|
72
82
|
const accessRights = (0, utils_2.getAccessRights)(authEnabled);
|
|
73
83
|
const response = await service.tx({ user: accessRights }).send({
|
|
74
84
|
event: model.target,
|
|
75
85
|
entity: model.entityKey,
|
|
76
|
-
data: operationInput,
|
|
86
|
+
data: elicitationResult?.data ?? operationInput,
|
|
77
87
|
params: [operationKeys],
|
|
78
88
|
});
|
|
79
89
|
return (0, utils_1.asMcpResult)(response);
|
|
@@ -87,7 +97,9 @@ function assignBoundOperation(params, model, server, authEnabled) {
|
|
|
87
97
|
* @param server - MCP server instance to register with
|
|
88
98
|
*/
|
|
89
99
|
function assignUnboundOperation(params, model, server, authEnabled) {
|
|
90
|
-
const
|
|
100
|
+
const useElicitInput = (0, elicited_input_1.isElicitInput)(model.elicits);
|
|
101
|
+
const inputSchema = buildZodSchema(useElicitInput ? {} : params);
|
|
102
|
+
const elicitationRequests = (0, elicited_input_1.constructElicitationFunctions)(model, params);
|
|
91
103
|
server.registerTool(model.name, {
|
|
92
104
|
title: model.name,
|
|
93
105
|
description: model.description,
|
|
@@ -109,10 +121,14 @@ function assignUnboundOperation(params, model, server, authEnabled) {
|
|
|
109
121
|
],
|
|
110
122
|
};
|
|
111
123
|
}
|
|
124
|
+
const elicitationResult = await (0, elicited_input_1.handleElicitationRequests)(elicitationRequests, server);
|
|
125
|
+
if (elicitationResult?.earlyResponse) {
|
|
126
|
+
return elicitationResult.earlyResponse;
|
|
127
|
+
}
|
|
112
128
|
const accessRights = (0, utils_2.getAccessRights)(authEnabled);
|
|
113
129
|
const response = await service
|
|
114
130
|
.tx({ user: accessRights })
|
|
115
|
-
.send(model.target, args);
|
|
131
|
+
.send(model.target, elicitationResult?.data ?? args);
|
|
116
132
|
return (0, utils_1.asMcpResult)(response);
|
|
117
133
|
});
|
|
118
134
|
}
|
|
@@ -130,27 +146,6 @@ function buildToolParameters(params) {
|
|
|
130
146
|
}
|
|
131
147
|
return result;
|
|
132
148
|
}
|
|
133
|
-
/**
|
|
134
|
-
* Converts a value to a string representation suitable for MCP responses
|
|
135
|
-
* Handles objects and arrays by JSON stringifying them instead of using String()
|
|
136
|
-
* @param value - The value to convert to string
|
|
137
|
-
* @returns String representation of the value
|
|
138
|
-
*/
|
|
139
|
-
function formatResponseValue(value) {
|
|
140
|
-
if (value === null || value === undefined) {
|
|
141
|
-
return String(value);
|
|
142
|
-
}
|
|
143
|
-
if (typeof value === "object") {
|
|
144
|
-
try {
|
|
145
|
-
return JSON.stringify(value, null, 2);
|
|
146
|
-
}
|
|
147
|
-
catch (error) {
|
|
148
|
-
// Fallback to String() if JSON.stringify fails (e.g., circular references)
|
|
149
|
-
return String(value);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return String(value);
|
|
153
|
-
}
|
|
154
149
|
/**
|
|
155
150
|
* Constructs a complete Zod schema object for MCP tool input validation
|
|
156
151
|
* @param params - Record of parameter names to Zod schema types
|
package/lib/mcp/utils.js
CHANGED