@dot-ai/adapter-claude 0.5.2 → 0.7.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,186 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * dot-ai MCP server for Claude Code.
4
+ * Exposes extension tools as MCP tools via stdio transport.
5
+ * Zero dependencies — speaks JSON-RPC 2.0 directly.
6
+ *
7
+ * Usage in .claude/settings.json:
8
+ * "mcpServers": {
9
+ * "dot-ai": {
10
+ * "command": "node",
11
+ * "args": ["path/to/mcp-server.js"]
12
+ * }
13
+ * }
14
+ */
15
+ import { DotAiRuntime } from '@dot-ai/core';
16
+ // ── MCP Protocol constants ──
17
+ const PROTOCOL_VERSION = '2024-11-05';
18
+ const SERVER_NAME = 'dot-ai';
19
+ const SERVER_VERSION = '0.6.0';
20
+ // ── State ──
21
+ let capabilities = [];
22
+ let initialized = false;
23
+ let initPromise = null;
24
+ async function ensureInit() {
25
+ if (initialized)
26
+ return;
27
+ if (!initPromise) {
28
+ initPromise = initCapabilities();
29
+ }
30
+ return initPromise;
31
+ }
32
+ // ── Initialize runtime ──
33
+ async function initCapabilities() {
34
+ if (initialized)
35
+ return;
36
+ try {
37
+ const workspaceRoot = process.cwd();
38
+ const runtime = new DotAiRuntime({ workspaceRoot });
39
+ await runtime.boot();
40
+ capabilities = runtime.capabilities;
41
+ initialized = true;
42
+ }
43
+ catch (err) {
44
+ process.stderr.write(`[dot-ai-mcp] Init error: ${err}\n`);
45
+ }
46
+ }
47
+ // ── MCP method handlers ──
48
+ function handleInitialize(_params) {
49
+ return {
50
+ protocolVersion: PROTOCOL_VERSION,
51
+ capabilities: {
52
+ tools: {},
53
+ },
54
+ serverInfo: {
55
+ name: SERVER_NAME,
56
+ version: SERVER_VERSION,
57
+ },
58
+ };
59
+ }
60
+ async function handleToolsList() {
61
+ await ensureInit();
62
+ return {
63
+ tools: capabilities.map((cap) => ({
64
+ name: cap.name,
65
+ description: cap.description,
66
+ inputSchema: {
67
+ ...cap.parameters,
68
+ },
69
+ })),
70
+ };
71
+ }
72
+ async function handleToolsCall(params) {
73
+ await ensureInit();
74
+ const name = params.name;
75
+ const args = (params.arguments ?? {});
76
+ const cap = capabilities.find((c) => c.name === name);
77
+ if (!cap) {
78
+ return {
79
+ content: [{ type: 'text', text: `Unknown tool: ${name}` }],
80
+ isError: true,
81
+ };
82
+ }
83
+ try {
84
+ const result = await cap.execute(args);
85
+ return {
86
+ content: [{ type: 'text', text: result.text }],
87
+ };
88
+ }
89
+ catch (err) {
90
+ return {
91
+ content: [{ type: 'text', text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
92
+ isError: true,
93
+ };
94
+ }
95
+ }
96
+ // ── Message handling ──
97
+ function send(msg) {
98
+ const json = JSON.stringify(msg);
99
+ process.stdout.write(`Content-Length: ${Buffer.byteLength(json)}\r\n\r\n${json}`);
100
+ }
101
+ async function handleMessage(msg) {
102
+ // Notifications (no id) — just acknowledge
103
+ if (msg.method === 'notifications/initialized') {
104
+ ensureInit().catch((err) => process.stderr.write(`[dot-ai-mcp] Init error: ${err}\n`));
105
+ return;
106
+ }
107
+ if (msg.method === 'notifications/cancelled') {
108
+ return;
109
+ }
110
+ const id = msg.id;
111
+ try {
112
+ let result;
113
+ switch (msg.method) {
114
+ case 'initialize':
115
+ result = handleInitialize(msg.params ?? {});
116
+ break;
117
+ case 'tools/list':
118
+ result = await handleToolsList();
119
+ break;
120
+ case 'tools/call':
121
+ result = await handleToolsCall(msg.params ?? {});
122
+ break;
123
+ case 'ping':
124
+ result = {};
125
+ break;
126
+ default:
127
+ send({
128
+ jsonrpc: '2.0',
129
+ id,
130
+ error: { code: -32601, message: `Method not found: ${msg.method}` },
131
+ });
132
+ return;
133
+ }
134
+ send({ jsonrpc: '2.0', id, result });
135
+ }
136
+ catch (err) {
137
+ send({
138
+ jsonrpc: '2.0',
139
+ id,
140
+ error: {
141
+ code: -32603,
142
+ message: err instanceof Error ? err.message : String(err),
143
+ },
144
+ });
145
+ }
146
+ }
147
+ // ── Stdio transport (Content-Length framing) ──
148
+ function main() {
149
+ let buffer = '';
150
+ process.stdin.on('data', (chunk) => {
151
+ buffer += chunk.toString('utf-8');
152
+ // Process all complete messages in buffer
153
+ while (true) {
154
+ // Look for Content-Length header
155
+ const headerEnd = buffer.indexOf('\r\n\r\n');
156
+ if (headerEnd === -1)
157
+ break;
158
+ const header = buffer.slice(0, headerEnd);
159
+ const match = header.match(/Content-Length:\s*(\d+)/i);
160
+ if (!match) {
161
+ // Skip malformed header
162
+ buffer = buffer.slice(headerEnd + 4);
163
+ continue;
164
+ }
165
+ const contentLength = parseInt(match[1], 10);
166
+ const bodyStart = headerEnd + 4;
167
+ if (buffer.length < bodyStart + contentLength) {
168
+ // Wait for more data
169
+ break;
170
+ }
171
+ const body = buffer.slice(bodyStart, bodyStart + contentLength);
172
+ buffer = buffer.slice(bodyStart + contentLength);
173
+ try {
174
+ const msg = JSON.parse(body);
175
+ handleMessage(msg).catch((err) => {
176
+ process.stderr.write(`[dot-ai-mcp] Handler error: ${err}\n`);
177
+ });
178
+ }
179
+ catch {
180
+ process.stderr.write('[dot-ai-mcp] Failed to parse JSON-RPC message\n');
181
+ }
182
+ }
183
+ });
184
+ process.stderr.write('[dot-ai-mcp] Server started\n');
185
+ }
186
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dot-ai/adapter-claude",
3
- "version": "0.5.2",
3
+ "version": "0.7.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/jogelin/dot-ai",
@@ -10,10 +10,11 @@
10
10
  "main": "dist/index.js",
11
11
  "types": "dist/index.d.ts",
12
12
  "bin": {
13
- "dot-ai-hook": "dist/hook.js"
13
+ "dot-ai-hook": "dist/hook.js",
14
+ "dot-ai-mcp": "dist/mcp-server.js"
14
15
  },
15
16
  "dependencies": {
16
- "@dot-ai/core": "0.5.2"
17
+ "@dot-ai/core": "0.7.0"
17
18
  },
18
19
  "devDependencies": {
19
20
  "@types/node": "^22.0.0",
package/plugin.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "dot-ai",
3
3
  "description": "dot-ai — deterministic context enrichment for Claude Code",
4
- "version": "0.4.0",
4
+ "version": "0.7.0",
5
5
  "author": {
6
6
  "name": "Jonathan Gelin",
7
7
  "url": "https://smartsdlc.dev"
8
8
  },
9
- "homepage": "https://github.com/smartsdlc/dot-ai-plugin",
9
+ "homepage": "https://github.com/jogelin/dot-ai",
10
10
  "repository": {
11
11
  "type": "git",
12
- "url": "https://github.com/smartsdlc/dot-ai-plugin"
12
+ "url": "https://github.com/jogelin/dot-ai"
13
13
  },
14
14
  "license": "MIT",
15
15
  "hooks": "hooks/hooks.json"