@absolutejs/sync 1.7.8 → 1.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/README.md +24 -0
- package/dist/adapters/drizzle/index.js +15 -1
- package/dist/adapters/drizzle/index.js.map +2 -2
- package/dist/adapters/mysql/index.js +15 -1
- package/dist/adapters/mysql/index.js.map +2 -2
- package/dist/adapters/postgres/index.js +15 -1
- package/dist/adapters/postgres/index.js.map +2 -2
- package/dist/adapters/prisma/index.js +15 -1
- package/dist/adapters/prisma/index.js.map +2 -2
- package/dist/adapters/sqlite/index.js +15 -1
- package/dist/adapters/sqlite/index.js.map +2 -2
- package/dist/adapters/tanstack-db/index.d.ts +40 -0
- package/dist/adapters/tanstack-db/index.js +523 -0
- package/dist/adapters/tanstack-db/index.js.map +11 -0
- package/dist/engine/index.js +15 -1
- package/dist/engine/index.js.map +2 -2
- package/dist/index.js +15 -1
- package/dist/index.js.map +2 -2
- package/dist/mcp/index.d.ts +10 -0
- package/dist/mcp/index.js +14387 -0
- package/dist/mcp/index.js.map +84 -0
- package/dist/mcp/server.d.ts +107 -0
- package/dist/scheduled.js +15 -1
- package/dist/scheduled.js.map +2 -2
- package/package.json +22 -2
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@absolutejs/sync/mcp` — a Model Context Protocol server that surfaces
|
|
3
|
+
* a {@link SyncEngine}'s public read + mutate surface to MCP-aware
|
|
4
|
+
* clients (Claude Code, Cursor, custom agents).
|
|
5
|
+
*
|
|
6
|
+
* The agent gets four tools out of the box:
|
|
7
|
+
*
|
|
8
|
+
* - `list_collections` — registered collection names + kinds + tables.
|
|
9
|
+
* - `list_mutations` — registered mutation names.
|
|
10
|
+
* - `inspect_engine` — full {@link EngineInspection} snapshot
|
|
11
|
+
* (collections, mutations, schedules, readers, writers, recent
|
|
12
|
+
* changes).
|
|
13
|
+
* - `get_snapshot` — `{ collection, params?, ctx? }` → current rows.
|
|
14
|
+
* - `run_mutation` — `{ mutation, args, ctx? }` → result.
|
|
15
|
+
*
|
|
16
|
+
* Tools that take a `ctx` accept the agent's per-call override; if
|
|
17
|
+
* omitted, the server's `defaultCtx` is used. That's how multi-tenant
|
|
18
|
+
* gating works: the platform spawns one MCP server per tenant with
|
|
19
|
+
* `defaultCtx: { tenantId }`, and the agent can't reach across.
|
|
20
|
+
*
|
|
21
|
+
* ## Why
|
|
22
|
+
*
|
|
23
|
+
* Val.town's MCP server ([val.town/mcp](https://blog.val.town/mcp))
|
|
24
|
+
* exposes its entire UI through 36+ tools — that's the 2026 entry
|
|
25
|
+
* point for "let me run code on a platform." Cloudflare's MCP server
|
|
26
|
+
* does the same for the Cloudflare API, fitting "the entire surface
|
|
27
|
+
* through just two tools in under 1,000 tokens" via Code Mode
|
|
28
|
+
* ([blog.cloudflare.com/dynamic-workers](https://blog.cloudflare.com/dynamic-workers/)).
|
|
29
|
+
*
|
|
30
|
+
* Sync's MCP server is the same play for the sync engine itself: an
|
|
31
|
+
* agent can wire up a real-time leaderboard in three messages, then
|
|
32
|
+
* `run_mutation` to drive it without ever touching source files.
|
|
33
|
+
*
|
|
34
|
+
* ## Usage (stdio)
|
|
35
|
+
*
|
|
36
|
+
* ```ts
|
|
37
|
+
* // mcp-stdio-server.ts — point your MCP client (claude-code, etc.)
|
|
38
|
+
* // at this file's path.
|
|
39
|
+
* import { createSyncEngine, ... } from '@absolutejs/sync/engine';
|
|
40
|
+
* import { createSyncMcpServer, serveStdio } from '@absolutejs/sync/mcp';
|
|
41
|
+
*
|
|
42
|
+
* const engine = createSyncEngine();
|
|
43
|
+
* // ... register your collections / mutations ...
|
|
44
|
+
*
|
|
45
|
+
* const server = createSyncMcpServer({
|
|
46
|
+
* engine,
|
|
47
|
+
* defaultCtx: { tenantId: 'demo' },
|
|
48
|
+
* });
|
|
49
|
+
* await serveStdio(server);
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* Run it as the MCP server: in your client's MCP config, add an entry
|
|
53
|
+
* like:
|
|
54
|
+
*
|
|
55
|
+
* ```json
|
|
56
|
+
* {
|
|
57
|
+
* "mcpServers": {
|
|
58
|
+
* "my-sync": {
|
|
59
|
+
* "command": "bun",
|
|
60
|
+
* "args": ["./mcp-stdio-server.ts"]
|
|
61
|
+
* }
|
|
62
|
+
* }
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* ## Optional peer dep
|
|
67
|
+
*
|
|
68
|
+
* `@modelcontextprotocol/sdk` is an optional peer — install only if
|
|
69
|
+
* you use the MCP surface. The dynamic `import()` below makes this
|
|
70
|
+
* subpath load-free when not used.
|
|
71
|
+
*/
|
|
72
|
+
import type { SyncEngine } from '../engine/syncEngine';
|
|
73
|
+
/** Per-call context default + override behaviour. */
|
|
74
|
+
export type SyncMcpServerOptions = {
|
|
75
|
+
/** The engine to expose. */
|
|
76
|
+
engine: SyncEngine;
|
|
77
|
+
/**
|
|
78
|
+
* Default `ctx` for `get_snapshot` and `run_mutation`. Tools accept
|
|
79
|
+
* an optional `ctx` override on each call; if absent, this default
|
|
80
|
+
* is used. Set per-tenant when running one server per tenant.
|
|
81
|
+
*/
|
|
82
|
+
defaultCtx?: unknown;
|
|
83
|
+
/**
|
|
84
|
+
* Display name advertised to the MCP client. Defaults to
|
|
85
|
+
* `'sync-engine'`. Useful when one client connects to multiple
|
|
86
|
+
* sync MCP servers (e.g. `'sync-prod'` / `'sync-staging'`).
|
|
87
|
+
*/
|
|
88
|
+
name?: string;
|
|
89
|
+
/** Semver string surfaced to the MCP client. Defaults to `'0.1.0'`. */
|
|
90
|
+
version?: string;
|
|
91
|
+
};
|
|
92
|
+
/** A precompiled MCP server with the sync tools already registered. */
|
|
93
|
+
export type SyncMcpServer = {
|
|
94
|
+
/** The underlying SDK server — register additional tools on it if you want. */
|
|
95
|
+
server: import('@modelcontextprotocol/sdk/server/mcp.js').McpServer;
|
|
96
|
+
/** Wire to a transport (stdio, sse, custom). The SDK handles the rest. */
|
|
97
|
+
connect: (transport: import('@modelcontextprotocol/sdk/shared/transport.js').Transport) => Promise<void>;
|
|
98
|
+
};
|
|
99
|
+
export declare const createSyncMcpServer: (options: SyncMcpServerOptions) => Promise<SyncMcpServer>;
|
|
100
|
+
/**
|
|
101
|
+
* Convenience: wire a {@link SyncMcpServer} to stdio. This is the
|
|
102
|
+
* normal path for "I want claude-code to talk to my sync engine."
|
|
103
|
+
*
|
|
104
|
+
* Blocks until the transport closes. The server stays alive across
|
|
105
|
+
* many tool calls.
|
|
106
|
+
*/
|
|
107
|
+
export declare const serveStdio: (syncMcp: SyncMcpServer | Promise<SyncMcpServer>) => Promise<void>;
|
package/dist/scheduled.js
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
2
16
|
var __require = import.meta.require;
|
|
3
17
|
|
|
4
18
|
// src/scheduled.ts
|
|
@@ -31,5 +45,5 @@ export {
|
|
|
31
45
|
scheduled
|
|
32
46
|
};
|
|
33
47
|
|
|
34
|
-
//# debugId=
|
|
48
|
+
//# debugId=8CB5CC79F76D462364756E2164756E21
|
|
35
49
|
//# sourceMappingURL=scheduled.js.map
|
package/dist/scheduled.js.map
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import { Elysia } from 'elysia';\nimport { cron } from '@elysiajs/cron';\nimport type { SyncEngine } from './engine/syncEngine';\n\nexport type ScheduledOptions = {\n\t/** The engine whose registered schedules (see `registerSchedule`) to run. */\n\tengine: SyncEngine;\n\t/** Prefix for the cron job names registered on Elysia's store. Default `sync`. */\n\tprefix?: string;\n\t/** Called when a scheduled run throws (the batch is rolled back). */\n\tonError?: (name: string, error: unknown) => void;\n};\n\n/**\n * Elysia plugin that fires the engine's registered scheduled functions on their\n * cron patterns, via `@elysiajs/cron`. Cron decides *when*; the engine runs the\n * schedule and makes its writes go live through the change feed (and a schedule\n * can `enqueue` into `@absolutejs/queue` for durable, retryable work).\n *\n * Register schedules with `engine.registerSchedule(...)` before mounting this, so\n * each one becomes a cron job named `<prefix>:<schedule.name>`. Mount once.\n */\nexport const scheduled = ({\n\tengine,\n\tprefix = 'sync',\n\tonError\n}: ScheduledOptions) => {\n\tconst run = (name: string) => () => {\n\t\tvoid engine.runSchedule(name).catch((error) => {\n\t\t\tif (onError === undefined) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tonError(name, error);\n\t\t});\n\t};\n\n\t// `.use` registers the cron job on this instance (mutating), so a loop builds\n\t// one plugin carrying every schedule's cron trigger.\n\tconst app = new Elysia({ name: '@absolutejs/sync/scheduled' });\n\tfor (const schedule of engine.listSchedules()) {\n\t\tapp.use(\n\t\t\tcron({\n\t\t\t\tname: `${prefix}:${schedule.name}`,\n\t\t\t\tpattern: schedule.pattern,\n\t\t\t\trun: run(schedule.name)\n\t\t\t})\n\t\t);\n\t}\n\treturn app;\n};\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AACA;AAqBO,IAAM,YAAY;AAAA,EACxB;AAAA,EACA,SAAS;AAAA,EACT;AAAA,MACuB;AAAA,EACvB,MAAM,MAAM,CAAC,SAAiB,MAAM;AAAA,IAC9B,OAAO,YAAY,IAAI,EAAE,MAAM,CAAC,UAAU;AAAA,MAC9C,IAAI,YAAY,WAAW;AAAA,QAC1B,MAAM;AAAA,MACP;AAAA,MACA,QAAQ,MAAM,KAAK;AAAA,KACnB;AAAA;AAAA,EAKF,MAAM,MAAM,IAAI,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAAA,EAC7D,WAAW,YAAY,OAAO,cAAc,GAAG;AAAA,IAC9C,IAAI,IACH,KAAK;AAAA,MACJ,MAAM,GAAG,UAAU,SAAS;AAAA,MAC5B,SAAS,SAAS;AAAA,MAClB,KAAK,IAAI,SAAS,IAAI;AAAA,IACvB,CAAC,CACF;AAAA,EACD;AAAA,EACA,OAAO;AAAA;",
|
|
8
|
+
"debugId": "8CB5CC79F76D462364756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@absolutejs/sync",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Lightweight reactive-push and write-behind-cache primitives for Elysia and the AbsoluteJS ecosystem — kill polling and keep a remote store off your hot path, without adopting a whole sync-engine backend.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -23,6 +23,11 @@
|
|
|
23
23
|
"import": "./dist/scheduled.js",
|
|
24
24
|
"default": "./dist/scheduled.js"
|
|
25
25
|
},
|
|
26
|
+
"./mcp": {
|
|
27
|
+
"types": "./dist/mcp/index.d.ts",
|
|
28
|
+
"import": "./dist/mcp/index.js",
|
|
29
|
+
"default": "./dist/mcp/index.js"
|
|
30
|
+
},
|
|
26
31
|
"./client": {
|
|
27
32
|
"types": "./dist/client/index.d.ts",
|
|
28
33
|
"import": "./dist/client/index.js",
|
|
@@ -63,6 +68,11 @@
|
|
|
63
68
|
"import": "./dist/adapters/sqlite/index.js",
|
|
64
69
|
"default": "./dist/adapters/sqlite/index.js"
|
|
65
70
|
},
|
|
71
|
+
"./tanstack-db": {
|
|
72
|
+
"types": "./dist/adapters/tanstack-db/index.d.ts",
|
|
73
|
+
"import": "./dist/adapters/tanstack-db/index.js",
|
|
74
|
+
"default": "./dist/adapters/tanstack-db/index.js"
|
|
75
|
+
},
|
|
66
76
|
"./react": {
|
|
67
77
|
"types": "./dist/react/index.d.ts",
|
|
68
78
|
"import": "./dist/react/index.js",
|
|
@@ -121,18 +131,23 @@
|
|
|
121
131
|
],
|
|
122
132
|
"peerDependencies": {
|
|
123
133
|
"@absolutejs/isolated-jsc": ">= 0.6.0",
|
|
134
|
+
"@modelcontextprotocol/sdk": ">= 1.29.0",
|
|
124
135
|
"@angular/core": ">= 21.0.0",
|
|
125
136
|
"@elysiajs/cron": ">= 1.4.0",
|
|
126
137
|
"drizzle-orm": ">= 0.44.0",
|
|
127
138
|
"elysia": ">= 1.4.26",
|
|
128
139
|
"react": ">= 19.0.0",
|
|
129
140
|
"svelte": ">= 5.0.0",
|
|
130
|
-
"vue": ">= 3.5.0"
|
|
141
|
+
"vue": ">= 3.5.0",
|
|
142
|
+
"@tanstack/db": ">= 0.6.7 <0.7"
|
|
131
143
|
},
|
|
132
144
|
"peerDependenciesMeta": {
|
|
133
145
|
"@absolutejs/isolated-jsc": {
|
|
134
146
|
"optional": true
|
|
135
147
|
},
|
|
148
|
+
"@modelcontextprotocol/sdk": {
|
|
149
|
+
"optional": true
|
|
150
|
+
},
|
|
136
151
|
"@angular/core": {
|
|
137
152
|
"optional": true
|
|
138
153
|
},
|
|
@@ -153,6 +168,9 @@
|
|
|
153
168
|
},
|
|
154
169
|
"vue": {
|
|
155
170
|
"optional": true
|
|
171
|
+
},
|
|
172
|
+
"@tanstack/db": {
|
|
173
|
+
"optional": true
|
|
156
174
|
}
|
|
157
175
|
},
|
|
158
176
|
"devDependencies": {
|
|
@@ -161,6 +179,8 @@
|
|
|
161
179
|
"@angular/core": "^21.0.0",
|
|
162
180
|
"@elysiajs/cron": "^1.4.2",
|
|
163
181
|
"@elysiajs/eden": "^1.4.9",
|
|
182
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
183
|
+
"@tanstack/db": "0.6.7",
|
|
164
184
|
"@types/bun": "latest",
|
|
165
185
|
"@types/react": "^19.2.0",
|
|
166
186
|
"drizzle-orm": "^0.45.2",
|