@frontmcp/skills 1.0.0-beta.12 → 1.0.0-beta.13
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/catalog/frontmcp-development/references/create-tool.md +20 -0
- package/catalog/frontmcp-guides/references/example-task-manager.md +15 -21
- package/catalog/frontmcp-guides/references/example-weather-api.md +3 -6
- package/catalog/frontmcp-testing/references/setup-testing.md +2 -0
- package/package.json +1 -1
|
@@ -209,6 +209,26 @@ async execute(input: { data: string }) {
|
|
|
209
209
|
|
|
210
210
|
## Error Handling
|
|
211
211
|
|
|
212
|
+
**Do NOT wrap `execute()` in try/catch.** The framework's tool execution flow automatically catches exceptions, formats error responses, and triggers error hooks. Only use `this.fail(err)` for **business-logic errors** (validation failures, not-found, permission denied). Let infrastructure errors (network, database) propagate naturally.
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
// WRONG — never do this:
|
|
216
|
+
async execute(input) {
|
|
217
|
+
try {
|
|
218
|
+
const result = await someOperation();
|
|
219
|
+
return result;
|
|
220
|
+
} catch (err) {
|
|
221
|
+
this.fail(err instanceof Error ? err : new Error(String(err)));
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// CORRECT — let the framework handle errors:
|
|
226
|
+
async execute(input) {
|
|
227
|
+
const result = await someOperation(); // errors propagate to framework
|
|
228
|
+
return result;
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
212
232
|
Use `this.fail(err)` to abort execution and trigger the error flow. The method throws internally and never returns.
|
|
213
233
|
|
|
214
234
|
```typescript
|
|
@@ -309,21 +309,18 @@ export class UpdateTaskTool extends ToolContext {
|
|
|
309
309
|
this.fail(new Error('Authentication required'));
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
-
try
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
} catch (err) {
|
|
325
|
-
this.fail(new Error(`Failed to update task: ${String(err)}`));
|
|
326
|
-
}
|
|
312
|
+
// No try/catch needed — the framework handles errors in the tool execution flow.
|
|
313
|
+
const updated = await store.update(input.id, userId, {
|
|
314
|
+
...(input.status && { status: input.status }),
|
|
315
|
+
...(input.priority && { priority: input.priority }),
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
id: updated.id,
|
|
320
|
+
title: updated.title,
|
|
321
|
+
priority: updated.priority,
|
|
322
|
+
status: updated.status,
|
|
323
|
+
};
|
|
327
324
|
}
|
|
328
325
|
}
|
|
329
326
|
```
|
|
@@ -358,12 +355,9 @@ export class DeleteTaskTool extends ToolContext {
|
|
|
358
355
|
this.fail(new Error('Authentication required'));
|
|
359
356
|
}
|
|
360
357
|
|
|
361
|
-
try
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
} catch (err) {
|
|
365
|
-
this.fail(new Error(`Failed to delete task: ${String(err)}`));
|
|
366
|
-
}
|
|
358
|
+
// No try/catch needed — the framework handles errors in the tool execution flow.
|
|
359
|
+
await store.delete(input.id, userId);
|
|
360
|
+
return { deleted: true, id: input.id };
|
|
367
361
|
}
|
|
368
362
|
}
|
|
369
363
|
```
|
|
@@ -99,12 +99,9 @@ export class GetWeatherTool extends ToolContext {
|
|
|
99
99
|
async execute(input: { city: string; units: 'celsius' | 'fahrenheit' }) {
|
|
100
100
|
const url = `https://api.weather.example.com/v1/current?city=${encodeURIComponent(input.city)}&units=${input.units}`;
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
} catch (err) {
|
|
106
|
-
this.fail(new Error(`Weather API unreachable: ${String(err)}`));
|
|
107
|
-
}
|
|
102
|
+
// No try/catch needed — the framework's tool execution flow handles errors automatically.
|
|
103
|
+
// Use this.fail() only for business-logic errors (e.g., invalid response).
|
|
104
|
+
const response = await this.fetch(url);
|
|
108
105
|
|
|
109
106
|
if (!response.ok) {
|
|
110
107
|
this.fail(new Error(`Weather API error: ${response.status} ${response.statusText}`));
|
|
@@ -316,6 +316,8 @@ test('prompts return well-formed messages', async ({ mcp }) => {
|
|
|
316
316
|
|
|
317
317
|
For more control, use `McpTestClient` and `TestServer` directly:
|
|
318
318
|
|
|
319
|
+
> **Note:** `npx tsx src/main.ts` is correct **only inside E2E tests** (the test framework uses it internally via `resolveServerCommand`). For development and running the server outside of tests, always use `frontmcp dev` (or your package.json `dev` script). Never run `npx tsx src/main.ts` directly for development.
|
|
320
|
+
|
|
319
321
|
```typescript
|
|
320
322
|
// advanced.e2e.spec.ts
|
|
321
323
|
import { McpTestClient, TestServer } from '@frontmcp/testing';
|
package/package.json
CHANGED