@tigerdata/mcp-boilerplate 1.3.4 → 1.4.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/dist/index.d.ts CHANGED
@@ -7,4 +7,4 @@ export { registerExitHandlers } from './registerExitHandlers.js';
7
7
  export { StatusError } from './StatusError.js';
8
8
  export { stdioServerFactory } from './stdio.js';
9
9
  export { addAiResultToSpan, withSpan } from './tracing.js';
10
- export type { ApiFactory, InferSchema, McpFeatureFlags, ParsedQs, PromptFactory, ResourceFactory, } from './types.js';
10
+ export type { ApiFactory, InferSchema, McpFeatureFlags, MigrationsConfig, ParsedQs, PromptFactory, ResourceFactory, } from './types.js';
package/dist/migrate.js CHANGED
@@ -64,16 +64,35 @@ export const createMigrator = (config) => {
64
64
  return {
65
65
  run: async () => new Promise((resolve, reject) => {
66
66
  log.info('Running database migrations...');
67
+ // Set search_path via PGOPTIONS so every pg.Client created by migration
68
+ // files picks it up automatically, without touching the migration files.
69
+ const prevPgOptions = process.env.PGOPTIONS;
70
+ if (schema) {
71
+ process.env.PGOPTIONS =
72
+ `${prevPgOptions ?? ''} --search_path=${schema},public`.trim();
73
+ }
74
+ const restore = () => {
75
+ if (schema) {
76
+ if (prevPgOptions === undefined) {
77
+ delete process.env.PGOPTIONS;
78
+ }
79
+ else {
80
+ process.env.PGOPTIONS = prevPgOptions;
81
+ }
82
+ }
83
+ };
67
84
  migrate.load({
68
85
  stateStore,
69
86
  migrationsDirectory: migrationsDirectory ?? './migrations',
70
87
  }, (err, set) => {
71
88
  if (err) {
89
+ restore();
72
90
  log.error('Database migration failed:', err);
73
91
  stateStore.close().finally(() => reject(err));
74
92
  return;
75
93
  }
76
94
  set.up((err) => {
95
+ restore();
77
96
  stateStore.close().finally(() => {
78
97
  if (err) {
79
98
  log.error('Database migration failed:', err);
@@ -36,6 +36,7 @@ export declare const zGitHubSkillCfg: z.ZodObject<{
36
36
  type: z.ZodLiteral<"github">;
37
37
  repo: z.ZodString;
38
38
  path: z.ZodOptional<z.ZodString>;
39
+ ref: z.ZodOptional<z.ZodString>;
39
40
  }, z.core.$strip>;
40
41
  export type GitHubSkillCfg = z.infer<typeof zGitHubSkillCfg>;
41
42
  export declare const zGitHubCollectionSkillCfg: z.ZodObject<{
@@ -45,6 +46,7 @@ export declare const zGitHubCollectionSkillCfg: z.ZodObject<{
45
46
  type: z.ZodLiteral<"github_collection">;
46
47
  repo: z.ZodString;
47
48
  path: z.ZodOptional<z.ZodString>;
49
+ ref: z.ZodOptional<z.ZodString>;
48
50
  }, z.core.$strip>;
49
51
  export type GitHubCollectionSkillCfg = z.infer<typeof zGitHubCollectionSkillCfg>;
50
52
  export declare const zSkillCfg: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -60,6 +62,7 @@ export declare const zSkillCfg: z.ZodDiscriminatedUnion<[z.ZodObject<{
60
62
  type: z.ZodLiteral<"github">;
61
63
  repo: z.ZodString;
62
64
  path: z.ZodOptional<z.ZodString>;
65
+ ref: z.ZodOptional<z.ZodString>;
63
66
  }, z.core.$strip>, z.ZodObject<{
64
67
  enabled_skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
65
68
  disabled_skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -67,6 +70,7 @@ export declare const zSkillCfg: z.ZodDiscriminatedUnion<[z.ZodObject<{
67
70
  type: z.ZodLiteral<"github_collection">;
68
71
  repo: z.ZodString;
69
72
  path: z.ZodOptional<z.ZodString>;
73
+ ref: z.ZodOptional<z.ZodString>;
70
74
  }, z.core.$strip>], "type">;
71
75
  export type SkillCfg = z.infer<typeof zSkillCfg>;
72
76
  export declare const zSkillCfgMap: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -82,6 +86,7 @@ export declare const zSkillCfgMap: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUn
82
86
  type: z.ZodLiteral<"github">;
83
87
  repo: z.ZodString;
84
88
  path: z.ZodOptional<z.ZodString>;
89
+ ref: z.ZodOptional<z.ZodString>;
85
90
  }, z.core.$strip>, z.ZodObject<{
86
91
  enabled_skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
87
92
  disabled_skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -89,6 +94,7 @@ export declare const zSkillCfgMap: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUn
89
94
  type: z.ZodLiteral<"github_collection">;
90
95
  repo: z.ZodString;
91
96
  path: z.ZodOptional<z.ZodString>;
97
+ ref: z.ZodOptional<z.ZodString>;
92
98
  }, z.core.$strip>], "type">>;
93
99
  export type SkillCfgMap = z.infer<typeof zSkillCfgMap>;
94
100
  export declare const zSkillMatter: z.ZodObject<{
@@ -109,6 +115,7 @@ export declare const zGitHubSkill: z.ZodObject<{
109
115
  type: z.ZodLiteral<"github">;
110
116
  repo: z.ZodString;
111
117
  path: z.ZodOptional<z.ZodString>;
118
+ ref: z.ZodOptional<z.ZodString>;
112
119
  }, z.core.$strip>;
113
120
  export type GitHubSkill = z.infer<typeof zGitHubSkill>;
114
121
  export declare const zSkill: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -122,6 +129,7 @@ export declare const zSkill: z.ZodDiscriminatedUnion<[z.ZodObject<{
122
129
  type: z.ZodLiteral<"github">;
123
130
  repo: z.ZodString;
124
131
  path: z.ZodOptional<z.ZodString>;
132
+ ref: z.ZodOptional<z.ZodString>;
125
133
  }, z.core.$strip>], "type">;
126
134
  export type Skill = z.infer<typeof zSkill>;
127
135
  export declare const zSkillMap: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -135,6 +143,7 @@ export declare const zSkillMap: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion
135
143
  type: z.ZodLiteral<"github">;
136
144
  repo: z.ZodString;
137
145
  path: z.ZodOptional<z.ZodString>;
146
+ ref: z.ZodOptional<z.ZodString>;
138
147
  }, z.core.$strip>], "type">>;
139
148
  export type SkillMap = z.infer<typeof zSkillMap>;
140
149
  export interface SkillsFlags {
@@ -22,11 +22,13 @@ export const zGitHubSkillCfg = z.object({
22
22
  type: z.literal('github'),
23
23
  repo: z.string(),
24
24
  path: z.string().optional(),
25
+ ref: z.string().optional(),
25
26
  });
26
27
  export const zGitHubCollectionSkillCfg = zCollectionFlagsCfg.extend({
27
28
  type: z.literal('github_collection'),
28
29
  repo: z.string(),
29
30
  path: z.string().optional(),
31
+ ref: z.string().optional(),
30
32
  });
31
33
  export const zSkillCfg = z.discriminatedUnion('type', [
32
34
  zLocalSkillCfg,
@@ -107,7 +107,7 @@ const doLoadSkills = async (octokit) => {
107
107
  log.error(`Failed to load skill at path: ${skillPath}`, err);
108
108
  }
109
109
  };
110
- const loadGitHubPath = async (owner, repo, path, flags) => {
110
+ const loadGitHubPath = async (owner, repo, path, ref, flags) => {
111
111
  if (shouldIgnorePath(path, flags))
112
112
  return;
113
113
  const skillPath = `${path}/SKILL.md`;
@@ -120,6 +120,7 @@ const doLoadSkills = async (octokit) => {
120
120
  owner,
121
121
  repo,
122
122
  path: skillPath,
123
+ ...(ref ? { ref } : {}),
123
124
  });
124
125
  if (Array.isArray(skillFileResponse.data) ||
125
126
  skillFileResponse.data.type !== 'file') {
@@ -127,6 +128,7 @@ const doLoadSkills = async (octokit) => {
127
128
  owner,
128
129
  repo,
129
130
  path: skillPath,
131
+ ref,
130
132
  });
131
133
  return;
132
134
  }
@@ -140,13 +142,14 @@ const doLoadSkills = async (octokit) => {
140
142
  type: 'github',
141
143
  repo: `${owner}/${repo}`,
142
144
  path,
145
+ ...(ref ? { ref } : {}),
143
146
  name,
144
147
  description,
145
148
  });
146
149
  skillContentCache.set(`${name}/SKILL.md`, content);
147
150
  }
148
151
  catch (err) {
149
- log.error(`Failed to load skill at GitHub path: ${owner}/${repo}/${skillPath}\n${err.message}`);
152
+ log.error(`Failed to load skill at GitHub path: ${owner}/${repo}/${skillPath}${ref ? `@${ref}` : ''}\n${err.message}`);
150
153
  }
151
154
  };
152
155
  const promises = [];
@@ -181,7 +184,7 @@ const doLoadSkills = async (octokit) => {
181
184
  log.error(`Invalid GitHub repo format in skill config: ${cfg.repo}`, null, { name, repo: cfg.repo });
182
185
  break;
183
186
  }
184
- promises.push(loadGitHubPath(owner, repo, cfg.path || '.'));
187
+ promises.push(loadGitHubPath(owner, repo, cfg.path || '.', cfg.ref));
185
188
  break;
186
189
  }
187
190
  case 'github_collection': {
@@ -201,9 +204,10 @@ const doLoadSkills = async (octokit) => {
201
204
  owner,
202
205
  repo,
203
206
  path: rootPath,
207
+ ...(cfg.ref ? { ref: cfg.ref } : {}),
204
208
  });
205
209
  if (!Array.isArray(dirResponse.data)) {
206
- log.error(`Expected github_collection repo path to be a directory`, null, { name, owner, repo, path: cfg.path || '.' });
210
+ log.error(`Expected github_collection repo path to be a directory`, null, { name, owner, repo, path: cfg.path || '.', ref: cfg.ref });
207
211
  break;
208
212
  }
209
213
  const flags = parseCollectionFlags(cfg);
@@ -217,7 +221,7 @@ const doLoadSkills = async (octokit) => {
217
221
  });
218
222
  continue;
219
223
  }
220
- promises.push(loadGitHubPath(owner, repo, entry.path, flags));
224
+ promises.push(loadGitHubPath(owner, repo, entry.path, cfg.ref, flags));
221
225
  }
222
226
  break;
223
227
  }
@@ -385,6 +389,7 @@ const getSkillContent = async ({ skill, path: targetPath, octokit, }) => {
385
389
  owner,
386
390
  repo,
387
391
  path,
392
+ ...(skill.ref ? { ref: skill.ref } : {}),
388
393
  });
389
394
  if (Array.isArray(response.data)) {
390
395
  // Directory listing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tigerdata/mcp-boilerplate",
3
- "version": "1.3.4",
3
+ "version": "1.4.0",
4
4
  "description": "MCP boilerplate code for Node.js",
5
5
  "license": "Apache-2.0",
6
6
  "author": "TigerData",