Run the plugin generator
Pass your plugin name in PascalCase — e.g. For example:This creates It also automatically registers your plugin in
Stripe, GoogleCalendar, HubSpot.packages/stripe/ with the full plugin structure:packages/corsair/core/constants.ts.Choose your auth type
Open OAuth 2 (Google, GitHub, etc.):Also update the
packages/<yourplugin>/index.ts and update the auth type to match the API you’re integrating with.API key (most REST APIs):defaultAuthType constant and authConfig to match:Let Claude Code implement it
Point Claude Code at the API docs for your integration and let it do the heavy lifting.Open Claude Code in the repo root and give it a prompt like:Claude Code can read the scaffold, understand the patterns from existing plugins (e.g.
packages/github/), and produce a working starting point.Typecheck and build
src/server/corsair.ts
Test your plugin
The repo includes a ready-made testing sandbox at Then run 4. Write your test in 5. Run the script:
demo/testing/. Add your plugin there and run scripts against it without setting up a new project.1. Add your plugin as a workspace dependency in demo/testing/package.json:demo/testing/package.json
pnpm install from the repo root to link it.3. Register your plugin in the test corsair instance:demo/testing/src/server/corsair.ts
demo/testing/src/scripts/test-script.ts:demo/testing/src/scripts/test-script.ts
Build watch required
In a separate terminal, run the build watcher in your plugin package so changes are picked up immediately:Without this, the test sandbox will be running stale compiled output.
Tips
- Look at existing plugins for reference —
packages/github/andpackages/resend/are good examples at different complexity levels. - Auth headers go in
client.tsinside theHEADERSconfig object. Most APIs useAuthorization: Bearer <key>orAuthorization: <key>. - Webhook signature verification — update the
TODOinwebhooks/types.tswith the HMAC logic for your provider. - Database entities — define Zod schemas in
schema/database.tsfor any data you want to cache locally. Leaveentities: {}empty if you only need live API calls.