Brandedflow api-endpoint-builder

Build Express.js API endpoints for the BrandedFlow MCP server. Covers route design, validation, Airtable dual-write, error handling, and rate limiting. Use when adding new MCP tools or API routes.

install
source · Clone the upstream repo
git clone https://github.com/JenCW/brandedflow
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/JenCW/brandedflow "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills-library/api-endpoint-builder" ~/.claude/skills/jencw-brandedflow-api-endpoint-builder && rm -rf "$T"
manifest: .claude/skills-library/api-endpoint-builder/SKILL.md
source content

API Endpoint Builder

When to Use

  • Adding a new route to
    brandedflow.onrender.com
  • Building a new MCP tool
  • Adding a webhook receiver
  • Creating a data transformation endpoint

BrandedFlow MCP Server Context

  • Runtime: Node.js / Express
  • Deployed: Render (
    brandedflow.onrender.com
    )
  • Codebase:
    4-automate/mcps/
  • Pattern: each MCP = one route file + registered in main server
  • Airtable master base:
    appYXzdeB0MUlwqFN
  • Auth: bearer token or Airtable API key via
    .env

Endpoint Design Process

  1. Name the tool — kebab-case, verb-noun (e.g.
    qualify-lead
    ,
    create-client-folder
    )
  2. Define inputs — What does the caller send? (JSON body schema)
  3. Define outputs — What does the endpoint return? (success + error shapes)
  4. Map side effects — What does it write? (Airtable, DB, file, email)
  5. Write the route — Express router, validation, business logic, response
  6. Register — Add to main server index
  7. Test — curl or Postman against staging

Endpoint Template

// routes/[tool-name].js
const express = require('express');
const router = express.Router();

router.post('/[tool-name]', async (req, res) => {
  const { field1, field2 } = req.body;

  // Validate
  if (!field1) return res.status(400).json({ error: 'field1 required' });

  try {
    // Business logic
    const result = await doTheThing(field1, field2);

    // Dual-write Airtable if needed
    await writeToAirtable(result);

    res.json({ success: true, data: result });
  } catch (err) {
    console.error('[tool-name] error:', err.message);
    res.status(500).json({ error: 'Internal error', details: err.message });
  }
});

module.exports = router;

Validation Rules

  • Always validate required fields → 400 if missing
  • Sanitize string inputs (trim, escape)
  • Rate-limit public endpoints (express-rate-limit)
  • Add honeypot field on public lead endpoints

End of Task

State: "END-OF-TASK: Directive [updated/N/A]. Self-annealing [applied/N/A]."