@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.
@@ -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
- 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
- };
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
- await store.delete(input.id, userId);
363
- return { deleted: true, id: input.id };
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
- let response: Response;
103
- try {
104
- response = await this.fetch(url);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/skills",
3
- "version": "1.0.0-beta.12",
3
+ "version": "1.0.0-beta.13",
4
4
  "description": "Curated skills catalog for FrontMCP projects",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "homepage": "https://docs.agentfront.dev",