@oimdb/mcp 2.0.0 → 3.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.
- package/README.md +17 -221
- package/bin/oimdb-mcp.cjs +2 -14
- package/dist/index.cjs +32 -447
- package/dist/index.d.cts +5 -71
- package/dist/index.d.ts +5 -71
- package/dist/index.js +37 -444
- package/package.json +9 -12
- package/bin/cdp.cjs +0 -98
- package/bin/devtools.cjs +0 -26
- package/ui/app.css +0 -323
- package/ui/app.js +0 -409
- package/ui/index.html +0 -63
package/README.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# @oimdb/mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The MCP server for OIMDB. It gives an AI assistant the tools `oimdb_inspect`, `oimdb_dump`,
|
|
4
|
+
`oimdb_collection` and `oimdb_computed` over a live browser tab or an in-process model. It is built on
|
|
5
|
+
`@oimdb/cli`, which answers the same four questions from a shell: an assistant that can run a command
|
|
6
|
+
can use `npx @oimdb/cli inspect` instead.
|
|
4
7
|
|
|
5
8
|
📖 **[Full documentation](https://oimdb.org/)**
|
|
6
9
|
|
|
7
10
|
## For AI Assistants
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
**Check whether MCP is already configured.** Look for `mcpServers.oimdb` in `.claude/settings.json` or
|
|
13
|
+
`~/.claude/settings.json`. If it is there, call `oimdb_inspect` now to see the current state.
|
|
10
14
|
|
|
11
|
-
**
|
|
12
|
-
|
|
13
|
-
**If MCP is not configured yet**, add this to the project's MCP config:
|
|
14
|
-
|
|
15
|
-
- Claude Code: `.claude/settings.json`
|
|
16
|
-
- Cursor: `.cursor/mcp.json`
|
|
15
|
+
**If MCP is not configured yet**, add this to the project's MCP config (Claude Code: `.claude/settings.json`,
|
|
16
|
+
Cursor: `.cursor/mcp.json`):
|
|
17
17
|
|
|
18
18
|
```json
|
|
19
19
|
{
|
|
@@ -26,64 +26,8 @@ If you are an AI assistant and this package is present in the project, you can g
|
|
|
26
26
|
}
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
Then ask the user to
|
|
30
|
-
|
|
31
|
-
2. Make sure `debug.ts` calls `oimDevRegistry.connect()` and the app is running in the browser
|
|
32
|
-
|
|
33
|
-
**If the user just wants a one-shot snapshot** without MCP setup, run this via Bash (requires Chrome launched with `--remote-debugging-port=9222`):
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
npx @oimdb/mcp cdp
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Human Setup
|
|
40
|
-
|
|
41
|
-
### Standalone DevTools UI (for humans)
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
npx @oimdb/mcp devtools
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Opens `http://localhost:7433` automatically and shows live collections and computeds from the running browser tab. No Chrome extension is needed.
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
OIMDB_WS_PORT=7433 OIMDB_UI_PORT=7434 npx @oimdb/mcp devtools # custom ports
|
|
51
|
-
npx @oimdb/mcp devtools --no-open # don't open browser
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### 1. Add MCP config (for AI tools)
|
|
55
|
-
|
|
56
|
-
Claude Code — `.claude/settings.json`:
|
|
57
|
-
|
|
58
|
-
```json
|
|
59
|
-
{
|
|
60
|
-
"mcpServers": {
|
|
61
|
-
"oimdb": {
|
|
62
|
-
"command": "npx",
|
|
63
|
-
"args": ["-y", "@oimdb/mcp"]
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Cursor — `.cursor/mcp.json`:
|
|
70
|
-
|
|
71
|
-
```json
|
|
72
|
-
{
|
|
73
|
-
"mcpServers": {
|
|
74
|
-
"oimdb": {
|
|
75
|
-
"command": "npx",
|
|
76
|
-
"args": ["-y", "@oimdb/mcp"]
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### 2. Connect the browser
|
|
83
|
-
|
|
84
|
-
The app calls `oimInitDevtools()` once at startup, before it builds its first
|
|
85
|
-
service, where it builds the database (see the `@oimdb/devtools` README, Setup).
|
|
86
|
-
The debug entry point then only connects:
|
|
29
|
+
Then ask the user to reload the assistant so the server starts, and to make sure the page connects to the
|
|
30
|
+
bridge:
|
|
87
31
|
|
|
88
32
|
```ts
|
|
89
33
|
// src/debug.ts
|
|
@@ -97,72 +41,23 @@ if (typeof window !== 'undefined') {
|
|
|
97
41
|
}
|
|
98
42
|
```
|
|
99
43
|
|
|
100
|
-
### 3. Use from Claude
|
|
101
|
-
|
|
102
|
-
```
|
|
103
|
-
Call oimdb_inspect to see what's in the store.
|
|
104
|
-
```
|
|
105
|
-
|
|
106
44
|
## Available MCP Tools
|
|
107
45
|
|
|
108
46
|
| Tool | Description |
|
|
109
47
|
|---|---|
|
|
110
48
|
| `oimdb_inspect` | Full structured state — collections with their index keys and relations, computeds, flush history, errors |
|
|
111
|
-
| `oimdb_dump` | Human-readable text summary — what `oimDevRegistry.dumpString()` returns
|
|
49
|
+
| `oimdb_dump` | Human-readable text summary — what `oimDevRegistry.dumpString()` returns |
|
|
112
50
|
| `oimdb_collection` | Details of one collection by name |
|
|
113
51
|
| `oimdb_computed` | Current value of one registered computed, by name |
|
|
114
52
|
|
|
115
53
|
## Offline / static mode (no browser)
|
|
116
54
|
|
|
117
|
-
By default the tools read a **live browser tab**. You can instead point the
|
|
118
|
-
server at an **in-process model** so it answers offline. This suits "what's the
|
|
119
|
-
data model?" questions when you don't want to run the app.
|
|
120
|
-
|
|
121
|
-
**CLI: a model module.** Set `OIMDB_MODEL_MODULE` to a module that builds the
|
|
122
|
-
model in Node and exports an `oimDevRegistry` (or a default export, or a zero-arg
|
|
123
|
-
factory that returns one). It calls `oimInitDevtools()` before it builds the first
|
|
124
|
-
service, as every app using `@oimdb/devtools` does:
|
|
125
|
-
|
|
126
|
-
```ts
|
|
127
|
-
// oimdb-model.js (built JS, or run the server under a TS loader)
|
|
128
|
-
import {
|
|
129
|
-
OIMDB, createOIMBucketService, createOIMEntityService, type TOIMEntitySlot,
|
|
130
|
-
} from '@oimdb/core';
|
|
131
|
-
import { OIMDevRegistry, oimInitDevtools } from '@oimdb/devtools';
|
|
132
|
-
|
|
133
|
-
oimInitDevtools();
|
|
134
|
-
|
|
135
|
-
type TUser = { id: string; name: string; role: string };
|
|
136
|
-
|
|
137
|
-
const db = new OIMDB();
|
|
138
|
-
const usersService = createOIMEntityService<TUser>(db, { keyOf: (user) => user.id });
|
|
139
|
-
const users = usersService.createStoreSlot(db);
|
|
140
|
-
// A bucket's slots are the caller's — a write to a user moves the value and
|
|
141
|
-
// files nothing, so whoever writes the user also calls
|
|
142
|
-
// `usersByRoleService.slotContentService.writeBucketMemberSlots(bucketSlot, entitySlots)`.
|
|
143
|
-
const usersByRoleService = createOIMBucketService<TOIMEntitySlot<TUser>>(db);
|
|
144
|
-
const usersByRole = usersByRoleService.createStoreSlot(db);
|
|
145
|
-
|
|
146
|
-
export const oimDevRegistry = new OIMDevRegistry();
|
|
147
|
-
// The bucket collection and its store slot — you constructed them, so you hand them over.
|
|
148
|
-
oimDevRegistry.collection('users', usersService, users, {
|
|
149
|
-
indexes: { byRole: { bucketCollectionService: usersByRoleService, bucketStoreSlot: usersByRole } },
|
|
150
|
-
});
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
The server asks a registry for only two methods, `inspect()` and `dumpString()`,
|
|
154
|
-
declared here as `IOIMDevRegistry`, so this package depends on no `@oimdb`
|
|
155
|
-
package at all. `OIMDevRegistry` from `@oimdb/devtools` satisfies it as it
|
|
156
|
-
stands, and so does anything else that answers those two.
|
|
157
|
-
|
|
158
55
|
```bash
|
|
159
56
|
OIMDB_MODEL_MODULE=./oimdb-model.js npx @oimdb/mcp
|
|
160
57
|
```
|
|
161
58
|
|
|
162
|
-
No WebSocket port is opened in this
|
|
163
|
-
|
|
164
|
-
**Embedded: inject a registry.** When you run the server from your own Node
|
|
165
|
-
process, pass the registry directly:
|
|
59
|
+
The module is the one `@oimdb/cli` reads with `--model`; see its README. No WebSocket port is opened in this
|
|
60
|
+
mode. From your own Node process, pass the registry directly:
|
|
166
61
|
|
|
167
62
|
```ts
|
|
168
63
|
import { createOIMDevMcpServer } from '@oimdb/mcp';
|
|
@@ -171,106 +66,7 @@ import { oimDevRegistry } from '@oimdb/devtools';
|
|
|
171
66
|
await createOIMDevMcpServer({ registry: oimDevRegistry }).start();
|
|
172
67
|
```
|
|
173
68
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
## CDP Inspector (no browser-side code needed)
|
|
180
|
-
|
|
181
|
-
Launch Chrome with `--remote-debugging-port=9222`, then:
|
|
182
|
-
|
|
183
|
-
```bash
|
|
184
|
-
npx @oimdb/mcp cdp
|
|
185
|
-
npx @oimdb/mcp cdp | jq .collections
|
|
186
|
-
OIMDB_CDP_URL=http://localhost:9222 npx @oimdb/mcp cdp
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
## Ports, host and origins
|
|
190
|
-
|
|
191
|
-
Everything here is configured through **environment variables**. The only CLI
|
|
192
|
-
flag in the package is `devtools --no-open`.
|
|
193
|
-
|
|
194
|
-
| Variable | Default | What it sets |
|
|
195
|
-
|---|---|---|
|
|
196
|
-
| `OIMDB_WS_PORT` | `7432` | The bridge WebSocket port |
|
|
197
|
-
| `OIMDB_UI_PORT` | `7433` | The `devtools` UI HTTP port |
|
|
198
|
-
| `OIMDB_HOST` | `127.0.0.1` | The interface both servers bind to |
|
|
199
|
-
| `OIMDB_ALLOWED_ORIGINS` | *(empty)* | Extra page origins allowed onto the bridge, comma-separated |
|
|
200
|
-
| `OIMDB_MODEL_MODULE` | — | Offline model module (see above) |
|
|
201
|
-
| `OIMDB_CDP_URL` | `http://localhost:9222` | The CDP endpoint the `cdp` subcommand reads |
|
|
202
|
-
|
|
203
|
-
The same two settings are `host` and `allowedOrigins` on `TOIMDevMcpOptions` and
|
|
204
|
-
`TOIMDevUIServerOptions` when you construct a server yourself.
|
|
205
|
-
|
|
206
|
-
**It binds to loopback by default, on purpose.** This port hands out the
|
|
207
|
-
application's entire data model, and a `WebSocketServer` built with no host
|
|
208
|
-
binds every interface, which would put the model on the café Wi-Fi.
|
|
209
|
-
Set `OIMDB_HOST=0.0.0.0` when the browser really runs
|
|
210
|
-
somewhere else (a container, a VM, a phone), and accept that everyone who can
|
|
211
|
-
route there can talk to it. Both servers print the bound host at startup.
|
|
212
|
-
|
|
213
|
-
**Origins are checked, and `'*'` is never allowed.** A request with no `Origin` header is
|
|
214
|
-
allowed (that is a non-browser client). A loopback origin is allowed
|
|
215
|
-
(`localhost`, `127.0.0.1`, `::1`, `[::1]`, `*.localhost`). Anything else is
|
|
216
|
-
allowed only if you listed it exactly in `OIMDB_ALLOWED_ORIGINS`. The literal
|
|
217
|
-
string `null` is always rejected, because a sandboxed iframe on any site in the world
|
|
218
|
-
sends exactly that. Only an allow-listed origin gets
|
|
219
|
-
`Access-Control-Allow-Origin` echoed back.
|
|
220
|
-
|
|
221
|
-
While bound to a loopback host, the UI server also rejects a request whose
|
|
222
|
-
`Host` header is not a loopback authority, with **421 Misdirected request**.
|
|
223
|
-
This is the DNS-rebinding guard, and it is switched off when you bind elsewhere.
|
|
224
|
-
|
|
225
|
-
Change the bridge port and update `oimDevRegistry.connect()` accordingly:
|
|
226
|
-
|
|
227
|
-
```bash
|
|
228
|
-
OIMDB_WS_PORT=7433 npx @oimdb/mcp
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
```ts
|
|
232
|
-
import { oimDevRegistry } from '@oimdb/devtools';
|
|
233
|
-
|
|
234
|
-
oimDevRegistry.connect('ws://localhost:7433');
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
## Running a server from your own process
|
|
238
|
-
|
|
239
|
-
```ts
|
|
240
|
-
import { createOIMDevMcpServer, createOIMDevUIServer } from '@oimdb/mcp';
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
- **`createOIMDevMcpServer(options?)`** → `OIMDevMcpServer`. Options: `wsPort?`
|
|
244
|
-
(7432), `registry?`, `modelModulePath?`, `host?` (`127.0.0.1`),
|
|
245
|
-
`allowedOrigins?` (`[]`).
|
|
246
|
-
- **`createOIMDevUIServer(options)`** → `OIMDevUIServer`. Options: `wsPort?`
|
|
247
|
-
(7432), `uiPort?` (7433), **`uiDir` — required, no default**, `open?` (true),
|
|
248
|
-
`host?` (`127.0.0.1`), `allowedOrigins?` (`[]`).
|
|
249
|
-
|
|
250
|
-
Both classes are exported too, along with `TOIMDevMcpOptions`,
|
|
251
|
-
`TOIMDevUIServerOptions` and `IOIMDevRegistry`.
|
|
252
|
-
|
|
253
|
-
Know these three behaviours before you wire this into anything:
|
|
254
|
-
|
|
255
|
-
- **The newest browser tab takes the bridge**, and the previous socket is closed
|
|
256
|
-
with "Replaced by a newer OIMDB DevTools tab". Only the socket that currently
|
|
257
|
-
holds the bridge may answer a request; anything else is ignored.
|
|
258
|
-
- **A query times out after 5 seconds**, reported as "Browser response timeout
|
|
259
|
-
(5s). Is the page active?".
|
|
260
|
-
- **A malformed frame drops that client** with close code 1007, and `EADDRINUSE`
|
|
261
|
-
exits the process with a message naming the env var to change.
|
|
262
|
-
|
|
263
|
-
The `devtools` UI serves `/`, `/index.html`, `/app.js`, `/app.css`, plus
|
|
264
|
-
`/api/inspect`, which answers `{ connected, tab, data }`:
|
|
265
|
-
|
|
266
|
-
```bash
|
|
267
|
-
curl http://127.0.0.1:7433/api/inspect
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
## Subcommands
|
|
271
|
-
|
|
272
|
-
```bash
|
|
273
|
-
npx @oimdb/mcp # the MCP server; `mcp` and `serve` are accepted aliases
|
|
274
|
-
npx @oimdb/mcp devtools # the standalone UI
|
|
275
|
-
npx @oimdb/mcp cdp # one-shot snapshot over the Chrome DevTools Protocol
|
|
276
|
-
```
|
|
69
|
+
`createOIMDevMcpServer(options?)` takes `wsPort?` (7432), `registry?`, `modelModulePath?`, `host?`
|
|
70
|
+
(`127.0.0.1`) and `allowedOrigins?` (`[]`). The bridge, ports, host and origin rules are `@oimdb/cli`'s and are
|
|
71
|
+
described in its README; `OIMDB_WS_PORT`, `OIMDB_HOST`, `OIMDB_ALLOWED_ORIGINS` and `OIMDB_MODEL_MODULE` set them
|
|
72
|
+
here too.
|
package/bin/oimdb-mcp.cjs
CHANGED
|
@@ -10,26 +10,14 @@ process.on('uncaughtException', err => {
|
|
|
10
10
|
process.on('unhandledRejection', reason => {
|
|
11
11
|
process.stderr.write(`[OIMDB] Unhandled rejection (continuing): ${String(reason)}\n`);
|
|
12
12
|
});
|
|
13
|
-
/**
|
|
14
|
-
* Single entry point for @oimdb/mcp. Dispatches on the first argument so all of
|
|
15
|
-
* these work via npx (one bin → npx can always resolve it):
|
|
16
|
-
*
|
|
17
|
-
* npx @oimdb/mcp # MCP server (default; for AI tools)
|
|
18
|
-
* npx @oimdb/mcp devtools # standalone DevTools UI (for humans)
|
|
19
|
-
* npx @oimdb/mcp cdp # one-shot CDP snapshot to stdout
|
|
20
|
-
*/
|
|
21
13
|
const sub = process.argv[2];
|
|
22
14
|
|
|
23
|
-
if (sub === '
|
|
24
|
-
require('./devtools.cjs')();
|
|
25
|
-
} else if (sub === 'cdp') {
|
|
26
|
-
require('./cdp.cjs')();
|
|
27
|
-
} else if (sub === undefined || sub === 'mcp' || sub === 'serve') {
|
|
15
|
+
if (sub === undefined || sub === 'mcp' || sub === 'serve') {
|
|
28
16
|
require('./server.cjs')();
|
|
29
17
|
} else {
|
|
30
18
|
process.stderr.write(
|
|
31
19
|
`[OIMDB] Unknown command: ${sub}\n` +
|
|
32
|
-
'Usage: oimdb-mcp
|
|
20
|
+
'Usage: oimdb-mcp (the MCP server). The DevTools UI and the CDP snapshot are in @oimdb/cli: oimdb serve, oimdb inspect --cdp.\n'
|
|
33
21
|
);
|
|
34
22
|
process.exit(1);
|
|
35
23
|
}
|