openbird 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * OpenBird Basic Usage Example
5
+ *
6
+ * This example demonstrates the two integration surfaces OpenBird provides:
7
+ *
8
+ * 1. Webhook server — receives real-time Feishu messages via HTTP POST
9
+ * 2. MCP client — calls Feishu API tools (send message, search, etc.)
10
+ *
11
+ * ── Quick start ──────────────────────────────────────────────────────
12
+ *
13
+ * # 1. Copy .env.example and fill in your cookie
14
+ * cp .env.example .env
15
+ * # edit .env → set OPENBIRD_COOKIE
16
+ *
17
+ * # 2. Run this example (it sets OPENBIRD_WEBHOOK_URL automatically)
18
+ * node examples/basic-usage.mjs
19
+ *
20
+ * ── What happens ─────────────────────────────────────────────────────
21
+ *
22
+ * • openbird-webhooks starts an HTTP server on a free port.
23
+ * • OpenBird is spawned as a child process with OPENBIRD_WEBHOOK_URL
24
+ * pointing at that server.
25
+ * • The MCP client connects to OpenBird over stdio.
26
+ * • Incoming Feishu messages are printed to the console.
27
+ * • After startup, the available MCP tools are listed, and
28
+ * `get_calendar_events` is called as a demo.
29
+ *
30
+ * ─────────────────────────────────────────────────────────────────────
31
+ */
32
+
33
+ import 'dotenv/config';
34
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
35
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
36
+ import { createServer } from 'openbird-webhook-node';
37
+
38
+ // ── 0. Preflight check ──────────────────────────────────────────────
39
+
40
+ if (!process.env.OPENBIRD_COOKIE) {
41
+ console.error('Error: OPENBIRD_COOKIE is not set.');
42
+ console.error('Copy .env.example to .env and paste your Feishu cookie.');
43
+ process.exit(1);
44
+ }
45
+
46
+ // ── 1. Start webhook receiver (openbird-webhooks) ────────────────────
47
+
48
+ const receiver = createServer();
49
+
50
+ receiver.on('im.message.*', (event) => {
51
+ const { data } = event;
52
+ const sender = data.sender?.id ?? '?';
53
+ const chat = data.conversation?.id ?? '?';
54
+ const chatType = data.conversation?.type ?? '?';
55
+ const contentType = data.content?.type ?? '?';
56
+ const text = data.content?.text ?? '';
57
+ const preview = text.length > 80 ? text.slice(0, 80) + '...' : text;
58
+
59
+ console.log(
60
+ `[message] ${chatType} | chat=${chat} | from=${sender} | ${contentType}: ${preview}`
61
+ );
62
+ });
63
+
64
+ receiver.on('system.*', (event) => {
65
+ console.log(`[event] ${event.type}`, JSON.stringify(event.data).slice(0, 120));
66
+ });
67
+
68
+ // Listen on a random free port
69
+ const httpServer = await receiver.listen(0, '127.0.0.1');
70
+ const webhookPort = httpServer.address().port;
71
+ const webhookUrl = `http://127.0.0.1:${webhookPort}/`;
72
+
73
+ // ── 2. Spawn OpenBird & connect MCP client ───────────────────────────
74
+
75
+ const transport = new StdioClientTransport({
76
+ command: 'npx',
77
+ args: ['openbird'],
78
+ env: {
79
+ ...process.env,
80
+ OPENBIRD_COOKIE: process.env.OPENBIRD_COOKIE,
81
+ OPENBIRD_WEBHOOK_URL: webhookUrl,
82
+ },
83
+ stderr: 'inherit', // OpenBird logs go to our stderr
84
+ });
85
+
86
+ const client = new Client({ name: 'example-client', version: '1.0.0' });
87
+ await client.connect(transport);
88
+ console.log('[example] MCP client connected to OpenBird');
89
+
90
+ // ── 3. List available tools ──────────────────────────────────────────
91
+
92
+ const { tools } = await client.listTools();
93
+ console.log(`[example] ${tools.length} tools available:`);
94
+ for (const tool of tools) {
95
+ console.log(` - ${tool.name}: ${tool.description}`);
96
+ }
97
+
98
+ // ── 4. Demo: call a tool ─────────────────────────────────────────────
99
+
100
+ console.log('\n[example] Calling get_calendar_events ...');
101
+ try {
102
+ const result = await client.callTool({ name: 'get_calendar_events', arguments: {} });
103
+ console.log('[example] Result:', JSON.stringify(result.content, null, 2));
104
+ } catch (err) {
105
+ console.error('[example] Tool call failed:', err.message);
106
+ }
107
+
108
+ // ── 5. Wait for incoming messages ────────────────────────────────────
109
+
110
+ console.log('\n[example] Listening for incoming Feishu messages (Ctrl+C to quit) ...\n');
111
+
112
+ process.on('SIGINT', async () => {
113
+ console.log('\n[example] Shutting down ...');
114
+ await client.close();
115
+ await receiver.close();
116
+ process.exit(0);
117
+ });
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "openbird",
3
+ "version": "1.0.0",
4
+ "description": "Feishu infrastructure service — WebSocket event forwarding + MCP Server",
5
+ "type": "module",
6
+ "bin": {
7
+ "openbird": "./bin/openbird.js"
8
+ },
9
+ "main": "src/index.js",
10
+ "scripts": {
11
+ "start": "node bin/openbird.js",
12
+ "generate:proto": "protoc --plugin=protoc-gen-es=node_modules/.bin/protoc-gen-es --proto_path=src/core/proto --es_out=src/core/proto src/core/proto/proto.proto"
13
+ },
14
+ "keywords": [
15
+ "feishu",
16
+ "lark",
17
+ "mcp",
18
+ "websocket",
19
+ "openbird"
20
+ ],
21
+ "license": "MIT",
22
+ "dependencies": {
23
+ "@bufbuild/protobuf": "^2.11.0",
24
+ "@modelcontextprotocol/sdk": "^1.12.1",
25
+ "axios": "^1.13.3",
26
+ "dotenv": "^17.2.3",
27
+ "pako": "^2.1.0",
28
+ "ws": "^8.14.0",
29
+ "zod": "^3.24.0"
30
+ },
31
+ "devDependencies": {
32
+ "@bufbuild/protoc-gen-es": "^2.11.0",
33
+ "openbird-webhook-node": "^1.0.0"
34
+ },
35
+ "engines": {
36
+ "node": ">=18.0.0"
37
+ }
38
+ }