Create Your Own Plugin
Create your own plugin for Corsair
The fastest way to build a custom plugin is to use the built-in generator. It scaffolds the full directory structure, wires up types, and registers your plugin — then you (or Claude Code) fill in the real API calls.
Fork or clone the Corsair repo
Plugins live inside the monorepo alongside the core library.
git clone https://github.com/corsair-dev/corsair.git
cd corsair
pnpm installRun the plugin generator
Pass your plugin name in PascalCase — e.g. Stripe, GoogleCalendar, HubSpot.
pnpm run generate:plugin <PluginName>For example:
pnpm run generate:plugin StripeThis creates packages/stripe/ with the full plugin structure:
packages/stripe/
├── index.ts
├── client.ts
├── error-handlers.ts
├── package.json
├── tsconfig.json
├── tsup.config.ts
├── endpoints/
│ ├── index.ts
│ ├── types.ts
│ └── example.ts
├── webhooks/
│ ├── index.ts
│ ├── types.ts
│ └── example.ts
└── schema/
├── index.ts
└── database.tsIt also automatically registers your plugin in packages/corsair/core/constants.ts.
Choose your auth type
Open packages/<yourplugin>/index.ts and update the auth type to match the API you're integrating with.
API key (most REST APIs):
authType?: PickAuth<'api_key'>;OAuth 2 (Google, GitHub, etc.):
authType?: PickAuth<'oauth_2'>;Also update the defaultAuthType constant and authConfig to match:
const defaultAuthType: AuthTypes = 'api_key'; // or 'oauth_2'
export const stripeAuthConfig = {
api_key: {
account: ['one'] as const,
},
} as const satisfies PluginAuthConfig;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:
I've generated a Corsair plugin scaffold at packages/stripe/.
Please implement it using the Stripe API docs at https://docs.stripe.com/api.
- Update client.ts with the correct base URL and auth headers (Bearer token)
- Replace the example endpoint with real Stripe endpoints (e.g. list customers, get invoice)
- Update the schema/database.ts with relevant entity shapes
- Remove the example webhook and add real Stripe webhook event typesClaude Code can read the scaffold, understand the patterns from existing plugins (e.g. packages/github/), and produce a working starting point.
Typecheck and build
cd packages/<yourplugin>
pnpm typecheck
pnpm buildFix any type errors, then register the plugin in your app the same way as any other Corsair plugin:
import { stripe } from '@corsair-dev/stripe';
export const corsair = createCorsair({
plugins: [stripe({ key: process.env.STRIPE_API_KEY })],
database: db,
kek: process.env.CORSAIR_KEK!,
});Test your plugin
The repo includes a ready-made testing sandbox at 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:
{
"dependencies": {
"@corsair-dev/stripe": "workspace:*"
}
}Then run pnpm install from the repo root to link it.
3. Register your plugin in the test corsair instance:
import { stripe } from '@corsair-dev/stripe';
export const corsair = createCorsair({
plugins: [
// ... existing plugins
stripe({ key: process.env.STRIPE_API_KEY }),
],
database: sqlite,
kek: process.env.CORSAIR_KEK!,
});4. Write your test in demo/testing/src/scripts/test-script.ts:
import { corsair } from '@/server/corsair';
import 'dotenv/config';
const main = async () => {
const customer = await corsair.stripe.api.customers.get({ id: 'cus_123' });
console.log(customer);
};
main();5. Run the script:
cd demo/testing
pnpm run testBuild watch required
In a separate terminal, run the build watcher in your plugin package so changes are picked up immediately:
cd packages/stripe
pnpm run build --watchWithout 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.