@leanmcp/core 0.3.11 → 0.3.12
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 +37 -0
- package/dist/index.js +25 -2
- package/dist/index.mjs +25 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
- **Schema Generation** — Declarative JSON Schema with `@SchemaConstraint` decorators
|
|
37
37
|
- **HTTP Transport** — Production-ready HTTP server with session management
|
|
38
38
|
- **Input Validation** — Built-in AJV validation for all inputs
|
|
39
|
+
- **Structured Content** — Automatic `structuredContent` for ChatGPT Apps SDK compatibility
|
|
39
40
|
- **MCP Compliant** — Built on official `@modelcontextprotocol/sdk`
|
|
40
41
|
|
|
41
42
|
## Installation
|
|
@@ -358,6 +359,42 @@ export class SlackService {
|
|
|
358
359
|
|
|
359
360
|
---
|
|
360
361
|
|
|
362
|
+
## Structured Content
|
|
363
|
+
|
|
364
|
+
Tool return values are automatically exposed as `structuredContent` in the MCP response, enabling ChatGPT Apps SDK compatibility.
|
|
365
|
+
|
|
366
|
+
**Automatic Handling:**
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
@Tool({ description: 'List channels' })
|
|
370
|
+
async listChannels() {
|
|
371
|
+
// Return a plain object - it becomes structuredContent automatically
|
|
372
|
+
return { channels: [...] };
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
The response includes both `content` (text) and `structuredContent` (object):
|
|
377
|
+
|
|
378
|
+
```json
|
|
379
|
+
{
|
|
380
|
+
"content": [{ "type": "text", "text": "{\"channels\": [...]}" }],
|
|
381
|
+
"structuredContent": { "channels": [...] }
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**Manual MCP Response:**
|
|
386
|
+
|
|
387
|
+
If your tool returns a manual MCP response (with `content` array), the SDK extracts data from `content[0].text`:
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
return {
|
|
391
|
+
content: [{ type: 'text', text: JSON.stringify({ channels }) }]
|
|
392
|
+
};
|
|
393
|
+
// structuredContent will be { channels: [...] }
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
361
398
|
## HTTP Endpoints
|
|
362
399
|
|
|
363
400
|
| Endpoint | Method | Description |
|
package/dist/index.js
CHANGED
|
@@ -1161,10 +1161,27 @@ var init_index = __esm({
|
|
|
1161
1161
|
const meta = request.params._meta;
|
|
1162
1162
|
const result = await tool.method.call(tool.instance, request.params.arguments, meta);
|
|
1163
1163
|
let formattedResult = result;
|
|
1164
|
+
let structuredContent = void 0;
|
|
1164
1165
|
if (methodMeta.renderFormat === "markdown" && typeof result === "string") {
|
|
1165
1166
|
formattedResult = result;
|
|
1166
|
-
} else if (
|
|
1167
|
-
|
|
1167
|
+
} else if (typeof result === "object" && result !== null) {
|
|
1168
|
+
if ("structuredContent" in result && Object.keys(result).length === 1) {
|
|
1169
|
+
structuredContent = result.structuredContent;
|
|
1170
|
+
formattedResult = JSON.stringify(structuredContent, null, 2);
|
|
1171
|
+
} else if ("content" in result && Array.isArray(result.content)) {
|
|
1172
|
+
const textItem = result.content.find((c) => c.type === "text");
|
|
1173
|
+
if (textItem?.text) {
|
|
1174
|
+
try {
|
|
1175
|
+
structuredContent = JSON.parse(textItem.text);
|
|
1176
|
+
} catch {
|
|
1177
|
+
structuredContent = textItem.text;
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
formattedResult = JSON.stringify(result, null, 2);
|
|
1181
|
+
} else {
|
|
1182
|
+
structuredContent = result;
|
|
1183
|
+
formattedResult = JSON.stringify(result, null, 2);
|
|
1184
|
+
}
|
|
1168
1185
|
} else {
|
|
1169
1186
|
formattedResult = String(result);
|
|
1170
1187
|
}
|
|
@@ -1176,6 +1193,12 @@ var init_index = __esm({
|
|
|
1176
1193
|
}
|
|
1177
1194
|
]
|
|
1178
1195
|
};
|
|
1196
|
+
if (structuredContent) {
|
|
1197
|
+
response.structuredContent = structuredContent;
|
|
1198
|
+
if (this.logger) {
|
|
1199
|
+
this.logger.debug(`[MCPServer] Setting structuredContent: ${JSON.stringify(structuredContent).slice(0, 100)}...`);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1179
1202
|
if (tool._meta && Object.keys(tool._meta).length > 0) {
|
|
1180
1203
|
response._meta = tool._meta;
|
|
1181
1204
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1058,10 +1058,27 @@ var MCPServer = class {
|
|
|
1058
1058
|
const meta = request.params._meta;
|
|
1059
1059
|
const result = await tool.method.call(tool.instance, request.params.arguments, meta);
|
|
1060
1060
|
let formattedResult = result;
|
|
1061
|
+
let structuredContent = void 0;
|
|
1061
1062
|
if (methodMeta.renderFormat === "markdown" && typeof result === "string") {
|
|
1062
1063
|
formattedResult = result;
|
|
1063
|
-
} else if (
|
|
1064
|
-
|
|
1064
|
+
} else if (typeof result === "object" && result !== null) {
|
|
1065
|
+
if ("structuredContent" in result && Object.keys(result).length === 1) {
|
|
1066
|
+
structuredContent = result.structuredContent;
|
|
1067
|
+
formattedResult = JSON.stringify(structuredContent, null, 2);
|
|
1068
|
+
} else if ("content" in result && Array.isArray(result.content)) {
|
|
1069
|
+
const textItem = result.content.find((c) => c.type === "text");
|
|
1070
|
+
if (textItem?.text) {
|
|
1071
|
+
try {
|
|
1072
|
+
structuredContent = JSON.parse(textItem.text);
|
|
1073
|
+
} catch {
|
|
1074
|
+
structuredContent = textItem.text;
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
formattedResult = JSON.stringify(result, null, 2);
|
|
1078
|
+
} else {
|
|
1079
|
+
structuredContent = result;
|
|
1080
|
+
formattedResult = JSON.stringify(result, null, 2);
|
|
1081
|
+
}
|
|
1065
1082
|
} else {
|
|
1066
1083
|
formattedResult = String(result);
|
|
1067
1084
|
}
|
|
@@ -1073,6 +1090,12 @@ var MCPServer = class {
|
|
|
1073
1090
|
}
|
|
1074
1091
|
]
|
|
1075
1092
|
};
|
|
1093
|
+
if (structuredContent) {
|
|
1094
|
+
response.structuredContent = structuredContent;
|
|
1095
|
+
if (this.logger) {
|
|
1096
|
+
this.logger.debug(`[MCPServer] Setting structuredContent: ${JSON.stringify(structuredContent).slice(0, 100)}...`);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1076
1099
|
if (tool._meta && Object.keys(tool._meta).length > 0) {
|
|
1077
1100
|
response._meta = tool._meta;
|
|
1078
1101
|
}
|