ai-toolkit-rules
Mandatory engineering, security, testing, git, performance, quality, and response rules.…
API design: naming, versioning, pagination, idempotency, OpenAPI, error contracts and safe retries. Triggers: API design, REST, GraphQL, OpenAPI, Swagger, error response, HTTP status, rate limit.
$ npx -y skills add softspark/ai-toolkit --skill api-patterns --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/api-patternsContext preview
The summary Claude sees to decide when to auto-load this skill.
API design: naming, versioning, pagination, idempotency, OpenAPI, error contracts and safe retries. Triggers: API design, REST, GraphQL, OpenAPI, Swagger, error response, HTTP status, rate limit.
name: api-patterns description: "API design: naming, versioning, pagination, idempotency, OpenAPI, error contracts and safe retries. Triggers: API design, REST, GraphQL, OpenAPI, Swagger, error response, HTTP status, rate limit." effort: medium user-invocable: false allowed-tools: Read
# Collection
GET /api/v1/documents # List documents
POST /api/v1/documents # Create document
# Single resource
GET /api/v1/documents/{id} # Get document
PUT /api/v1/documents/{id} # Replace document
PATCH /api/v1/documents/{id} # Update document
DELETE /api/v1/documents/{id} # Delete document
# Nested resources
GET /api/v1/users/{id}/documents # User's documents| Code | Meaning | When to Use | |------|---------|-------------| | 200 | OK | Successful GET/PUT/PATCH | | 201 | Created | Successful POST | | 204 | No Content | Successful DELETE | | 400 | Bad Request | Malformed request or an established domain refusal | | 401 | Unauthorized | Missing/invalid auth | | 403 | Forbidden | No permission | | 404 | Not Found | Resource doesn't exist | | 405 | Method Not Allowed | Unsupported method; preserve Allow | | 409 | Conflict | Duplicate resource or current-state conflict | | 412 | Precondition Failed | Supplied concurrency version is stale | | 422 | Unprocessable | Validation error | | 428 | Precondition Required | Required concurrency precondition is missing | | 429 | Too Many Requests | Rate limited | | 500 | Internal Error | Server error | | 503 | Service Unavailable | Dependency temporarily unavailable |
Follow the host's existing resource and collection contract. This envelope is illustrative; do not impose it on a framework that already defines another shape.
{
"data": {
"id": "123",
"type": "document",
"attributes": {
"title": "Example",
"content": "..."
}
},
"meta": {
"total": 100,
"page": 1,
"per_page": 10
}
}Use the established error representation, which may be problem details, framework validation errors, or a domain-specific envelope like this example:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input",
"details": [
{"field": "title", "message": "Title is required"},
{"field": "limit", "message": "Must be between 1 and 100"}
]
}
}When implementing or reviewing failure paths, read [Error contracts and safe retries](reference/error-contracts.md). Classify from the original cause, preserve public codes and JSON types, and distinguish an unknown operation outcome from a confirmed refusal. Do not turn arbitrary server failures into invalid-input responses.
When adding client-side validation, read `reference/input-validation.md` from the installed `security-patterns` skill. Resolve that skill through the current client's catalog, since adapters may namespace skill directory names. Use one authoritative rule source and prove parity at the request boundary.
---
from fastapi import FastAPI, HTTPException, Query, Path
from pydantic import BaseModel, Field
app = FastAPI(title="RAG-MCP API", version="1.0.0")
class InvalidSearchQuery(Exception):
"""Known request-level refusal from the application-owned search adapter."""
class SearchRequest(BaseModel):
query: str = Field(..., min_length=1, description="Search query")
limit: int = Field(10, ge=1, le=100, description="Max results")
class SearchResult(BaseModel):
id: str
title: str
score: float
content: str
class SearchResponse(BaseModel):
results: list[SearchResult]
total: int
@app.post("/api/v1/search", response_model=SearchResponse)
async def search(request: SearchRequest):
"""Search the knowledge base.
Args:
request: Search parameters
Returns:
Search results with scores
"""
try:
results = await perform_search(request.query, request.limit)
return SearchResponse(results=results, total=len(results))
except InvalidSearchQuery as exc:
raise HTTPException(
status_code=400,
detail="The search query is not supported. Check its syntax.",
) from exc---
The same rules apply to OpenAPI `description` fields, Pydantic `Field(description=...)`, and MCP tool parameters: the description should encode the *workflow*, not just restate the type. A consumer (human or LLM) reads it to know how to supply a valid value, not what language primitive it is.
A free-form `string` for `status` forces the caller to guess valid values. Constrain it and document each one:
class ListReposRequest(BaseModel):
visibility: Literal["PUBLIC", "PRIVATE", "INTERNAL"] = Field(
"PUBLIC",
description=(
"Repository visibility filter. "
"PUBLIC = visible to anyone; "
"PRIVATE = only members with explicit access; "
"INTERNAL = visible to all org members (Enterprise only)."
),
)In OpenAPI, pair `enum` with the value meanings in the description (or `x-enum-descriptions` if your tooling renders it). Avoid documenting a closed set as plain `string` — the caller cannot tell `INTERNAL` is valid but `internal` is not.
Document cross-field requirements where the dependent field is defined and encode them in the supported schema dialect. JSON Schema supports conditional requirements with `dependentRequired` or `if`/`then`; application state and opaque-token provenance still require prose and runtime checks. See [conditional schema validation](https://json-schema.org/understanding-json-schema/reference/conditionals).
cursor: str | None = Field(
None,
descAI coding toolkit with machine-enforced safety, 116 skills, 44 agents, lifecycle hooks, persona presets, opt-in plugin packs, and benchmark tooling.
Repo: softspark/ai-toolkit
Mandatory engineering, security, testing, git, performance, quality, and response rules.…
Searches past coding sessions for observations, decisions, context. Triggers: mem-search,…
Accessibility validator: WCAG 2.1 AA, EN 301 549, EAA. Triggers: a11y, accessibility, WCAG,…
Creates new specialized agents with frontmatter, tools, delegation. Triggers: new agent,…
Analyzes code quality, complexity, patterns across codebase. Triggers: quality report,…
App scaffolding: Next.js, Vite, Nuxt, Astro, FastAPI, Django, Laravel, RN, Flutter. Triggers:…