Agent skill

API Endpoint Contract

by trycompai in trycompai/comp

The contract every new or modified API endpoint must follow so it is correct for the public OpenAPI spec, the MCP server (npm @trycompai/mcp-server), the ValidationPipe, and the docs.

AGPL-3.0Auto-check passedBackend & APIs

Install API Endpoint Contract

skills CLI
$ npx skills add trycompai/comp --skill api-endpoint-contract -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install trycompai/comp api-endpoint-contract --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/trycompai/comp.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/api-endpoint-contract .claude/skills/api-endpoint-contract && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
api-endpoint-contract
GitHub stars
2k
Token cost
~2.7k tokens
SKILL.md length
1,008 words
Files
1
Skills in repo
31
Repo updated
First seen
Licence
AGPL-3.0

At a glance

The contract every new or modified API endpoint must follow so it is correct for the public OpenAPI spec, the MCP server (npm @trycompai/mcp-server), the ValidationPipe, and the docs.

  • Works in 11 steps: DTOs MUST be classes — never interfaces,… → Every DTO property carries BOTH… → Add @ApiBody({ type: DtoClass }) on the… → …
  • @RequirePermission
  • SKILL.md covers The 11 rules, Workflow checklist when adding… and Why this matters
  • Calls node, bun and git

What it does

API Endpoint Contract is an agent skill from trycompai/comp. The contract every new or modified API endpoint must follow so it is correct for the public OpenAPI spec, the MCP server (npm @trycompai/mcp-server), the ValidationPipe, and the docs. Triggers on "new endpoint", "add API", "new DTO", "@Body", "@RequirePermission", "MCP tool", "edit controller in apps/api", "OpenAPI", or whenever editing controllers under apps/api/src/.

Its SKILL.md is about 2.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Backend & APIs, covering OpenAPI specifications, REST APIs and MCP servers. It works with OpenAPI, Model Context Protocol and npm. The repository describes itself as: AI Native platform to get companies compliant - Vanta & Drata Alternative. The licence is AGPL-3.0.

When your agent uses it

  • @RequirePermission
  • Edit controller in apps/api
  • Whenever editing controllers under apps/api/src/

Example prompts

  • “new endpoint”
  • “add API”
  • “new DTO”
  • “/api-endpoint-contract”

Workflow steps

11 steps, taken from the step headings in SKILL.md.

  1. DTOs MUST be classes — never interfaces, never inline types
  2. Every DTO property carries BOTH decorator stacks
  3. Add @ApiBody({ type: DtoClass }) on the endpoint
  4. Operation descriptions ≤ 240 characters
  5. Use a clean MCP tool name when the auto-derived one is ugly
  6. Agent-callable endpoints must NOT be behind SessionOnlyGuard
  7. Long-running operations: async + poll, never sync wait
  8. File uploads from agents: presigned URL + s3Key — never inline base64
  9. Sensitive endpoints are deny-listed from public docs — don't fight it
  10. MCP-incompatible response shapes: disable the MCP tool in the overlay
  11. Every endpoint MUST have a meaningful summary + description — it powers MCP discovery

What it can do on your machine

Read from SKILL.md and the folder at commit 1bf4d52. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • node
    • bun
    • git

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use git, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

API Endpoint Contract loads about 2.7k tokens when it runs. Until then it costs about 98 tokens; SKILL.md has 1,008 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~98
When it runs · the whole SKILL.md, loaded when a task matches
~2.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from trycompai/comp at commit 1bf4d52, republished under its AGPL-3.0 licence (© trycompai). 1,008 words, ~2,748 tokens.

Download SKILL.mdSave it as .claude/skills/api-endpoint-contract/SKILL.md (or your agent's skills folder).
name
api-endpoint-contract
description
The contract every new or modified API endpoint must follow so it is correct for the public OpenAPI spec, the MCP server (npm @trycompai/mcp-server), the ValidationPipe, and the docs. Triggers on "new endpoint", "add API", "new DTO", "@Body", "@RequirePermission", "MCP tool", "edit controller in apps/api", "OpenAPI", or whenever editing controllers under apps/api/src/.

API Endpoint Contract (MCP-friendly NestJS endpoints)

Every customer-facing endpoint in apps/api/src/ ends up in three places:

  1. The OpenAPI spec (packages/docs/openapi.json) — regenerated on every dev boot, consumed by Speakeasy.
  2. The MCP server (apps/mcp-server/, published as @trycompai/mcp-server on npm) — generated daily from the OpenAPI spec.
  3. The runtime ValidationPipe — accepts/rejects request bodies based on class-validator metadata.

If any one of these three is wrong, the endpoint either silently breaks for agents (Claude Desktop, Cursor, Codex, etc.) or fails validation at runtime. Follow this contract on every body-accepting endpoint.

The 11 rules

1. DTOs MUST be classes — never interfaces, never inline types
ts
// ❌ erased at runtime → empty MCP schema → agents blind-guess the body
interface CreateConnectionDto {
  providerSlug: string;
  credentials?: Record<string, string | string[]>;
}

// ❌ same problem
async updateConnection(@Body() body: { metadata?: Record<string, unknown> }) { ... }

// ✅ class — survives to runtime, @nestjs/swagger can introspect it
class CreateConnectionDto {
  @ApiProperty({ description: '...', example: 'aws' })
  @IsString()
  providerSlug!: string;
}
2. Every DTO property carries BOTH decorator stacks

The global ValidationPipe runs with whitelist: true, forbidNonWhitelisted: true. A class with @ApiProperty but no class-validator decorator has zero "known" properties — the pipe rejects every field with "property X should not exist". The reverse (class-validator without @ApiProperty) generates an empty MCP schema and agents blind-guess the body.

ts
class FooDto {
  // ✅ both stacks
  @ApiProperty({ description: 'Name', example: 'foo' })
  @IsString()
  name!: string;

  @ApiPropertyOptional({ description: 'Optional tag', example: 'beta' })
  @IsOptional()
  @IsString()
  tag?: string;

  @ApiPropertyOptional({ type: 'object', additionalProperties: true })
  @IsOptional()
  @IsObject()
  metadata?: Record<string, unknown>;

  @ApiProperty({ type: 'array', items: { type: 'string' } })
  @IsArray()
  @IsString({ each: true })
  services!: string[];
}
3. Add @ApiBody({ type: DtoClass }) on the endpoint

@nestjs/swagger does NOT reliably infer the body type from @Body() body: DtoClass alone. Always declare it explicitly so the OpenAPI requestBody.content.application/json.schema.$ref resolves correctly.

ts
@Post()
@RequirePermission('integration', 'create')
@ApiOperation({ summary: 'Create an integration connection' })
@ApiBody({ type: CreateConnectionDto })
async createConnection(
  @Body() body: CreateConnectionDto,
  @OrganizationId() organizationId: string,
) { ... }
4. Operation descriptions ≤ 240 characters

apps/api/src/openapi/seo-text.ts:71 (toOperationDescription) trims every @ApiOperation.description to 240 chars at a word boundary for SEO/docs consistency. Anything longer gets cut mid-sentence and the trailing words are stripped — including the actionable step at the end of your description. Count chars; keep the key instruction in the first 240.

5. Use a clean MCP tool name when the auto-derived one is ugly

Tool names are auto-derived from controller method names by applyMcpToolNames in apps/api/src/openapi/public-docs-metadata.ts. If the auto-name is generic or ugly, override:

ts
@Post(':id/auto-answer')
@ApiExtension('x-speakeasy-mcp', { name: 'generate-questionnaire-answers' })
async triggerAutoAnswer(@Param('id') id: string) { ... }

Tool name budget: 52 chars max, kebab-case.

6. Agent-callable endpoints must NOT be behind SessionOnlyGuard

If your endpoint uses @UseGuards(HybridAuthGuard, SessionOnlyGuard, PermissionGuard), API-key callers get a 403 — meaning the MCP tool exists but fails for every customer call. Either:

  • Remove SessionOnlyGuard if the endpoint should be agent-callable, OR
  • Disable the MCP tool entirely in apps/mcp-server/.speakeasy/mcp-uploads-overlay.yaml with x-speakeasy-mcp: { disabled: true }.
7. Long-running operations: async + poll, never sync wait

Anything taking > ~30s should not block on a single tool call. Return a run handle and let the agent poll:

ts
// Trigger: returns immediately
@Post(':id/auto-answer')
async triggerAutoAnswer(@Param('id') id: string): Promise<TriggerResponseDto> {
  const handle = await tasks.trigger('auto-answer-task', { id, ... });
  return { runId: handle.id, status: 'generating', totalQuestions, answeredQuestions };
}

// Agent polls find-by-id until counts converge

The @ApiOperation.description should tell the agent the poll target (e.g. "Poll GET /v1/X/:id until answeredQuestions equals totalQuestions").

8. File uploads from agents: presigned URL + s3Key — never inline base64

Base64-through-LLM is catastrophically slow and overflows the context window. For any endpoint that needs file bytes:

ts
// Endpoint accepts both for the web UI (fileData) and agents (s3Key):
class UploadAndParseDto {
  @ApiPropertyOptional({ description: 'Base64 — web UI only. AI clients use s3Key.' })
  @IsOptional() @IsString()
  fileData?: string;

  @ApiPropertyOptional({ description: 'Key returned by /v1/uploads/presign.' })
  @IsOptional() @IsString()
  s3Key?: string;
}

// Service resolves whichever was provided:
const bytes = dto.fileData
  ?? (dto.s3Key ? await uploadsService.readUploadAsBase64(orgId, dto.s3Key) : null);

The MCP overlay then strips fileData from the MCP tool input so agents are forced into the presigned path. Pattern is in apps/mcp-server/.speakeasy/mcp-uploads-overlay.yaml.

9. Sensitive endpoints are deny-listed from public docs — don't fight it

apps/api/src/openapi/public-docs-quality.ts strips paths matching /\/credentials(?:\/|$)/ and similar from packages/docs/openapi.json. Endpoints for rotating credentials, raw secrets, etc. intentionally do not appear in MCP. Add new sensitive paths to that deny-list if they handle secrets.

10. MCP-incompatible response shapes: disable the MCP tool in the overlay

SSE streams (@ApiProduces('text/event-stream')) and binary file responses (@Res() res.send(buffer)) cannot be consumed by a single JSON-RPC tool call. Disable them for MCP only (HTTP endpoint stays for the web UI):

yaml
# apps/mcp-server/.speakeasy/mcp-uploads-overlay.yaml
- target: "$.paths['/v1/questionnaire/auto-answer'].post"
  update:
    x-speakeasy-mcp:
      disabled: true
11. Every endpoint MUST have a meaningful summary + description — it powers MCP discovery

@ApiOperation({ summary, description }) is not optional. openapi-docs.spec.ts (via collectPublicOpenApiIssues in apps/api/src/openapi/public-docs-quality.ts) fails CI if any non-excluded operation has:

  • an empty summary → missingSummaries
  • a missing description or SEO metadata → missingMetadata
  • SEO metadata outside 80–160 chars, or a title > 60 chars → invalidSeo

This matters more now that the hosted MCP (Gram) uses dynamic toolsets: with 300+ tools the agent never sees them all — it runs a semantic search over tool names + descriptions and only loads matches. A tool with a weak or missing description is effectively undiscoverable. The description is the tool's only chance of being found.

ts
@ApiOperation({
  summary: 'List compliance policies', // concise tool title
  description:
    "Returns the organization's compliance policies (SOC 2, ISO 27001, …) " +
    'with status and owner. Use to review or audit policy coverage.', // what it does + when to use it
})

Write the description for the agent deciding whether to call this tool: state what it does and when to use it. (Keep it ≤ 240 chars — see Rule 4.)

Show full SKILL.md (367 more words)Show less

Workflow checklist when adding a body endpoint

  1. Define a class DTO. Two decorator stacks on every field. Add @ApiBody({ type: DtoClass }) on the endpoint.
  2. Give the endpoint a meaningful @ApiOperation({ summary, description }) — both required, CI-enforced by openapi-docs.spec.ts, and they power MCP dynamic-toolset discovery (Rule 11). Keep the description ≤ 240 chars (Rule 4).
  3. If the auto-derived MCP tool name is ugly, set @ApiExtension('x-speakeasy-mcp', { name: '...' }).
  4. If the endpoint requires session auth, decide: remove SessionOnlyGuard, or disable it for MCP via the overlay.
  5. For long-running work, return a run handle and document the poll target.
  6. For file uploads, accept s3Key and read via UploadsService.readUploadAsBase64.
  7. bun run --filter '@trycompai/api' dev — your dev server regenerates packages/docs/openapi.json on boot.
  8. git add packages/docs/openapi.json — commit the regenerated spec alongside your API change. The daily Speakeasy CI reads from this file; if it's stale, your new tool never reaches customers.
  9. Sanity-check the new operation in the spec:
    node -e 'const o=require("./packages/docs/openapi.json"); console.log(o.paths["/v1/your-path"]?.post?.requestBody?.content?.["application/json"]?.schema)'
    If the schema is undefined or has empty properties, stop — fix the DTO before merging.

Why this matters

Every bug below was a real customer-visible MCP failure caught during the May 2026 audit:

BugRoot causeRule that prevents it
PDF upload crashed with Cannot read properties of undefined (reading 'replace')Inline @Body() type → empty schema → agent guessed wrong bodyRule 1 + 3
Auto-answer "schema is just an empty object"DTO had class-validator only, no @ApiPropertyRule 2
create-connection "Provider undefined not found"DTO was an interface, not a classRule 1
create-connection "property X should not exist" 400Class converted, but I forgot class-validator decoratorsRule 2
create-upload-url description cut at "...then."Description was 330 chars; seo-text.ts truncates at 240Rule 4
Agent uploads stuck for 15+ min on base64 encodingTool accepted fileData as the only file inputRule 8
Agent calls SSE auto-answer and hangsTool was generated from @ApiProduces('text/event-stream')Rule 10
Agent tries to start OAuth and gets 403Endpoint was behind SessionOnlyGuard but generated as MCP toolRule 6
Agent can't find a tool that exists (dynamic toolsets)Endpoint had a missing/weak description → invisible to semantic searchRule 11

Follow the 10 rules and you avoid every one of these.

© trycompai, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .claude/skills/api-endpoint-contract of trycompai/comp.

Open the folder on GitHubat commit 1bf4d52

Compare with similar skills

API Endpoint Contract next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

API Endpoint Contract compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
API Endpoint Contract this skilltrycompai/comp2k—~2.7kAutomated safety check: PassAGPL-3.0
OpenAPI to MCP Servermcp-use/mcp-use11k—~5.2kAutomated safety check: PassApache-2.0
Dashclaw Shipucsandman/DashClaw310—~7.2kAutomated safety check: PassMIT
OpenAPI CLI CallerEvilFreelancer/openapi-to-cli265—~879Automated safety check: PassMIT
SpikardGoldziher/spikard123—~799Automated safety check: PassMIT
Kingdee MCP DevWaHaiLong/KingdeeMCP103—~853Automated safety check: PassMIT

Similar skills

  • OpenAPI to MCP Server

    mcp-use/mcp-use

    Turns an OpenAPI or Swagger spec into an MCP server with the mcp-use TypeScript SDK, mapping each operation to a tool, wiring auth, testing and deploying.

    11k GitHub stars~5.2k tokensUpdated today
    Backend & APIsAuto-check passed
  • Dashclaw Ship

    ucsandman/DashClaw

    The single command that gets a DashClaw change ON MAIN AND LIVE — it resolves everything blocking production, never defers, and never hands back a checklist.

    310 GitHub stars~7.2k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • OpenAPI CLI Caller

    EvilFreelancer/openapi-to-cli

    Turns an OpenAPI, Swagger or OpenRPC spec into CLI commands the agent can search and call, with no MCP server or code generation.

    265 GitHub stars~879 tokensUpdated 15 days ago
    Backend & APIsAuto-check passed
  • Spikard

    Goldziher/spikard

    Scaffold Spikard projects and generate code from OpenAPI, AsyncAPI, OpenRPC, GraphQL, and Protobuf schemas using the Spikard CLI or its MCP server.

    123 GitHub stars~799 tokensUpdated 3 days ago
    Backend & APIsAuto-check passed
  • Kingdee MCP Dev

    WaHaiLong/KingdeeMCP

    Knowledge base for the Kingdee MCP Dev Squad. An agent skill from WaHaiLong/KingdeeMCP.

    103 GitHub stars~853 tokensUpdated 1 mo ago
    Backend & APIsAuto-check passed
  • Frontmcp Development

    agentfront/frontmcp

    A skill your agent uses when building any FrontMCP server component other than a tool (for tools, use create-tool).

    146 GitHub stars~11k tokensUpdated today
    Backend & APIsAuto-check passed

More from trycompai/comp

All 31 skills in this repo
  • Check Results Service

    trycompai/comp

    How to reuse ANY integration check's results in a feature via the universal CheckResultsService (apps/api integration-platform).

    2k GitHub stars~2.1k tokensUpdated 5 days ago
    Auto-check passed
  • Data

    trycompai/comp

    A skill your agent uses when implementing data fetching, API calls, server/client components, or SWR hooks

    2k GitHub stars~955 tokensUpdated 5 days ago
    Auto-check passed
  • A skill your agent uses when SDK generation failed or seeing errors.

    2k GitHub stars~938 tokensUpdated 5 days ago
    Auto-check passed
  • Forms

    trycompai/comp

    A skill your agent uses when building forms - covers React Hook Form, Zod validation, and form patterns

    2k GitHub stars~1k tokensUpdated 5 days ago
    Auto-check passed
  • Code

    trycompai/comp

    A skill your agent uses when writing TypeScript/React code - covers type safety, component patterns, and file organization

    2k GitHub stars~909 tokensUpdated 5 days ago
    Auto-check: warnings
  • Generate MCP Server

    trycompai/comp

    A skill your agent uses when generating an MCP server from an OpenAPI spec with Speakeasy.

    2k GitHub stars~2.7k tokensUpdated 5 days ago
    Auto-check passed

Categories

Questions about API Endpoint Contract

What does API Endpoint Contract do?

The contract every new or modified API endpoint must follow so it is correct for the public OpenAPI spec, the MCP server (npm @trycompai/mcp-server), the ValidationPipe, and the docs. API Endpoint Contract is an agent skill from trycompai/comp. The contract every new or modified API endpoint must follow so it is correct for the public OpenAPI spec, the MCP server (npm @trycompai/mcp-server), the ValidationPipe, and the docs.

When should I use API Endpoint Contract?

API Endpoint Contract fits situations like: @RequirePermission; edit controller in apps/api; whenever editing controllers under apps/api/src/.

How do I install API Endpoint Contract in Claude Code?

Run `npx skills add trycompai/comp --skill api-endpoint-contract -a claude-code`. Or copy the skill folder (.claude/skills/api-endpoint-contract in trycompai/comp) into .claude/skills/api-endpoint-contract in your project. Claude Code loads it when a task matches its description.

How do I install API Endpoint Contract in Codex?

Run `npx skills add trycompai/comp --skill api-endpoint-contract -a codex`. Or copy the skill folder (.claude/skills/api-endpoint-contract in trycompai/comp) into .agents/skills/api-endpoint-contract in your project. Codex loads it when a task matches its description.

Can I use API Endpoint Contract in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add trycompai/comp --skill api-endpoint-contract -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/api-endpoint-contract, .gemini/skills/api-endpoint-contract, .github/skills/api-endpoint-contract and .opencode/skills/api-endpoint-contract in your project.

What does API Endpoint Contract need to run?

Going by SKILL.md and its folder, API Endpoint Contract needs the command-line tools its instructions call (node, bun and git).

Does API Endpoint Contract access the network?

SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is API Endpoint Contract safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does API Endpoint Contract use?

API Endpoint Contract is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does API Endpoint Contract use?

About 2.7k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to API Endpoint Contract?

Skills that share tags, products or a category with API Endpoint Contract: OpenAPI to MCP Server (mcp-use/mcp-use, 11k stars), Dashclaw Ship (ucsandman/DashClaw, 310 stars), OpenAPI CLI Caller (EvilFreelancer/openapi-to-cli, 265 stars) and Spikard (Goldziher/spikard, 123 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains API Endpoint Contract?

trycompai (a GitHub organization) maintains it in trycompai/comp, which has 2,016 GitHub stars. The repository holds 31 skills in this directory. The repository was last updated on October 2, 2026.

Source: trycompai/comp on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.