icode-mcp-adapter 1.0.7 → 1.0.9
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "icode-mcp-adapter",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Dynamic MCP server adapter — auto-generates CRUD tools from schema configs. Plugs into icode-server via Fastify or runs standalone.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/engine/McpEngine.js",
|
package/src/engine/McpEngine.js
CHANGED
|
@@ -10,14 +10,14 @@ import { resolveSchemas as defaultResolveSchemas } from './SchemaAdapter.js';
|
|
|
10
10
|
* @param {{ userId: string }} [identity] - Caller identity; required when a table is owner-scoped
|
|
11
11
|
* @returns {McpServer}
|
|
12
12
|
*/
|
|
13
|
-
export function createMcpServer(config, db, identity) {
|
|
13
|
+
export function createMcpServer(config, db, identity, newGuid) {
|
|
14
14
|
const server = new McpServer({
|
|
15
15
|
name: `${config.appName}-mcp`,
|
|
16
16
|
version: config.version,
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
for (const table of config.tables) {
|
|
20
|
-
registerTableTools(server, db, table, identity);
|
|
20
|
+
registerTableTools(server, db, table, identity, newGuid);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
return server;
|
|
@@ -47,5 +47,5 @@ export async function createMcpServerAuto(config, db, opts = {}) {
|
|
|
47
47
|
appName: config.appName,
|
|
48
48
|
version: config.version || '1.0.0',
|
|
49
49
|
tables,
|
|
50
|
-
}, db, opts.identity);
|
|
50
|
+
}, db, opts.identity, opts.newGuid);
|
|
51
51
|
}
|
|
@@ -75,7 +75,7 @@ function pkSchema(table) {
|
|
|
75
75
|
* @param {import('./types.js').TableSchema} table
|
|
76
76
|
* @param {{ userId: string }} [identity] - Caller identity; required for owner-scoped tables.
|
|
77
77
|
*/
|
|
78
|
-
export function registerTableTools(server, db, table, identity) {
|
|
78
|
+
export function registerTableTools(server, db, table, identity, newGuid) {
|
|
79
79
|
const display = table.displayName || table.singular;
|
|
80
80
|
|
|
81
81
|
// Row-level ownership: scope every query to the calling user. Fail closed —
|
|
@@ -92,7 +92,7 @@ export function registerTableTools(server, db, table, identity) {
|
|
|
92
92
|
switch (op) {
|
|
93
93
|
case 'list': regList(server, db, table, display, owner); break;
|
|
94
94
|
case 'get': regGet(server, db, table, display, owner); break;
|
|
95
|
-
case 'add': regAdd(server, db, table, display, owner); break;
|
|
95
|
+
case 'add': regAdd(server, db, table, display, owner, newGuid); break;
|
|
96
96
|
case 'update': regUpdate(server, db, table, display, owner); break;
|
|
97
97
|
case 'delete': regDelete(server, db, table, display, owner); break;
|
|
98
98
|
}
|
|
@@ -174,7 +174,7 @@ function regGet(server, db, table, display, owner) {
|
|
|
174
174
|
|
|
175
175
|
// ── ADD ───────────────────────────────────────────────────────────────────────
|
|
176
176
|
|
|
177
|
-
function regAdd(server, db, table, display, owner) {
|
|
177
|
+
function regAdd(server, db, table, display, owner, newGuid) {
|
|
178
178
|
const cols = writableCols(table);
|
|
179
179
|
const inputSchema = {};
|
|
180
180
|
for (const c of cols) {
|
|
@@ -192,19 +192,21 @@ function regAdd(server, db, table, display, owner) {
|
|
|
192
192
|
const insertVals = [];
|
|
193
193
|
const placeholders = [];
|
|
194
194
|
|
|
195
|
-
// Auto-set
|
|
195
|
+
// Auto-set _created — epoch ms for a bigint column, a Date for a datetime column
|
|
196
|
+
// (mysql2 serializes a Date to the column's expected 'YYYY-MM-DD HH:MM:SS').
|
|
196
197
|
for (const c of table.columns) {
|
|
197
198
|
if (c.autoSet === 'created_at') {
|
|
198
199
|
insertCols.push(q(c.name));
|
|
199
|
-
insertVals.push(Date.now());
|
|
200
|
+
insertVals.push(c.type === 'timestamp' ? Date.now() : new Date());
|
|
200
201
|
placeholders.push('?');
|
|
201
202
|
}
|
|
202
203
|
}
|
|
203
204
|
|
|
204
|
-
// String PK (guid) —
|
|
205
|
+
// String PK (guid) — use the injected generator (e.g. icode's <entity>-<guid8>),
|
|
206
|
+
// falling back to a UUID when none is provided.
|
|
205
207
|
let generatedGuid;
|
|
206
208
|
if (table.pkType === 'string') {
|
|
207
|
-
generatedGuid = randomUUID();
|
|
209
|
+
generatedGuid = newGuid ? newGuid(table.name) : randomUUID();
|
|
208
210
|
insertCols.push(q(table.primaryKey));
|
|
209
211
|
insertVals.push(generatedGuid);
|
|
210
212
|
placeholders.push('?');
|
|
@@ -83,6 +83,7 @@ function unauthorized(req, reply) {
|
|
|
83
83
|
export default async function mcpPlugin(fastify, opts = {}) {
|
|
84
84
|
const getDb = opts.getDb;
|
|
85
85
|
const getUser = opts.getUser;
|
|
86
|
+
const newGuid = opts.newGuid;
|
|
86
87
|
const resolveSchemas = opts.resolveSchemas;
|
|
87
88
|
const prefix = opts.prefix || '/v1/mcp';
|
|
88
89
|
const isPublic = opts.public ?? true;
|
|
@@ -149,7 +150,7 @@ export default async function mcpPlugin(fastify, opts = {}) {
|
|
|
149
150
|
|
|
150
151
|
let server;
|
|
151
152
|
try {
|
|
152
|
-
server = await createMcpServerAuto(appConfig, db, { resolveSchemas, identity });
|
|
153
|
+
server = await createMcpServerAuto(appConfig, db, { resolveSchemas, identity, newGuid });
|
|
153
154
|
} catch (err) {
|
|
154
155
|
return reply.code(500).send({ ok: false, error: err.message || 'Failed to initialize MCP server' });
|
|
155
156
|
}
|