@abraca/mcp 2.6.0 → 2.8.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.
package/src/index.ts CHANGED
@@ -24,84 +24,94 @@
24
24
  * schema before forwarding to the server.
25
25
  * When unset, behaviour is unchanged.
26
26
  */
27
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
28
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
29
- import { AbracadabraMCPServer, type TriggerMode } from './server.ts'
30
- import { registerTreeTools } from './tools/tree.ts'
31
- import { registerContentTools } from './tools/content.ts'
32
- import { registerMetaTools } from './tools/meta.ts'
33
- import { registerFileTools } from './tools/files.ts'
34
- import { registerAwarenessTools } from './tools/awareness.ts'
35
- import { registerChannelTools } from './tools/channel.ts'
36
- import { registerSvgTools } from './tools/svg.ts'
37
- import { registerAgentGuide } from './resources/agent-guide.ts'
38
- import { registerTreeResource } from './resources/tree-resource.ts'
39
- import { registerServerInfoResource } from './resources/server-info.ts'
40
- import { registerHookTools } from './tools/hooks.ts'
41
- import { HookBridge } from './hook-bridge.ts'
42
- import { loadSchemaBundle, SchemaBundleLoadError } from './schema/loader.ts'
43
- import type { SchemaBundleValidator } from './schema/validator.ts'
27
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
28
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
29
+ import { HookBridge } from "./hook-bridge.ts";
30
+ import { registerAgentGuide } from "./resources/agent-guide.ts";
31
+ import { registerServerInfoResource } from "./resources/server-info.ts";
32
+ import { registerTreeResource } from "./resources/tree-resource.ts";
33
+ import { loadSchemaBundle, SchemaBundleLoadError } from "./schema/loader.ts";
34
+ import type { SchemaBundleValidator } from "./schema/validator.ts";
35
+ import { AbracadabraMCPServer, type TriggerMode } from "./server.ts";
36
+ import { registerAwarenessTools } from "./tools/awareness.ts";
37
+ import { registerChannelTools } from "./tools/channel.ts";
38
+ import { registerContentTools } from "./tools/content.ts";
39
+ import { registerFileTools } from "./tools/files.ts";
40
+ import { registerHookTools } from "./tools/hooks.ts";
41
+ import { registerMetaTools } from "./tools/meta.ts";
42
+ import { registerSvgTools } from "./tools/svg.ts";
43
+ import { registerTreeTools } from "./tools/tree.ts";
44
44
 
45
45
  async function main() {
46
- const url = process.env.ABRA_URL
47
-
48
- if (!url) {
49
- console.error('Missing required environment variable: ABRA_URL')
50
- process.exit(1)
51
- }
52
-
53
- // Parse trigger mode (defaults to mention+task)
54
- const rawMode = (process.env.ABRA_AGENT_TRIGGER_MODE ?? 'mention+task').trim().toLowerCase()
55
- const validModes: TriggerMode[] = ['all', 'mention', 'task', 'mention+task']
56
- const triggerMode = (validModes as string[]).includes(rawMode)
57
- ? (rawMode as TriggerMode)
58
- : 'mention+task'
59
- if (rawMode && !(validModes as string[]).includes(rawMode)) {
60
- console.error(`[abracadabra-mcp] Invalid ABRA_AGENT_TRIGGER_MODE="${rawMode}", falling back to "mention+task"`)
61
- }
62
-
63
- const aliasEnv = process.env.ABRA_AGENT_MENTION_ALIASES
64
- const mentionAliases: string[] | undefined = aliasEnv
65
- ? aliasEnv.split(',').map((a: string) => a.trim()).filter((a: string) => a.length > 0)
66
- : undefined
67
-
68
- // Create the Abracadabra connection manager
69
- const server = new AbracadabraMCPServer({
70
- url,
71
- agentName: process.env.ABRA_AGENT_NAME,
72
- agentColor: process.env.ABRA_AGENT_COLOR,
73
- inviteCode: process.env.ABRA_INVITE_CODE,
74
- keyFile: process.env.ABRA_KEY_FILE,
75
- triggerMode,
76
- mentionAliases,
77
- })
78
-
79
- console.error(`[abracadabra-mcp] Trigger mode: ${triggerMode}; aliases: ${server.mentionAliases.join(', ')}`)
80
-
81
- // Optional schema bundle. When set, update_metadata + create_document validate
82
- // `meta` against the resolved doc-type's schema before forwarding. When unset,
83
- // behaviour is identical to today (Rules 2 + 4 in feedback_schema_free_core.md).
84
- let schemaValidator: SchemaBundleValidator | null = null
85
- const schemaBundlePath = process.env.ABRA_MCP_SCHEMA_BUNDLE
86
- if (schemaBundlePath && schemaBundlePath.trim().length > 0) {
87
- try {
88
- schemaValidator = loadSchemaBundle(schemaBundlePath)
89
- console.error(
90
- `[abracadabra-mcp] Loaded schema bundle from ${schemaBundlePath}; known doc-types: ${schemaValidator.knownTypes.join(', ')}`,
91
- )
92
- } catch (err) {
93
- const msg = err instanceof SchemaBundleLoadError ? err.message : String(err)
94
- console.error(`[abracadabra-mcp] ${msg}`)
95
- process.exit(1)
96
- }
97
- }
98
-
99
- // Create MCP server with channel capability
100
- const mcp = new McpServer(
101
- { name: 'abracadabra', version: '1.0.0' },
102
- {
103
- capabilities: { experimental: { 'claude/channel': {} } },
104
- instructions: `Abracadabra is a CRDT collaboration platform where everything is a document in a tree.
46
+ const url = process.env.ABRA_URL;
47
+
48
+ if (!url) {
49
+ console.error("Missing required environment variable: ABRA_URL");
50
+ process.exit(1);
51
+ }
52
+
53
+ // Parse trigger mode (defaults to mention+task)
54
+ const rawMode = (process.env.ABRA_AGENT_TRIGGER_MODE ?? "mention+task")
55
+ .trim()
56
+ .toLowerCase();
57
+ const validModes: TriggerMode[] = ["all", "mention", "task", "mention+task"];
58
+ const triggerMode = (validModes as string[]).includes(rawMode)
59
+ ? (rawMode as TriggerMode)
60
+ : "mention+task";
61
+ if (rawMode && !(validModes as string[]).includes(rawMode)) {
62
+ console.error(
63
+ `[abracadabra-mcp] Invalid ABRA_AGENT_TRIGGER_MODE="${rawMode}", falling back to "mention+task"`,
64
+ );
65
+ }
66
+
67
+ const aliasEnv = process.env.ABRA_AGENT_MENTION_ALIASES;
68
+ const mentionAliases: string[] | undefined = aliasEnv
69
+ ? aliasEnv
70
+ .split(",")
71
+ .map((a: string) => a.trim())
72
+ .filter((a: string) => a.length > 0)
73
+ : undefined;
74
+
75
+ // Create the Abracadabra connection manager
76
+ const server = new AbracadabraMCPServer({
77
+ url,
78
+ agentName: process.env.ABRA_AGENT_NAME,
79
+ agentColor: process.env.ABRA_AGENT_COLOR,
80
+ inviteCode: process.env.ABRA_INVITE_CODE,
81
+ keyFile: process.env.ABRA_KEY_FILE,
82
+ triggerMode,
83
+ mentionAliases,
84
+ });
85
+
86
+ console.error(
87
+ `[abracadabra-mcp] Trigger mode: ${triggerMode}; aliases: ${server.mentionAliases.join(", ")}`,
88
+ );
89
+
90
+ // Optional schema bundle. When set, update_metadata + create_document validate
91
+ // `meta` against the resolved doc-type's schema before forwarding. When unset,
92
+ // behaviour is identical to today (Rules 2 + 4 in feedback_schema_free_core.md).
93
+ let schemaValidator: SchemaBundleValidator | null = null;
94
+ const schemaBundlePath = process.env.ABRA_MCP_SCHEMA_BUNDLE;
95
+ if (schemaBundlePath && schemaBundlePath.trim().length > 0) {
96
+ try {
97
+ schemaValidator = loadSchemaBundle(schemaBundlePath);
98
+ console.error(
99
+ `[abracadabra-mcp] Loaded schema bundle from ${schemaBundlePath}; known doc-types: ${schemaValidator.knownTypes.join(", ")}`,
100
+ );
101
+ } catch (err) {
102
+ const msg =
103
+ err instanceof SchemaBundleLoadError ? err.message : String(err);
104
+ console.error(`[abracadabra-mcp] ${msg}`);
105
+ process.exit(1);
106
+ }
107
+ }
108
+
109
+ // Create MCP server with channel capability
110
+ const mcp = new McpServer(
111
+ { name: "abracadabra", version: "1.0.0" },
112
+ {
113
+ capabilities: { experimental: { "claude/channel": {} } },
114
+ instructions: `Abracadabra is a CRDT collaboration platform where everything is a document in a tree.
105
115
 
106
116
  ## CRITICAL: Responding to Channel Events
107
117
  The user CANNOT see your plain text output — they only see messages sent via MCP tools. When you receive a channel event:
@@ -136,68 +146,72 @@ The user CANNOT see your plain text output — they only see messages sent via M
136
146
 
137
147
  ## Full Reference
138
148
  Read the resource at abracadabra://agent-guide for the complete guide covering page type schemas, metadata reference, awareness/presence, content structure, and detailed examples.`,
139
- },
140
- )
141
-
142
- // Register tools
143
- registerTreeTools(mcp, server, schemaValidator)
144
- registerContentTools(mcp, server)
145
- registerMetaTools(mcp, server, schemaValidator)
146
- registerFileTools(mcp, server)
147
- registerAwarenessTools(mcp, server)
148
- registerChannelTools(mcp, server)
149
- registerSvgTools(mcp, server)
150
-
151
- // Register resources
152
- registerAgentGuide(mcp)
153
- registerTreeResource(mcp, server)
154
- registerServerInfoResource(mcp, server)
155
-
156
- // Connect to Abracadabra server
157
- try {
158
- await server.connect()
159
- } catch (error: any) {
160
- console.error(`[abracadabra-mcp] Failed to connect: ${error.message}`)
161
- process.exit(1)
162
- }
163
-
164
- // Start Claude Code hook bridge (HTTP server for activity events)
165
- const hookBridge = new HookBridge(server)
166
- try {
167
- const hookPort = await hookBridge.start()
168
- console.error(`[abracadabra-mcp] Hook bridge listening on port ${hookPort}`)
169
- } catch (error: any) {
170
- console.error(`[abracadabra-mcp] Hook bridge failed to start: ${error.message}`)
171
- }
172
-
173
- // Register hook config tool (must be after bridge starts so port is available)
174
- registerHookTools(mcp, hookBridge)
175
-
176
- // Start MCP stdio transport
177
- const transport = new StdioServerTransport()
178
- await mcp.connect(transport)
179
-
180
- // Wire up real-time channel notifications (awareness → channel dispatch)
181
- server.startChannelNotifications(mcp)
182
- console.error('[abracadabra-mcp] MCP server running on stdio')
183
-
184
- // Graceful shutdown
185
- const shutdown = async () => {
186
- console.error('[abracadabra-mcp] Shutting down...')
187
- await hookBridge.destroy()
188
- await server.destroy()
189
- process.exit(0)
190
- }
191
-
192
- process.on('SIGINT', shutdown)
193
- process.on('SIGTERM', shutdown)
149
+ },
150
+ );
151
+
152
+ // Register tools
153
+ registerTreeTools(mcp, server, schemaValidator);
154
+ registerContentTools(mcp, server);
155
+ registerMetaTools(mcp, server, schemaValidator);
156
+ registerFileTools(mcp, server);
157
+ registerAwarenessTools(mcp, server);
158
+ registerChannelTools(mcp, server);
159
+ registerSvgTools(mcp, server);
160
+
161
+ // Register resources
162
+ registerAgentGuide(mcp);
163
+ registerTreeResource(mcp, server);
164
+ registerServerInfoResource(mcp, server);
165
+
166
+ // Connect to Abracadabra server
167
+ try {
168
+ await server.connect();
169
+ } catch (error: any) {
170
+ console.error(`[abracadabra-mcp] Failed to connect: ${error.message}`);
171
+ process.exit(1);
172
+ }
173
+
174
+ // Start Claude Code hook bridge (HTTP server for activity events)
175
+ const hookBridge = new HookBridge(server);
176
+ try {
177
+ const hookPort = await hookBridge.start();
178
+ console.error(
179
+ `[abracadabra-mcp] Hook bridge listening on port ${hookPort}`,
180
+ );
181
+ } catch (error: any) {
182
+ console.error(
183
+ `[abracadabra-mcp] Hook bridge failed to start: ${error.message}`,
184
+ );
185
+ }
186
+
187
+ // Register hook config tool (must be after bridge starts so port is available)
188
+ registerHookTools(mcp, hookBridge);
189
+
190
+ // Start MCP stdio transport
191
+ const transport = new StdioServerTransport();
192
+ await mcp.connect(transport);
193
+
194
+ // Wire up real-time channel notifications (awareness → channel dispatch)
195
+ server.startChannelNotifications(mcp);
196
+ console.error("[abracadabra-mcp] MCP server running on stdio");
197
+
198
+ // Graceful shutdown
199
+ const shutdown = async () => {
200
+ console.error("[abracadabra-mcp] Shutting down...");
201
+ await hookBridge.destroy();
202
+ await server.destroy();
203
+ process.exit(0);
204
+ };
205
+
206
+ process.on("SIGINT", shutdown);
207
+ process.on("SIGTERM", shutdown);
194
208
  }
195
209
 
196
210
  main().catch((error) => {
197
- console.error('[abracadabra-mcp] Fatal error:', error)
198
- process.exit(1)
199
- })
211
+ console.error("[abracadabra-mcp] Fatal error:", error);
212
+ process.exit(1);
213
+ });
200
214
 
215
+ export type { MCPServerConfig } from "./server.ts";
201
216
  // Re-export for library usage
202
- export { AbracadabraMCPServer } from './server.ts'
203
- export type { MCPServerConfig } from './server.ts'
217
+ export { AbracadabraMCPServer } from "./server.ts";