Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,6 @@ state.txt
**/orginal-sdk/
**/fixtures

/store
/store

.claude/settings.local.json
24 changes: 21 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,37 @@
"db:push": "drizzle-kit push",
"db:studio": "drizzle-kit studio",
"script": "tsx server/script.ts",
"mcp": "tsx server/mcp-server.ts",
"new-plugin": "tsx scripts/new-plugin.ts",
"format": "biome format . --write",
"lint": "biome check .",
"lint:fix": "biome check . --fix --unsafe",
"test": "vitest run",
"test:watch": "vitest",
"available-plugins": "tsx scripts/available-plugins.ts"
"available-plugins": "tsx scripts/available-plugins.ts",
"test:mcp": "tsx scripts/test-mcp.ts",
"test:mcp:base": "tsx scripts/test-base-mcp.ts",
"test:mcp:claude": "tsx scripts/test-claude-tools.ts",
"test:mcp:http": "tsx scripts/test-mcp-http.ts",
"test:openai": "tsx scripts/test-openai.ts",
"test:claude-sdk": "tsx scripts/test-claude-sdk.ts",
"test:webhook": "tsx scripts/test-webhook.ts",
"test:cron": "tsx scripts/test-cron.ts",
"test:claude-api": "tsx scripts/test-claude-api.ts"
},
"dependencies": {
"@ai-sdk/anthropic": "^3.0.58",
"@anthropic-ai/claude-agent-sdk": "^0.2.52",
"@anthropic-ai/sdk": "^0.78.0",
"@corsair-dev/mcp": "^0.1.7",
"@corsair/ui": "@corsair-dev/ui",
"@modelcontextprotocol/sdk": "^1.27.1",
"@openai/agents": "^0.5.4",
"@trpc/server": "^11.10.0",
"@whiskeysockets/baileys": "^7.0.0-rc.9",
"ai": "6.0.37",
"chokidar": "^4.0.3",
"corsair": "0.1.13",
"corsair": "0.1.26",
"dotenv": "^16.4.0",
"drizzle-orm": "^0.44.5",
"express": "^4.21.0",
Expand All @@ -37,7 +54,8 @@
"pg": "^8.13.0",
"pino": "^9.6.0",
"tsx": "^4.19.0",
"zod": "^3.25.0"
"zod": "^3.25.0",
"zod-to-json-schema": "^3.25.0"
},
"pnpm": {
"onlyBuiltDependencies": [
Expand Down
531 changes: 513 additions & 18 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions scripts/test-claude-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'dotenv/config';
import Anthropic from '@anthropic-ai/sdk';
import { AnthropicProvider } from '@corsair-dev/mcp';
import { corsair } from '../server/corsair';

// Initialize Corsair tools
const provider = new AnthropicProvider();
const tools = provider.build({ corsair });

const client = new Anthropic();

// Run with automatic tool loop
const message = await client.beta.messages.toolRunner({
model: 'claude-opus-4-6',
max_tokens: 4096,
tools,
messages: [
{ role: 'user', content: 'list all slack channels, send test message to sdk-test channel' },
],
});

for (const block of message.content) {
if (block.type === 'text') process.stdout.write(block.text);
}
31 changes: 31 additions & 0 deletions scripts/test-claude-sdk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'dotenv/config';
import { createSdkMcpServer, query } from '@anthropic-ai/claude-agent-sdk';
import { ClaudeProvider } from '@corsair-dev/mcp';
import { corsair } from '../server/corsair';

// Initialize Corsair MCP tools
const provider = new ClaudeProvider();
const tools = await provider.build({ corsair });

// Create in-process MCP server
const server = createSdkMcpServer({ name: 'corsair', tools });

// Query Claude with MCP tools
const stream = query({
prompt: 'list all slack channels, send test message to sdk-test channel',
options: {
model: 'claude-opus-4-6',
permissionMode: 'bypassPermissions',
allowDangerouslySkipPermissions: true,
mcpServers: {
corsair: server,
},
},
});

// Stream the response
for await (const event of stream) {
if ('result' in event) {
process.stdout.write(event.result);
}
}
18 changes: 18 additions & 0 deletions scripts/test-cron.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'dotenv/config';
import { corsair } from '../server/corsair'; // imported for type safety — injected at runtime
import { workflow } from '../server/sdk';

await workflow.cron({
id: 'morningSlackReport',
description: 'Posts a morning message to #sdk-test every weekday at 9am',
schedule: '0 9 * * 1-5',
handler: async () => {
await corsair.slack.api.messages.post({
channel: 'C0A3ZTB9X7X',
text: 'Good morning! Your daily report is ready.',
});
},
});

const workflows = await workflow.list('cron');
console.table(workflows.map((w) => ({ name: w.name, schedule: (w.triggerConfig as any)?.cron, status: w.status })));
16 changes: 16 additions & 0 deletions scripts/test-mcp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import 'dotenv/config';
import Anthropic from '@anthropic-ai/sdk';
import { getCorsairMcp } from '../server/sdk';

const anthropic = new Anthropic();
const mcp = getCorsairMcp();

const response = await anthropic.beta.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 4096,
mcp_servers: [{ type: 'url', name: 'corsair', url: mcp.url }],
messages: [{ role: 'user', content: 'List all available operations' }],
betas: ['mcp-client-2025-04-04'],
});

console.log(response.content);
20 changes: 20 additions & 0 deletions scripts/test-openai-agents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'dotenv/config';
import { Agent, run, tool } from '@openai/agents';
import { OpenAIAgentsProvider } from '@corsair-dev/mcp';
import { corsair } from '../server/corsair';

// Initialize Corsair tools for OpenAI Agents SDK
const provider = new OpenAIAgentsProvider();
const tools = provider.build({ corsair, tool });

// Create an agent with Corsair tools
const agent = new Agent({
name: 'corsair-agent',
model: 'gpt-4.1',
instructions: 'You are a helpful assistant with access to Corsair tools. Use list_operations to discover available APIs, get_schema to understand required arguments, and corsair_run to execute them. When referencing resources (like channels), always use their ID, not their name. If a tool call fails, use get_schema to check the expected arguments and retry.',
tools,
});

// Run the agent
const result = await run(agent, 'list all slack channels and send test message to sdk-test channel');
console.log(result.finalOutput);
19 changes: 19 additions & 0 deletions scripts/test-webhook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'dotenv/config';
import { corsair } from '../server/corsair'; // imported for type safety — injected at runtime
import { workflow } from '../server/sdk';

await workflow.webhook({
id: 'forwardSlackMessageToSdkTest',
description: 'Forwards every Slack message to #sdk-test',
trigger: { plugin: 'slack', action: 'messages.message' },
handler: async (event: any) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any way to strongly type this event? seems unsafe to assert it to any

if (!event?.text || event?.channel === 'C0A3ZTB9X7X') return;
await corsair.slack.api.messages.post({
channel: 'C0A3ZTB9X7X',
text: `[forwarded] <@${event.user}>: ${event.text}`,
});
},
});

const workflows = await workflow.list('webhook');
console.table(workflows.map((w) => ({ name: w.name, trigger: JSON.stringify(w.triggerConfig), status: w.status })));
Loading
Loading