@tigerdata/mcp-boilerplate 1.3.2 → 1.3.3
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/dist/cliEntrypoint.d.ts +2 -1
- package/dist/cliEntrypoint.js +15 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/migrate.d.ts +4 -0
- package/dist/migrate.js +86 -0
- package/dist/types.d.ts +5 -0
- package/package.json +13 -1
package/dist/cliEntrypoint.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import type { MigrationsConfig } from './types.js';
|
|
2
|
+
export declare function cliEntrypoint(stdioEntrypoint: string, httpEntrypoint: string, instrumentation?: string, dbConfig?: MigrationsConfig): Promise<void>;
|
package/dist/cliEntrypoint.js
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import { dirname, join } from 'node:path';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { log } from './logger.js';
|
|
3
4
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
4
|
-
export async function cliEntrypoint(stdioEntrypoint, httpEntrypoint, instrumentation = join(__dirname, './instrumentation.js')) {
|
|
5
|
+
export async function cliEntrypoint(stdioEntrypoint, httpEntrypoint, instrumentation = join(__dirname, './instrumentation.js'), dbConfig) {
|
|
5
6
|
// Parse command line arguments first
|
|
6
7
|
const args = process.argv.slice(2);
|
|
7
8
|
const scriptName = args[0] || 'stdio';
|
|
8
9
|
try {
|
|
10
|
+
if (dbConfig) {
|
|
11
|
+
const { createMigrator } = await import('./migrate.js');
|
|
12
|
+
log.info('starting server...');
|
|
13
|
+
try {
|
|
14
|
+
log.info('Running database migrations...');
|
|
15
|
+
await createMigrator(dbConfig).run();
|
|
16
|
+
log.info('Database migrations completed successfully');
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
log.error('Database migration failed:', error);
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
9
23
|
// Dynamically import only the requested module to prevent all modules from initializing
|
|
10
24
|
switch (scriptName) {
|
|
11
25
|
case 'stdio': {
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { cliEntrypoint } from './cliEntrypoint.js';
|
|
|
2
2
|
export { httpServerFactory } from './httpServer.js';
|
|
3
3
|
export { log } from './logger.js';
|
|
4
4
|
export type { AdditionalSetupArgs } from './mcpServer.js';
|
|
5
|
+
export { createMigrator } from './migrate.js';
|
|
5
6
|
export { registerExitHandlers } from './registerExitHandlers.js';
|
|
6
7
|
export { StatusError } from './StatusError.js';
|
|
7
8
|
export { stdioServerFactory } from './stdio.js';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { cliEntrypoint } from './cliEntrypoint.js';
|
|
2
2
|
export { httpServerFactory } from './httpServer.js';
|
|
3
3
|
export { log } from './logger.js';
|
|
4
|
+
export { createMigrator } from './migrate.js';
|
|
4
5
|
export { registerExitHandlers } from './registerExitHandlers.js';
|
|
5
6
|
export { StatusError } from './StatusError.js';
|
|
6
7
|
export { stdioServerFactory } from './stdio.js';
|
package/dist/migrate.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import migrate from 'migrate';
|
|
3
|
+
import { Client } from 'pg';
|
|
4
|
+
const createStateStore = (name, schema = 'public') => {
|
|
5
|
+
let client;
|
|
6
|
+
// Use a hash of the project name to create a lock
|
|
7
|
+
const hash = createHash('sha256').update(name).digest('hex');
|
|
8
|
+
const advisoryLockId = parseInt(hash.substring(0, 15), 16);
|
|
9
|
+
return {
|
|
10
|
+
async load(callback) {
|
|
11
|
+
try {
|
|
12
|
+
client = new Client();
|
|
13
|
+
await client.connect();
|
|
14
|
+
// Acquire advisory lock to prevent concurrent migrations
|
|
15
|
+
await client.query(/* sql */ `SELECT pg_advisory_lock($1)`, [
|
|
16
|
+
advisoryLockId,
|
|
17
|
+
]);
|
|
18
|
+
// Ensure migrations table exists
|
|
19
|
+
await client.query(/* sql */ `
|
|
20
|
+
CREATE SCHEMA IF NOT EXISTS ${schema};
|
|
21
|
+
|
|
22
|
+
CREATE TABLE IF NOT EXISTS ${schema}.migrations (
|
|
23
|
+
id SERIAL PRIMARY KEY,
|
|
24
|
+
set JSONB NOT NULL,
|
|
25
|
+
applied_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
26
|
+
);
|
|
27
|
+
`);
|
|
28
|
+
// Load the most recent migration set
|
|
29
|
+
const result = await client.query(
|
|
30
|
+
/* sql */ `SELECT set FROM ${schema}.migrations ORDER BY applied_at DESC LIMIT 1`);
|
|
31
|
+
const set = result.rows.length > 0 ? result.rows[0].set : {};
|
|
32
|
+
callback(null, set);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
callback(error);
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
async save(set, callback) {
|
|
39
|
+
try {
|
|
40
|
+
// Insert the entire set as JSONB
|
|
41
|
+
await client.query(
|
|
42
|
+
/* sql */ `INSERT INTO ${schema}.migrations (set) VALUES ($1)`, [JSON.stringify(set)]);
|
|
43
|
+
callback(null);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
callback(error);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
async close() {
|
|
50
|
+
if (client) {
|
|
51
|
+
// Release advisory lock
|
|
52
|
+
await client.query(/* sql */ `SELECT pg_advisory_unlock($1)`, [
|
|
53
|
+
advisoryLockId,
|
|
54
|
+
]);
|
|
55
|
+
await client.end();
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
export const createMigrator = (config) => {
|
|
61
|
+
const { schema, migrationsDirectory, serviceName } = config;
|
|
62
|
+
const stateStore = createStateStore(serviceName, schema);
|
|
63
|
+
return {
|
|
64
|
+
run: async () => new Promise((resolve, reject) => {
|
|
65
|
+
migrate.load({
|
|
66
|
+
stateStore,
|
|
67
|
+
migrationsDirectory: migrationsDirectory ?? './migrations',
|
|
68
|
+
}, (err, set) => {
|
|
69
|
+
if (err) {
|
|
70
|
+
stateStore.close().finally(() => reject(err));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
set.up((err) => {
|
|
74
|
+
stateStore.close().finally(() => {
|
|
75
|
+
if (err) {
|
|
76
|
+
reject(err);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
resolve();
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}),
|
|
85
|
+
};
|
|
86
|
+
};
|
package/dist/types.d.ts
CHANGED
|
@@ -107,4 +107,9 @@ export type InferSchema<T extends Record<string, z.ZodType>> = Flatten<{
|
|
|
107
107
|
} & {
|
|
108
108
|
[K in OptionalKeys<T>]?: z.infer<T[K]>;
|
|
109
109
|
}>;
|
|
110
|
+
export interface MigrationsConfig {
|
|
111
|
+
serviceName: string;
|
|
112
|
+
migrationsDirectory?: string;
|
|
113
|
+
schema?: string;
|
|
114
|
+
}
|
|
110
115
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tigerdata/mcp-boilerplate",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "MCP boilerplate code for Node.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "TigerData",
|
|
@@ -58,10 +58,22 @@
|
|
|
58
58
|
"yaml": "^2.8.2"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
+
"migrate": "^2.1.0",
|
|
62
|
+
"pg": "^8.16.3",
|
|
61
63
|
"zod": "^3.25 || ^4.0"
|
|
62
64
|
},
|
|
65
|
+
"peerDependenciesMeta": {
|
|
66
|
+
"migrate": {
|
|
67
|
+
"optional": true
|
|
68
|
+
},
|
|
69
|
+
"pg": {
|
|
70
|
+
"optional": true
|
|
71
|
+
}
|
|
72
|
+
},
|
|
63
73
|
"devDependencies": {
|
|
64
74
|
"@biomejs/biome": "^2.4.8",
|
|
75
|
+
"migrate": "^2.1.0",
|
|
76
|
+
"pg": "^8.16.3",
|
|
65
77
|
"zod": "^4.3.6",
|
|
66
78
|
"@octokit/rest": "^22.0.1",
|
|
67
79
|
"@types/bun": "^1.3.10",
|