@jaypie/mcp 0.3.2 → 0.4.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/dist/createMcpServer.d.ts +7 -1
- package/dist/index.js +26 -3135
- package/dist/index.js.map +1 -1
- package/dist/suite.d.ts +1 -0
- package/dist/suite.js +2442 -0
- package/dist/suite.js.map +1 -0
- package/package.json +8 -3
- package/release-notes/constructs/1.2.17.md +11 -0
- package/release-notes/fabric/0.1.2.md +11 -0
- package/release-notes/fabric/0.1.3.md +25 -0
- package/release-notes/fabric/0.1.4.md +42 -0
- package/release-notes/mcp/0.3.3.md +12 -0
- package/release-notes/mcp/0.3.4.md +36 -0
- package/release-notes/mcp/0.4.0.md +27 -0
- package/release-notes/testkit/1.2.15.md +23 -0
- package/skills/agents.md +25 -0
- package/skills/aws.md +107 -0
- package/skills/cdk.md +141 -0
- package/skills/cicd.md +152 -0
- package/skills/datadog.md +129 -0
- package/skills/debugging.md +148 -0
- package/skills/dns.md +134 -0
- package/skills/dynamodb.md +140 -0
- package/skills/errors.md +142 -0
- package/skills/fabric.md +191 -0
- package/skills/index.md +7 -0
- package/skills/jaypie.md +100 -0
- package/skills/legacy.md +97 -0
- package/skills/logs.md +160 -0
- package/skills/mocks.md +174 -0
- package/skills/models.md +195 -0
- package/skills/releasenotes.md +94 -0
- package/skills/secrets.md +155 -0
- package/skills/services.md +175 -0
- package/skills/style.md +190 -0
- package/skills/tests.md +209 -0
- package/skills/tools.md +127 -0
- package/skills/topics.md +116 -0
- package/skills/variables.md +146 -0
- package/skills/writing.md +153 -0
- package/prompts/Branch_Management.md +0 -34
- package/prompts/Development_Process.md +0 -89
- package/prompts/Jaypie_Agent_Rules.md +0 -110
- package/prompts/Jaypie_Auth0_Express_Mongoose.md +0 -736
- package/prompts/Jaypie_Browser_and_Frontend_Web_Packages.md +0 -18
- package/prompts/Jaypie_CDK_Constructs_and_Patterns.md +0 -430
- package/prompts/Jaypie_CICD_with_GitHub_Actions.md +0 -371
- package/prompts/Jaypie_Commander_CLI_Package.md +0 -166
- package/prompts/Jaypie_Core_Errors_and_Logging.md +0 -39
- package/prompts/Jaypie_DynamoDB_Package.md +0 -774
- package/prompts/Jaypie_Eslint_NPM_Package.md +0 -78
- package/prompts/Jaypie_Express_Package.md +0 -630
- package/prompts/Jaypie_Fabric_Commander.md +0 -411
- package/prompts/Jaypie_Fabric_LLM.md +0 -312
- package/prompts/Jaypie_Fabric_Lambda.md +0 -308
- package/prompts/Jaypie_Fabric_MCP.md +0 -316
- package/prompts/Jaypie_Fabric_Package.md +0 -513
- package/prompts/Jaypie_Fabricator.md +0 -617
- package/prompts/Jaypie_Ideal_Project_Structure.md +0 -78
- package/prompts/Jaypie_Init_CICD_with_GitHub_Actions.md +0 -1186
- package/prompts/Jaypie_Init_Express_on_Lambda.md +0 -115
- package/prompts/Jaypie_Init_Jaypie_CDK_Package.md +0 -35
- package/prompts/Jaypie_Init_Lambda_Package.md +0 -505
- package/prompts/Jaypie_Init_Monorepo_Project.md +0 -44
- package/prompts/Jaypie_Init_Project_Subpackage.md +0 -65
- package/prompts/Jaypie_Legacy_Patterns.md +0 -15
- package/prompts/Jaypie_Llm_Calls.md +0 -449
- package/prompts/Jaypie_Llm_Tools.md +0 -155
- package/prompts/Jaypie_MCP_Package.md +0 -281
- package/prompts/Jaypie_Mocks_and_Testkit.md +0 -137
- package/prompts/Jaypie_Repokit.md +0 -103
- package/prompts/Jaypie_Scrub.md +0 -177
- package/prompts/Jaypie_Streaming.md +0 -467
- package/prompts/Templates_CDK_Subpackage.md +0 -115
- package/prompts/Templates_Express_Subpackage.md +0 -187
- package/prompts/Templates_Project_Monorepo.md +0 -326
- package/prompts/Templates_Project_Subpackage.md +0 -93
- package/prompts/Write_Efficient_Prompt_Guides.md +0 -48
- package/prompts/Write_and_Maintain_Engaging_Readme.md +0 -67
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: AWS Lambda integration with fabricService for event processing and callbacks
|
|
3
|
-
include: "**/lambda/**"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Jaypie Fabric Lambda Adapter
|
|
7
|
-
|
|
8
|
-
The Lambda adapter (`@jaypie/fabric/lambda`) wraps Jaypie service handlers for use as AWS Lambda handlers, providing automatic event parsing, secrets management, and lifecycle hooks.
|
|
9
|
-
|
|
10
|
-
**See also:** [Jaypie_Fabric_Package.md](Jaypie_Fabric_Package.md) for core fabricService documentation.
|
|
11
|
-
|
|
12
|
-
## Installation
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
npm install @jaypie/fabric
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Quick Start
|
|
19
|
-
|
|
20
|
-
```typescript
|
|
21
|
-
import { fabricService } from "@jaypie/fabric";
|
|
22
|
-
import { fabricLambda } from "@jaypie/fabric/lambda";
|
|
23
|
-
|
|
24
|
-
const handler = fabricService({
|
|
25
|
-
alias: "processOrder",
|
|
26
|
-
input: { orderId: { type: String } },
|
|
27
|
-
service: async ({ orderId }) => {
|
|
28
|
-
return { orderId, status: "processed" };
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
export const lambdaHandler = fabricLambda({ service: handler });
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## fabricLambda
|
|
36
|
-
|
|
37
|
-
Wraps a fabricService for use as an AWS Lambda handler.
|
|
38
|
-
|
|
39
|
-
### Options
|
|
40
|
-
|
|
41
|
-
| Option | Type | Description |
|
|
42
|
-
|--------|------|-------------|
|
|
43
|
-
| `service` | `Service` | Required. The service handler to wrap |
|
|
44
|
-
| `chaos` | `string` | Chaos testing mode |
|
|
45
|
-
| `name` | `string` | Override handler name for logging (default: handler.alias) |
|
|
46
|
-
| `onComplete` | `OnCompleteCallback` | Called with handler's return value on success |
|
|
47
|
-
| `onError` | `OnErrorCallback` | Receives errors reported via `context.onError()` in service |
|
|
48
|
-
| `onFatal` | `OnFatalCallback` | Receives fatal errors (thrown or via `context.onFatal()`) |
|
|
49
|
-
| `onMessage` | `OnMessageCallback` | Receives messages from `context.sendMessage` |
|
|
50
|
-
| `secrets` | `string[]` | AWS secrets to load into process.env |
|
|
51
|
-
| `setup` | `LifecycleFunction[]` | Functions to run before handler |
|
|
52
|
-
| `teardown` | `LifecycleFunction[]` | Functions to run after handler (always runs) |
|
|
53
|
-
| `throw` | `boolean` | Re-throw errors instead of returning error response |
|
|
54
|
-
| `unavailable` | `boolean` | Return 503 Unavailable immediately |
|
|
55
|
-
| `validate` | `ValidatorFunction[]` | Validation functions to run before handler |
|
|
56
|
-
|
|
57
|
-
## Lifecycle Callbacks
|
|
58
|
-
|
|
59
|
-
Services can use context callbacks to report progress, errors, and completion:
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
import { fabricService } from "@jaypie/fabric";
|
|
63
|
-
import { fabricLambda } from "@jaypie/fabric/lambda";
|
|
64
|
-
|
|
65
|
-
const handler = fabricService({
|
|
66
|
-
alias: "evaluate",
|
|
67
|
-
input: { jobId: { type: String } },
|
|
68
|
-
service: async ({ jobId }, context) => {
|
|
69
|
-
context?.sendMessage?.({ content: `Starting job ${jobId}` });
|
|
70
|
-
|
|
71
|
-
// Handle recoverable errors without throwing
|
|
72
|
-
try {
|
|
73
|
-
await riskyOperation();
|
|
74
|
-
} catch (err) {
|
|
75
|
-
context?.onError?.(err); // Reports error but continues
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// For fatal errors, either throw or call context.onFatal()
|
|
79
|
-
if (criticalFailure) {
|
|
80
|
-
context?.onFatal?.(new Error("Cannot continue"));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return { jobId, status: "complete" };
|
|
84
|
-
},
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
export const lambdaHandler = fabricLambda({
|
|
88
|
-
service: handler,
|
|
89
|
-
onComplete: (response) => {
|
|
90
|
-
console.log("Done:", JSON.stringify(response, null, 2));
|
|
91
|
-
},
|
|
92
|
-
onError: (error) => {
|
|
93
|
-
// Recoverable errors reported via context.onError()
|
|
94
|
-
console.error("Warning:", error);
|
|
95
|
-
},
|
|
96
|
-
onFatal: (error) => {
|
|
97
|
-
// Fatal errors (thrown or via context.onFatal())
|
|
98
|
-
console.error("Fatal:", error);
|
|
99
|
-
},
|
|
100
|
-
onMessage: (msg) => {
|
|
101
|
-
console.log(`[${msg.level || "info"}] ${msg.content}`);
|
|
102
|
-
},
|
|
103
|
-
});
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
**Error handling**: Services receive `context.onError()` and `context.onFatal()` callbacks to report errors without throwing. Any error that escapes the service (is thrown) is treated as fatal and routes to `onFatal`. If `onFatal` is not provided, thrown errors fall back to `onError`. Callback errors are swallowed to ensure failures never halt service execution.
|
|
107
|
-
|
|
108
|
-
## Secrets Management
|
|
109
|
-
|
|
110
|
-
Automatically loads AWS Secrets Manager values into `process.env`:
|
|
111
|
-
|
|
112
|
-
```typescript
|
|
113
|
-
export const lambdaHandler = fabricLambda({
|
|
114
|
-
service: handler,
|
|
115
|
-
secrets: ["ANTHROPIC_API_KEY", "DATABASE_URL"],
|
|
116
|
-
});
|
|
117
|
-
// Before handler runs, secrets are fetched and available as:
|
|
118
|
-
// process.env.ANTHROPIC_API_KEY
|
|
119
|
-
// process.env.DATABASE_URL
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## Lifecycle Hooks
|
|
123
|
-
|
|
124
|
-
### setup
|
|
125
|
-
|
|
126
|
-
Functions to run before the handler:
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
export const lambdaHandler = fabricLambda({
|
|
130
|
-
service: handler,
|
|
131
|
-
setup: [
|
|
132
|
-
async () => {
|
|
133
|
-
await initializeDatabase();
|
|
134
|
-
},
|
|
135
|
-
async () => {
|
|
136
|
-
await warmCache();
|
|
137
|
-
},
|
|
138
|
-
],
|
|
139
|
-
});
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### teardown
|
|
143
|
-
|
|
144
|
-
Functions to run after the handler (always runs, even on error):
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
export const lambdaHandler = fabricLambda({
|
|
148
|
-
service: handler,
|
|
149
|
-
teardown: [
|
|
150
|
-
async () => {
|
|
151
|
-
await closeConnections();
|
|
152
|
-
},
|
|
153
|
-
],
|
|
154
|
-
});
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### validate
|
|
158
|
-
|
|
159
|
-
Validation functions to run before handler. If any returns falsy or throws, handler is skipped:
|
|
160
|
-
|
|
161
|
-
```typescript
|
|
162
|
-
export const lambdaHandler = fabricLambda({
|
|
163
|
-
service: handler,
|
|
164
|
-
validate: [
|
|
165
|
-
(event) => event.headers?.authorization !== undefined,
|
|
166
|
-
async (event) => {
|
|
167
|
-
const token = event.headers?.authorization;
|
|
168
|
-
return await verifyToken(token);
|
|
169
|
-
},
|
|
170
|
-
],
|
|
171
|
-
});
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
## Event Handling
|
|
175
|
-
|
|
176
|
-
The adapter uses `getMessages()` from `@jaypie/aws` to extract messages from various event types:
|
|
177
|
-
|
|
178
|
-
- **SQS Events**: Extracts message body from each record
|
|
179
|
-
- **SNS Events**: Extracts message from SNS notification
|
|
180
|
-
- **Direct Invocation**: Uses event body directly
|
|
181
|
-
|
|
182
|
-
### Single vs Multiple Messages
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
// Single message returns single response
|
|
186
|
-
const result = await lambdaHandler(singleMessageEvent);
|
|
187
|
-
// result: { orderId: "123", status: "processed" }
|
|
188
|
-
|
|
189
|
-
// Multiple messages return array of responses
|
|
190
|
-
const results = await lambdaHandler(sqsBatchEvent);
|
|
191
|
-
// results: [
|
|
192
|
-
// { orderId: "123", status: "processed" },
|
|
193
|
-
// { orderId: "456", status: "processed" },
|
|
194
|
-
// ]
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
## Complete Example
|
|
198
|
-
|
|
199
|
-
```typescript
|
|
200
|
-
import { fabricService } from "@jaypie/fabric";
|
|
201
|
-
import { fabricLambda } from "@jaypie/fabric/lambda";
|
|
202
|
-
import log from "@jaypie/logger";
|
|
203
|
-
|
|
204
|
-
const processOrderHandler = fabricService({
|
|
205
|
-
alias: "processOrder",
|
|
206
|
-
description: "Process an incoming order",
|
|
207
|
-
input: {
|
|
208
|
-
orderId: { type: String, description: "Order ID to process" },
|
|
209
|
-
priority: { type: [1, 2, 3], default: 2 },
|
|
210
|
-
rush: { type: Boolean, default: false },
|
|
211
|
-
},
|
|
212
|
-
service: async ({ orderId, priority, rush }, context) => {
|
|
213
|
-
context?.sendMessage?.({ content: `Processing order ${orderId}` });
|
|
214
|
-
|
|
215
|
-
if (rush) {
|
|
216
|
-
context?.sendMessage?.({ content: "Rush order - expediting", level: "warn" });
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// Process the order...
|
|
220
|
-
await processOrder(orderId, { priority, rush });
|
|
221
|
-
|
|
222
|
-
context?.sendMessage?.({ content: "Order processed successfully" });
|
|
223
|
-
return { orderId, status: "complete", priority, rush };
|
|
224
|
-
},
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
export const handler = fabricLambda({
|
|
228
|
-
service: processOrderHandler,
|
|
229
|
-
name: "order-processor",
|
|
230
|
-
secrets: ["DATABASE_URL", "STRIPE_API_KEY"],
|
|
231
|
-
setup: [
|
|
232
|
-
async () => {
|
|
233
|
-
await connectToDatabase();
|
|
234
|
-
},
|
|
235
|
-
],
|
|
236
|
-
teardown: [
|
|
237
|
-
async () => {
|
|
238
|
-
await flushMetrics();
|
|
239
|
-
},
|
|
240
|
-
],
|
|
241
|
-
onMessage: (msg) => {
|
|
242
|
-
log[msg.level || "info"](msg.content);
|
|
243
|
-
},
|
|
244
|
-
});
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
## Error Handling
|
|
248
|
-
|
|
249
|
-
### Default Behavior
|
|
250
|
-
|
|
251
|
-
Errors are caught and returned as structured error responses:
|
|
252
|
-
|
|
253
|
-
```typescript
|
|
254
|
-
// On error, returns:
|
|
255
|
-
{
|
|
256
|
-
error: true,
|
|
257
|
-
message: "Error message",
|
|
258
|
-
statusCode: 500,
|
|
259
|
-
// ... additional error details
|
|
260
|
-
}
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
### Re-throwing Errors
|
|
264
|
-
|
|
265
|
-
Set `throw: true` to re-throw errors (useful for SQS retry behavior):
|
|
266
|
-
|
|
267
|
-
```typescript
|
|
268
|
-
export const lambdaHandler = fabricLambda({
|
|
269
|
-
service: handler,
|
|
270
|
-
throw: true, // Errors will propagate, triggering SQS retry
|
|
271
|
-
});
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
## TypeScript Types
|
|
275
|
-
|
|
276
|
-
```typescript
|
|
277
|
-
import type {
|
|
278
|
-
FabricLambdaConfig,
|
|
279
|
-
FabricLambdaOptions,
|
|
280
|
-
LambdaContext,
|
|
281
|
-
OnCompleteCallback,
|
|
282
|
-
OnErrorCallback,
|
|
283
|
-
OnFatalCallback,
|
|
284
|
-
OnMessageCallback,
|
|
285
|
-
} from "@jaypie/fabric/lambda";
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
## Exports
|
|
289
|
-
|
|
290
|
-
```typescript
|
|
291
|
-
// @jaypie/fabric/lambda
|
|
292
|
-
export { fabricLambda } from "./fabricLambda.js";
|
|
293
|
-
|
|
294
|
-
export type {
|
|
295
|
-
FabricLambdaConfig,
|
|
296
|
-
FabricLambdaOptions,
|
|
297
|
-
LambdaContext,
|
|
298
|
-
OnCompleteCallback,
|
|
299
|
-
OnErrorCallback,
|
|
300
|
-
OnFatalCallback,
|
|
301
|
-
OnMessageCallback,
|
|
302
|
-
} from "./types.js";
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
## Related
|
|
306
|
-
|
|
307
|
-
- [Jaypie_Fabric_Package.md](Jaypie_Fabric_Package.md) - Core fabricService and type conversion
|
|
308
|
-
- [Jaypie_Init_Lambda_Package.md](Jaypie_Init_Lambda_Package.md) - Setting up Lambda projects
|
|
@@ -1,316 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: MCP server tool registration from fabricService
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Jaypie Fabric MCP Adapter
|
|
6
|
-
|
|
7
|
-
The MCP adapter (`@jaypie/fabric/mcp`) registers Jaypie service handlers as MCP (Model Context Protocol) tools for use with MCP servers.
|
|
8
|
-
|
|
9
|
-
**See also:** [Jaypie_Fabric_Package.md](Jaypie_Fabric_Package.md) for core fabricService documentation.
|
|
10
|
-
|
|
11
|
-
## Installation
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm install @jaypie/fabric @modelcontextprotocol/sdk
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Quick Start
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
21
|
-
import { fabricService } from "@jaypie/fabric";
|
|
22
|
-
import { fabricMcp } from "@jaypie/fabric/mcp";
|
|
23
|
-
|
|
24
|
-
const handler = fabricService({
|
|
25
|
-
alias: "greet",
|
|
26
|
-
description: "Greet a user by name",
|
|
27
|
-
input: {
|
|
28
|
-
userName: { type: String, description: "The user's name" },
|
|
29
|
-
loud: { type: Boolean, default: false, description: "Shout the greeting" },
|
|
30
|
-
},
|
|
31
|
-
service: ({ userName, loud }) => {
|
|
32
|
-
const greeting = `Hello, ${userName}!`;
|
|
33
|
-
return loud ? greeting.toUpperCase() : greeting;
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
const server = new McpServer({ name: "my-server", version: "1.0.0" });
|
|
38
|
-
fabricMcp({ service: handler, server });
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## fabricMcp
|
|
42
|
-
|
|
43
|
-
Registers a fabricService as an MCP tool.
|
|
44
|
-
|
|
45
|
-
### Options
|
|
46
|
-
|
|
47
|
-
| Option | Type | Description |
|
|
48
|
-
|--------|------|-------------|
|
|
49
|
-
| `service` | `Service` | Required. The service handler to adapt |
|
|
50
|
-
| `server` | `McpServer` | Required. The MCP server to register with |
|
|
51
|
-
| `name` | `string` | Override tool name (defaults to handler.alias) |
|
|
52
|
-
| `description` | `string` | Override tool description (defaults to handler.description) |
|
|
53
|
-
| `onComplete` | `OnCompleteCallback` | Called with tool's return value on success |
|
|
54
|
-
| `onError` | `OnErrorCallback` | Receives errors reported via `context.onError()` in service |
|
|
55
|
-
| `onFatal` | `OnFatalCallback` | Receives fatal errors (thrown or via `context.onFatal()`) |
|
|
56
|
-
| `onMessage` | `OnMessageCallback` | Receives messages from `context.sendMessage` in service |
|
|
57
|
-
|
|
58
|
-
### Basic Usage
|
|
59
|
-
|
|
60
|
-
```typescript
|
|
61
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
62
|
-
import { fabricService } from "@jaypie/fabric";
|
|
63
|
-
import { fabricMcp } from "@jaypie/fabric/mcp";
|
|
64
|
-
|
|
65
|
-
const calculateHandler = fabricService({
|
|
66
|
-
alias: "calculate",
|
|
67
|
-
description: "Perform a mathematical calculation",
|
|
68
|
-
input: {
|
|
69
|
-
operation: { type: ["add", "subtract", "multiply", "divide"] },
|
|
70
|
-
a: { type: Number, description: "First operand" },
|
|
71
|
-
b: { type: Number, description: "Second operand" },
|
|
72
|
-
},
|
|
73
|
-
service: ({ operation, a, b }) => {
|
|
74
|
-
switch (operation) {
|
|
75
|
-
case "add": return a + b;
|
|
76
|
-
case "subtract": return a - b;
|
|
77
|
-
case "multiply": return a * b;
|
|
78
|
-
case "divide": return a / b;
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
const server = new McpServer({ name: "calculator", version: "1.0.0" });
|
|
84
|
-
fabricMcp({ service: calculateHandler, server });
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Overriding Name and Description
|
|
88
|
-
|
|
89
|
-
```typescript
|
|
90
|
-
fabricMcp({
|
|
91
|
-
service: handler,
|
|
92
|
-
server,
|
|
93
|
-
name: "math_calculate",
|
|
94
|
-
description: "A tool for performing basic math operations",
|
|
95
|
-
});
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### Lifecycle Callbacks
|
|
99
|
-
|
|
100
|
-
Services can use context callbacks to report progress, errors, and completion:
|
|
101
|
-
|
|
102
|
-
```typescript
|
|
103
|
-
const handler = fabricService({
|
|
104
|
-
alias: "evaluate",
|
|
105
|
-
input: { jobId: { type: String } },
|
|
106
|
-
service: async ({ jobId }, context) => {
|
|
107
|
-
context?.sendMessage?.({ content: `Processing ${jobId}` });
|
|
108
|
-
|
|
109
|
-
try {
|
|
110
|
-
await riskyOperation();
|
|
111
|
-
} catch (err) {
|
|
112
|
-
context?.onError?.(err); // Reports error but continues
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return { jobId, status: "complete" };
|
|
116
|
-
},
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
fabricMcp({
|
|
120
|
-
service: handler,
|
|
121
|
-
server,
|
|
122
|
-
onComplete: (result) => console.log("Tool completed:", result),
|
|
123
|
-
onError: (error) => console.warn("Recoverable error:", error),
|
|
124
|
-
onFatal: (error) => console.error("Fatal error:", error),
|
|
125
|
-
onMessage: (msg) => console.log(`[${msg.level || "info"}] ${msg.content}`),
|
|
126
|
-
});
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
**Error handling**: Services receive `context.onError()` and `context.onFatal()` callbacks to report errors without throwing. Any error that escapes the service (is thrown) is treated as fatal and routes to `onFatal`. If `onFatal` is not provided, thrown errors fall back to `onError`. Callback errors are swallowed to ensure failures never halt service execution.
|
|
130
|
-
|
|
131
|
-
## Response Format
|
|
132
|
-
|
|
133
|
-
The adapter formats handler responses as MCP text content:
|
|
134
|
-
|
|
135
|
-
```typescript
|
|
136
|
-
// Handler returns:
|
|
137
|
-
{ result: 42, status: "complete" }
|
|
138
|
-
|
|
139
|
-
// MCP response:
|
|
140
|
-
{
|
|
141
|
-
content: [{
|
|
142
|
-
type: "text",
|
|
143
|
-
text: '{"result":42,"status":"complete"}'
|
|
144
|
-
}]
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
For string responses:
|
|
149
|
-
|
|
150
|
-
```typescript
|
|
151
|
-
// Handler returns:
|
|
152
|
-
"Hello, World!"
|
|
153
|
-
|
|
154
|
-
// MCP response:
|
|
155
|
-
{
|
|
156
|
-
content: [{
|
|
157
|
-
type: "text",
|
|
158
|
-
text: "Hello, World!"
|
|
159
|
-
}]
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
## Complete Example
|
|
164
|
-
|
|
165
|
-
```typescript
|
|
166
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
167
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
168
|
-
import { fabricService } from "@jaypie/fabric";
|
|
169
|
-
import { fabricMcp } from "@jaypie/fabric/mcp";
|
|
170
|
-
|
|
171
|
-
// Define handlers
|
|
172
|
-
const weatherHandler = fabricService({
|
|
173
|
-
alias: "get_weather",
|
|
174
|
-
description: "Get current weather for a location",
|
|
175
|
-
input: {
|
|
176
|
-
location: { type: String, description: "City name" },
|
|
177
|
-
units: { type: ["celsius", "fahrenheit"], default: "celsius" },
|
|
178
|
-
},
|
|
179
|
-
service: async ({ location, units }) => {
|
|
180
|
-
const weather = await fetchWeather(location);
|
|
181
|
-
return {
|
|
182
|
-
location,
|
|
183
|
-
temperature: units === "celsius" ? weather.tempC : weather.tempF,
|
|
184
|
-
units,
|
|
185
|
-
conditions: weather.conditions,
|
|
186
|
-
};
|
|
187
|
-
},
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
const searchHandler = fabricService({
|
|
191
|
-
alias: "search",
|
|
192
|
-
description: "Search for information",
|
|
193
|
-
input: {
|
|
194
|
-
query: { type: String, description: "Search query" },
|
|
195
|
-
limit: { type: Number, default: 10 },
|
|
196
|
-
},
|
|
197
|
-
service: async ({ query, limit }) => {
|
|
198
|
-
return await performSearch(query, { limit });
|
|
199
|
-
},
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
// Create server and register tools
|
|
203
|
-
const server = new McpServer({
|
|
204
|
-
name: "my-mcp-server",
|
|
205
|
-
version: "1.0.0",
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
fabricMcp({ service: weatherHandler, server });
|
|
209
|
-
fabricMcp({ service: searchHandler, server });
|
|
210
|
-
|
|
211
|
-
// Start server
|
|
212
|
-
const transport = new StdioServerTransport();
|
|
213
|
-
await server.connect(transport);
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
## Input Validation and Schema Generation
|
|
217
|
-
|
|
218
|
-
The adapter automatically converts fabric input definitions to Zod schemas for the MCP SDK, enabling proper parameter validation and type inference:
|
|
219
|
-
|
|
220
|
-
```typescript
|
|
221
|
-
// Fabric input definitions:
|
|
222
|
-
input: {
|
|
223
|
-
name: { type: String, description: "User name" },
|
|
224
|
-
count: { type: Number, default: 10 },
|
|
225
|
-
active: { type: Boolean, required: false },
|
|
226
|
-
status: { type: ["pending", "active", "done"] },
|
|
227
|
-
tags: { type: [String] },
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// Automatically generates equivalent Zod schemas:
|
|
231
|
-
// name: z.string().describe("User name")
|
|
232
|
-
// count: z.number().optional().default(10)
|
|
233
|
-
// active: z.boolean().optional()
|
|
234
|
-
// status: z.enum(["active", "done", "pending"])
|
|
235
|
-
// tags: z.array(z.string())
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
The adapter also delegates input validation to the service handler. Invalid inputs result in errors:
|
|
239
|
-
|
|
240
|
-
```typescript
|
|
241
|
-
// If handler expects:
|
|
242
|
-
input: {
|
|
243
|
-
priority: { type: [1, 2, 3, 4, 5] },
|
|
244
|
-
email: { type: /^[^@]+@[^@]+\.[^@]+$/ },
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// Invalid calls throw BadRequestError:
|
|
248
|
-
// { priority: 10 } → Validation fails
|
|
249
|
-
// { email: "invalid" } → Pattern mismatch
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## TypeScript Types
|
|
253
|
-
|
|
254
|
-
```typescript
|
|
255
|
-
import type {
|
|
256
|
-
FabricMcpConfig,
|
|
257
|
-
FabricMcpResult,
|
|
258
|
-
McpToolContentItem,
|
|
259
|
-
McpToolResponse,
|
|
260
|
-
OnCompleteCallback,
|
|
261
|
-
OnErrorCallback,
|
|
262
|
-
OnFatalCallback,
|
|
263
|
-
OnMessageCallback,
|
|
264
|
-
} from "@jaypie/fabric/mcp";
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
### Type Definitions
|
|
268
|
-
|
|
269
|
-
```typescript
|
|
270
|
-
interface McpToolContentItem {
|
|
271
|
-
type: "text";
|
|
272
|
-
text: string;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
interface McpToolResponse {
|
|
276
|
-
content: McpToolContentItem[];
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
interface FabricMcpConfig {
|
|
280
|
-
service: Service;
|
|
281
|
-
server: McpServer;
|
|
282
|
-
name?: string;
|
|
283
|
-
description?: string;
|
|
284
|
-
onComplete?: OnCompleteCallback;
|
|
285
|
-
onError?: OnErrorCallback;
|
|
286
|
-
onFatal?: OnFatalCallback;
|
|
287
|
-
onMessage?: OnMessageCallback;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
interface FabricMcpResult {
|
|
291
|
-
name: string;
|
|
292
|
-
}
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
## Exports
|
|
296
|
-
|
|
297
|
-
```typescript
|
|
298
|
-
// @jaypie/fabric/mcp
|
|
299
|
-
export { fabricMcp } from "./fabricMcp.js";
|
|
300
|
-
|
|
301
|
-
export type {
|
|
302
|
-
FabricMcpConfig,
|
|
303
|
-
FabricMcpResult,
|
|
304
|
-
McpToolContentItem,
|
|
305
|
-
McpToolResponse,
|
|
306
|
-
OnCompleteCallback,
|
|
307
|
-
OnErrorCallback,
|
|
308
|
-
OnFatalCallback,
|
|
309
|
-
OnMessageCallback,
|
|
310
|
-
} from "./types.js";
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
## Related
|
|
314
|
-
|
|
315
|
-
- [Jaypie_Fabric_Package.md](Jaypie_Fabric_Package.md) - Core fabricService and type conversion
|
|
316
|
-
- [Jaypie_Fabric_LLM.md](Jaypie_Fabric_LLM.md) - LLM tool creation (similar pattern)
|