用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/corsairdev/agent --skill add-plugin命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | add-plugin |
| description | Add a new plugin. Use when user wants to add a plugin that Corsair does not natively support. |
You are helping a developer add a new custom plugin to their Corsair integration so they can call a third-party API through Corsair's pipeline.
Ask the developer two questions before doing anything else:
Use WebSearch or WebFetch to look up the API documentation. Find:
https://api.stripe.com/v1)Run the scaffold command:
npm run new-plugin <PluginName>
Use PascalCase (e.g., Stripe, Twilio, OpenAI). This creates server/plugins/<pluginname>.ts with a single-file boilerplate.
Open the generated file and fill it in based on the API docs:
1. Update API_BASE to the correct base URL.
2. Update the auth header to match the API:
// Bearer token (most common)
Authorization: `Bearer ${apiKey}`,
// API key in header
'X-API-Key': apiKey,
// Basic auth
Authorization: `Basic ${Buffer.from(`${apiKey}:`).toString('base64')}`,
3. Replace response types with actual shapes from the API docs:
type Customer = {
id: string;
email: string;
name: string | null;
created: number;
};
4. Replace the example endpoints with the ones the developer needs:
const customersGet: CorsairEndpoint<StripeContext, { id: string }, Customer> = async (ctx, input) => {
return apiRequest<Customer>(`customers/${input.id}`, ctx.key);
};
const customersCreate: CorsairEndpoint<StripeContext, { email: string; name?: string }, Customer> = async (ctx, input) => {
return apiRequest<Customer>('customers', ctx.key, {
method: 'POST',
body: { email: input.email, name: input.name },
});
};
5. Update the endpoint tree to group related endpoints:
const endpoints = {
customers: {
get: customersGet,
create: customersCreate,
list: customersList,
},
charges: {
create: chargesCreate,
},
} as const;
6. Update the plugin function name and id to match your plugin name.
The full structure of a complete single-file plugin looks like this:
import type {
BindEndpoints,
CorsairEndpoint,
CorsairPlugin,
CorsairPluginContext,
} from 'corsair/core';
type StripeOptions = { key: string };
const StripeSchema = { version: '1.0.0', entities: {} } as const;
type StripeContext = CorsairPluginContext<typeof StripeSchema, StripeOptions>;
type Customer = { id: string; email: string; name: string | null };
const API_BASE = 'https://api.stripe.com/v1';
async function apiRequest<T>(
path: string,
apiKey: string,
options: {
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
body?: Record<string, >;
?: <, | | | >;
} = {},
): <T> {
{ method = , body, query } = options;
url = ();
(query) {
( [k, v] .(query)) {
(v !== ) url..(k, (v));
}
}
res = (url.(), {
method,
: {
: ,
: ,
},
: body ? .(body) : ,
});
(!res.) {
();
}
(res. === ) { : } T;
res.() <T>;
}
: <, { : }, > = (ctx, input) => {
apiRequest<>(, ctx.);
};
endpoints = {
: { : customersGet },
} ;
webhooks = {} ;
defaultAuthType = ;
= < endpoints>;
< > = <
,
,
endpoints,
webhooks,
,
defaultAuthType
>;
stripe< >(
: & = {} & ,
): <> {
{
: ,
: ,
options,
endpoints,
: (_ctx, source) => {
(source === ) options.;
;
},
};
}
Open server/corsair.ts and add the plugin import and registration:
import { createCorsair, googlecalendar, linear, resend, slack } from 'corsair';
import { stripe } from './plugins/stripe'; // add this
import { pool } from './db';
export const corsair = createCorsair({
plugins: [slack(), linear(), resend(), googlecalendar(), stripe({ key: process.env.STRIPE_API_KEY! })], // add plugin here
database: pool,
kek: process.env.CORSAIR_KEK!,
multiTenancy: false,
});
Remind the developer to add the API key environment variable (e.g., STRIPE_API_KEY) to their .env file.
Open server/seed/examples.ts and add 2–3 examples showing how to use the new plugin. These are used by the AI agent to understand how to write code against this API.
Each example has a description (plain English, used for search) and code (a runnable async function):
{
description:
'Get a Stripe customer by their ID. Returns customer details including email, name, and metadata.',
code: `async function main() {
const customer = await corsair.stripe.api.customers.get({ id: 'cus_xxx' });
console.log(customer);
}
main().catch(console.error);`,
},
{
description:
'Create a new Stripe customer with an email address.',
code: `async function main() {
const customer = await corsair.stripe.api.customers.create({
email: 'user@example.com',
name: 'Jane Doe',
});
console.log(customer.id);
}
main().catch(console.error);`,
},
The API call pattern is always: corsair.<pluginId>.api.<endpointGroup>.<method>(input)
server/plugins/<name>.ts). No subdirectories.stripe({ key: process.env.STRIPE_API_KEY! }). No key manager needed.ctx.key inside endpoint implementations — Corsair populates it from the keyBuilder.id field in the plugin must be a unique string (lowercase, no spaces). It becomes the property name on corsair.*.