Load PROACTIVELY when task involves building or modifying API endpoints. Use when user says "build an API", "add an endpoint", "create a REST route", "set up GraphQL", or "add tRPC procedures". Covers route design and file organization, request validation with Zod, response formatting, error handling patterns, middleware composition, authentication guards, rate limiting, pagination, and API documentation generation.
Guides the design and implementation of API endpoints with validation, error handling, and documentation.
/plugin marketplace add mgd34msu/goodvibes-plugin/plugin install goodvibes@goodvibes-marketThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/api-style-guide.mdscripts/api-checklist.shscripts/
api-checklist.sh
references/
api-style-guide.md
This skill guides you through designing and implementing API endpoints using GoodVibes precision and project engine tools. Use this workflow when building REST APIs, GraphQL resolvers, tRPC procedures, or any HTTP endpoint.
Load this skill when:
Trigger phrases: "create an API", "build endpoint", "implement route", "add validation", "GraphQL resolver", "tRPC procedure".
Before implementing anything, understand existing patterns.
Use get_api_routes to discover all API endpoints in the project.
mcp__plugin_goodvibes_project-engine__get_api_routes:
project_root: "." # or specific path
What this reveals:
Use discover to find middleware, validation, error handling, and auth patterns.
discover:
queries:
- id: middleware
type: grep
pattern: "(middleware|use\\()"
glob: "**/*.{ts,js}"
- id: validation
type: grep
pattern: "(z\\.|yup\\.|joi\\.|validator\\.)"
glob: "**/*.{ts,js}"
- id: error_handlers
type: grep
pattern: "(catch|try|Error|throw)"
glob: "src/api/**/*.{ts,js}"
- id: auth_patterns
type: grep
pattern: "(auth|jwt|session|bearer|getServerSession)"
glob: "**/*.{ts,js}"
verbosity: files_only
What this reveals:
Read 2-3 representative route files to understand implementation patterns.
precision_read:
files:
- path: "src/api/users/route.ts" # or discovered route
extract: content
- path: "src/lib/validation.ts" # or discovered validation file
extract: outline
verbosity: standard
Choose the API paradigm that fits your needs. See references/api-style-guide.md for the full decision tree.
Consult references/api-style-guide.md for the REST vs GraphQL vs tRPC vs Server Actions decision tree.
Create request validation using the project's validation library.
Example with Zod:
import { z } from 'zod';
export const createUserSchema = z.object({
email: z.string().email(),
name: z.string().min(2).max(100),
role: z.enum(['user', 'admin']).default('user'),
});
export type CreateUserInput = z.infer<typeof createUserSchema>;
Best Practices:
Write the route handler following project conventions.
Next.js App Router Example:
import { NextRequest, NextResponse } from 'next/server';
import { createUserSchema } from './schema';
import { db } from '@/lib/db';
import { getServerSession } from '@/lib/auth';
export async function POST(request: NextRequest) {
// 1. Authentication
const session = await getServerSession();
if (!session) {
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 401 }
);
}
// 2. Parse and validate input
const body = await request.json();
const result = createUserSchema.safeParse(body);
if (!result.success) {
return NextResponse.json(
{ error: 'Validation failed', details: result.error.flatten() },
{ status: 400 }
);
}
// 3. Authorization check
if (session.user.role !== 'admin') {
return NextResponse.json(
{ error: 'Forbidden' },
{ status: 403 }
);
}
// 4. Business logic
try {
const user = await db.user.create({
data: result.data,
});
return NextResponse.json(user, { status: 201 });
} catch (error) {
console.error('Failed to create user:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
tRPC Example:
import { z } from 'zod';
import { protectedProcedure, router } from '../trpc';
export const userRouter = router({
create: protectedProcedure
.input(
z.object({
email: z.string().email(),
name: z.string().min(2).max(100),
})
)
.mutation(async ({ ctx, input }) => {
if (ctx.session.user.role !== 'admin') {
throw new TRPCError({ code: 'FORBIDDEN' });
}
return await ctx.db.user.create({
data: input,
});
}),
});
Use precision_write to create route files, validation schemas, and types.
precision_write:
files:
- path: "src/app/api/users/route.ts"
content: |
import { NextRequest, NextResponse } from 'next/server';
// ... [full handler implementation]
- path: "src/app/api/users/schema.ts"
content: |
import { z } from 'zod';
export const createUserSchema = z.object({ ... });
verbosity: count_only
Maintain consistent error responses across all endpoints.
interface APIError {
error: string; // Human-readable message
code?: string; // Machine-readable error code
details?: unknown; // Validation errors or additional context
trace_id?: string; // For debugging in production
}
HTTP Status Code Guidelines:
200 - Success201 - Created (POST)204 - No Content (DELETE)400 - Bad Request (validation error)401 - Unauthorized (not authenticated)403 - Forbidden (not authorized)404 - Not Found409 - Conflict (duplicate resource)500 - Internal Server Errortry {
// Business logic
} catch (error) {
// Log for debugging (never expose to client)
console.error('Operation failed:', error);
// User-facing error
return NextResponse.json(
{ error: 'Failed to process request' },
{ status: 500 }
);
}
Never expose:
For REST APIs, generate OpenAPI documentation automatically.
mcp__plugin_goodvibes_project-engine__generate_openapi:
project_root: "."
output_path: "docs/openapi.yaml"
What this generates:
If the tool doesn't exist or fails, manually document endpoints:
# In a routes.md file
POST /api/users
Description: Create a new user
Auth: Required (admin)
Body: { email: string, name: string, role?: 'user' | 'admin' }
Response 201: User object
Response 400: Validation error
Response 401: Unauthorized
Response 403: Forbidden
Document route handlers with JSDoc.
/**
* Create a new user.
*
* @requires Authentication (admin role)
* @body {CreateUserInput} User data
* @returns {User} Created user object
* @throws {401} Unauthorized - Not authenticated
* @throws {403} Forbidden - Not an admin
* @throws {400} Bad Request - Validation failed
*/
export async function POST(request: NextRequest) {
// ...
}
Use sync_api_types to check type alignment.
mcp__plugin_goodvibes_project-engine__sync_api_types:
backend_dir: "src/app/api"
frontend_dir: "src/lib/api-client"
What this checks:
Expose types for client consumption.
// src/types/api.ts
export type { CreateUserInput, User } from '@/app/api/users/schema';
For tRPC, types are automatically inferred:
// Client code
import { trpc } from '@/lib/trpc';
const user = await trpc.user.create.mutate({
email: 'test@example.com',
name: 'Test User',
}); // Fully typed!
Use validate_api_contract to verify responses match spec.
mcp__plugin_goodvibes_analysis-engine__validate_api_contract:
spec_path: "docs/openapi.yaml"
implementation_dir: "src/app/api"
What this validates:
If the tool doesn't exist, manually test:
# Use curl or httpie to test endpoints
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","name":"Test"}'
Verify TypeScript compilation.
precision_exec:
commands:
- cmd: "npm run typecheck"
expect:
exit_code: 0
stderr_empty: true
verbosity: minimal
Use the validation script to ensure quality.
bash scripts/api-checklist.sh .
See scripts/api-checklist.sh for the complete validation suite.
Implement authentication, CORS, and rate limiting middleware following the patterns in references/api-style-guide.md. Always use environment variables for security-sensitive configuration like CORS origins.
Test API endpoints with meaningful assertions covering success cases, validation errors, and authentication failures. See references/api-style-guide.md for testing patterns.
DON'T:
any types in route handlersDO:
Discovery Phase:
get_api_routes: { project_root: "." }
discover: { queries: [middleware, validation, auth], verbosity: files_only }
precision_read: { files: [route examples], extract: content }
Implementation Phase:
precision_write: { files: [route, schema, types], verbosity: count_only }
Validation Phase:
generate_openapi: { project_root: ".", output_path: "docs/openapi.yaml" }
validate_api_contract: { spec_path: "docs/openapi.yaml" }
sync_api_types: { backend_dir: "src/api", frontend_dir: "src/lib" }
precision_exec: { commands: [{ cmd: "npm run typecheck" }] }
Post-Implementation:
bash scripts/api-checklist.sh .
For detailed decision trees and framework-specific patterns, see references/api-style-guide.md.
Activates when the user asks about AI prompts, needs prompt templates, wants to search for prompts, or mentions prompts.chat. Use for discovering, retrieving, and improving prompts.
Search, retrieve, and install Agent Skills from the prompts.chat registry using MCP tools. Use when the user asks to find skills, browse skill catalogs, install a skill for Claude, or extend Claude's capabilities with reusable AI agent components.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.