@mcpolyglot/config 0.0.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA+CxB,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQnB,CAAC;AAEH,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQrB,CAAC;AAEH,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBvB,CAAC;AAEH,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAkBnB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBvB,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAC5D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAClE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACtE,MAAM,MAAM,YAAY,GAAG,eAAe,GAAG,iBAAiB,GAAG,mBAAmB,CAAC;AACrF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,gBAAgB,GAAG,CAAC,MAAM,gBAAgB,CAAC,GAAG,gBAAgB,CAE/F;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA0CxE"}
package/dist/schema.js ADDED
@@ -0,0 +1,198 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { extname, isAbsolute, resolve } from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ import { parse as parseYaml } from 'yaml';
5
+ import { z } from 'zod';
6
+ import { ConfigError } from '@mcpolyglot/core';
7
+ const ScopeSchema = z.enum([
8
+ 'schema:read',
9
+ 'tables:read',
10
+ 'tables:write',
11
+ 'query:raw',
12
+ 'http:call',
13
+ ]);
14
+ const PerEntitySchema = z
15
+ .object({
16
+ enabled: z.boolean().default(false),
17
+ include: z.array(z.string()).optional(),
18
+ exclude: z.array(z.string()).optional(),
19
+ })
20
+ .default({ enabled: false });
21
+ const RedactSchema = z
22
+ .object({
23
+ columns: z.array(z.string()).default([]),
24
+ patterns: z
25
+ .array(z.object({
26
+ name: z.string(),
27
+ regex: z.string(),
28
+ replacement: z.string().optional(),
29
+ }))
30
+ .default([]),
31
+ })
32
+ .default({ columns: [], patterns: [] });
33
+ const LimitsSchema = z
34
+ .object({
35
+ rowCap: z.number().int().positive().max(10_000).default(200),
36
+ timeoutMs: z.number().int().positive().max(60_000).default(10_000),
37
+ maxBytes: z
38
+ .number()
39
+ .int()
40
+ .positive()
41
+ .max(8 * 1024 * 1024)
42
+ .default(256 * 1024),
43
+ })
44
+ .default({ rowCap: 200, timeoutMs: 10_000, maxBytes: 256 * 1024 });
45
+ const SqlSourceSchema = z.object({
46
+ id: z.string().regex(/^[a-z0-9._-]+$/i),
47
+ kind: z.enum(['postgres', 'mysql', 'mariadb', 'sqlite']),
48
+ url: z.string().min(1),
49
+ scopes: z.array(ScopeSchema).default(['schema:read', 'tables:read']),
50
+ perEntityTools: PerEntitySchema,
51
+ limits: LimitsSchema,
52
+ redact: RedactSchema,
53
+ });
54
+ const MongoSourceSchema = z.object({
55
+ id: z.string().regex(/^[a-z0-9._-]+$/i),
56
+ kind: z.literal('mongo'),
57
+ url: z.string().min(1),
58
+ database: z.string().optional(),
59
+ scopes: z.array(ScopeSchema).default(['schema:read', 'tables:read']),
60
+ limits: LimitsSchema,
61
+ redact: RedactSchema,
62
+ });
63
+ const OpenApiSourceSchema = z.object({
64
+ id: z.string().regex(/^[a-z0-9._-]+$/i),
65
+ kind: z.literal('openapi'),
66
+ spec: z.string(),
67
+ baseUrl: z.string().url(),
68
+ auth: z
69
+ .union([
70
+ z.object({ type: z.literal('none') }),
71
+ z.object({ type: z.literal('bearer'), token: z.string() }),
72
+ z.object({ type: z.literal('apiKey'), header: z.string(), value: z.string() }),
73
+ z.object({ type: z.literal('basic'), username: z.string(), password: z.string() }),
74
+ ])
75
+ .default({ type: 'none' }),
76
+ allowMethods: z
77
+ .array(z.enum(['GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']))
78
+ .default(['GET', 'HEAD', 'OPTIONS']),
79
+ scopes: z.array(ScopeSchema).default(['http:call']),
80
+ limits: LimitsSchema,
81
+ redact: RedactSchema,
82
+ });
83
+ const TransportSchema = z.union([
84
+ z.object({ kind: z.literal('stdio') }),
85
+ z.object({
86
+ kind: z.literal('http'),
87
+ host: z.string().default('127.0.0.1'),
88
+ port: z.number().int().min(1).max(65535).default(7337),
89
+ auth: z
90
+ .union([
91
+ z.object({ type: z.literal('bearer'), token: z.string().optional() }),
92
+ z.object({
93
+ type: z.literal('oauth'),
94
+ issuer: z.string().url(),
95
+ audience: z.string(),
96
+ jwksUri: z.string().url().optional(),
97
+ }),
98
+ ])
99
+ .default({ type: 'bearer' }),
100
+ }),
101
+ ]);
102
+ export const ConfigSchema = z.object({
103
+ server: z
104
+ .object({
105
+ name: z.string().default('mcpolyglot'),
106
+ version: z.string().default('0.0.1'),
107
+ })
108
+ .default({ name: 'mcpolyglot', version: '0.0.1' }),
109
+ transport: TransportSchema.default({ kind: 'stdio' }),
110
+ sources: z.array(z.union([SqlSourceSchema, MongoSourceSchema, OpenApiSourceSchema])).min(1),
111
+ audit: z
112
+ .object({ path: z.string().default('~/.mcpolyglot/audit.log') })
113
+ .default({ path: '~/.mcpolyglot/audit.log' }),
114
+ rateLimit: z
115
+ .object({
116
+ defaultPerMinute: z.number().int().positive().default(30),
117
+ maxConcurrent: z.number().int().positive().default(5),
118
+ })
119
+ .default({ defaultPerMinute: 30, maxConcurrent: 5 }),
120
+ security: z
121
+ .object({
122
+ wrapMode: z.enum(['strict', 'minimal', 'off']).default('strict'),
123
+ })
124
+ .default({ wrapMode: 'strict' }),
125
+ });
126
+ /**
127
+ * Identity helper for type-safe `mcpolyglot.config.ts` files. Wraps the config so editors
128
+ * give you autocomplete and Zod's validation runs at load time rather than crashing later.
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * import { defineConfig } from '@mcpolyglot/config';
133
+ *
134
+ * export default defineConfig({
135
+ * transport: { kind: 'stdio' },
136
+ * sources: [{
137
+ * id: 'pg.main',
138
+ * kind: 'postgres',
139
+ * url: '${env:DATABASE_URL}',
140
+ * scopes: ['schema:read', 'tables:read', 'query:raw'],
141
+ * perEntityTools: { enabled: false },
142
+ * limits: { rowCap: 200, timeoutMs: 10_000, maxBytes: 262144 },
143
+ * redact: { columns: ['public.users.password_hash'], patterns: [] },
144
+ * }],
145
+ * });
146
+ * ```
147
+ */
148
+ export function defineConfig(cfg) {
149
+ return typeof cfg === 'function' ? cfg() : cfg;
150
+ }
151
+ /**
152
+ * Load and validate a config file. Supports `.ts`, `.mts`, `.js`, `.mjs`, `.cjs`,
153
+ * `.json`, `.yaml`, and `.yml`. TS files require the `tsx` loader (the CLI registers it).
154
+ *
155
+ * @throws {ConfigError} when the file is missing, has an unsupported extension,
156
+ * or fails Zod validation.
157
+ */
158
+ export async function loadConfig(path) {
159
+ const abs = isAbsolute(path) ? path : resolve(process.cwd(), path);
160
+ if (!existsSync(abs)) {
161
+ throw new ConfigError(`Config file not found: ${abs}`);
162
+ }
163
+ const ext = extname(abs).toLowerCase();
164
+ let raw;
165
+ switch (ext) {
166
+ case '.json':
167
+ raw = JSON.parse(readFileSync(abs, 'utf8'));
168
+ break;
169
+ case '.yaml':
170
+ case '.yml':
171
+ raw = parseYaml(readFileSync(abs, 'utf8'));
172
+ break;
173
+ case '.ts':
174
+ case '.mts': {
175
+ // Best-effort dynamic import. tsx loader (registered by the CLI) handles TS at runtime.
176
+ const mod = (await import(pathToFileURL(abs).href));
177
+ raw = mod.default ?? mod;
178
+ break;
179
+ }
180
+ case '.js':
181
+ case '.mjs':
182
+ case '.cjs': {
183
+ const mod = (await import(pathToFileURL(abs).href));
184
+ raw = mod.default ?? mod;
185
+ break;
186
+ }
187
+ default:
188
+ throw new ConfigError(`Unsupported config extension: ${ext}`);
189
+ }
190
+ const parsed = ConfigSchema.safeParse(raw);
191
+ if (!parsed.success) {
192
+ throw new ConfigError(`Config validation failed: ${parsed.error.message}`, {
193
+ issues: parsed.error.issues,
194
+ });
195
+ }
196
+ return parsed.data;
197
+ }
198
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Resolve `${env:NAME}`, `${file:./path}`, and `${keychain:item}` references inside a string.
3
+ * Throws ConfigError if a reference can't be resolved.
4
+ */
5
+ export declare function resolveSecrets(input: string): Promise<string>;
6
+ /**
7
+ * Heuristic check: does this string look like a literal credential the user
8
+ * should have wrapped in a `${env:...}` / `${file:...}` / `${keychain:...}` ref?
9
+ * Used by `mcpolyglot doctor` to surface warnings.
10
+ */
11
+ export declare function looksLikeLiteralCredential(value: string): boolean;
12
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAcnE;AAmCD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAWjE"}
@@ -0,0 +1,77 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { ConfigError } from '@mcpolyglot/core';
3
+ const REF_RE = /\$\{(env|file|keychain):([^}]+)\}/g;
4
+ /**
5
+ * Resolve `${env:NAME}`, `${file:./path}`, and `${keychain:item}` references inside a string.
6
+ * Throws ConfigError if a reference can't be resolved.
7
+ */
8
+ export async function resolveSecrets(input) {
9
+ const matches = [...input.matchAll(REF_RE)];
10
+ if (matches.length === 0)
11
+ return input;
12
+ let out = '';
13
+ let last = 0;
14
+ for (const m of matches) {
15
+ out += input.slice(last, m.index);
16
+ const [, kind, target] = m;
17
+ out += await resolveOne(kind, target);
18
+ last = (m.index ?? 0) + m[0].length;
19
+ }
20
+ out += input.slice(last);
21
+ return out;
22
+ }
23
+ async function resolveOne(kind, target) {
24
+ switch (kind) {
25
+ case 'env': {
26
+ const v = process.env[target];
27
+ if (v === undefined)
28
+ throw new ConfigError(`Env var not set: ${target}`);
29
+ return v;
30
+ }
31
+ case 'file': {
32
+ try {
33
+ return (await readFile(target, 'utf8')).trim();
34
+ }
35
+ catch (err) {
36
+ throw new ConfigError(`Failed to read secret file ${target}: ${err.message}`);
37
+ }
38
+ }
39
+ case 'keychain': {
40
+ try {
41
+ const keytar = await import('keytar').catch(() => null);
42
+ if (!keytar) {
43
+ throw new ConfigError('keytar is not installed; install it to use ${keychain:...} refs');
44
+ }
45
+ const v = await keytar.default.getPassword('mcpolyglot', target);
46
+ if (v == null)
47
+ throw new ConfigError(`Keychain item not found: mcpolyglot/${target}`);
48
+ return v;
49
+ }
50
+ catch (err) {
51
+ if (err instanceof ConfigError)
52
+ throw err;
53
+ throw new ConfigError(`Keychain lookup failed: ${err.message}`);
54
+ }
55
+ }
56
+ default:
57
+ throw new ConfigError(`Unknown secret-ref kind: ${kind}`);
58
+ }
59
+ }
60
+ /**
61
+ * Heuristic check: does this string look like a literal credential the user
62
+ * should have wrapped in a `${env:...}` / `${file:...}` / `${keychain:...}` ref?
63
+ * Used by `mcpolyglot doctor` to surface warnings.
64
+ */
65
+ export function looksLikeLiteralCredential(value) {
66
+ if (REF_RE.test(value))
67
+ return false;
68
+ // postgres://user:pass@host/db with a non-trivial password
69
+ const dbUriMatch = value.match(/^[a-z][a-z0-9+]*:\/\/[^:@/\s]+:([^@/\s]+)@/i);
70
+ if (dbUriMatch && dbUriMatch[1] && dbUriMatch[1].length > 4)
71
+ return true;
72
+ // bare bearer-token-shaped strings (long base64-ish)
73
+ if (/^[A-Za-z0-9_\-]{32,}$/.test(value))
74
+ return true;
75
+ return false;
76
+ }
77
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@mcpolyglot/config",
3
+ "version": "0.0.2",
4
+ "description": "Config schema and loader for mcpolyglot. Validates user config and resolves secrets via env / file / OS keychain refs.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/ishay60/mcpolyglot.git",
9
+ "directory": "packages/config"
10
+ },
11
+ "type": "module",
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "dependencies": {
24
+ "tsx": "^4.19.1",
25
+ "yaml": "^2.5.1",
26
+ "zod": "^3.23.8",
27
+ "@mcpolyglot/core": "^0.1.0"
28
+ },
29
+ "optionalDependencies": {
30
+ "keytar": "^7.9.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^25.6.0",
34
+ "typescript": "^6.0.3",
35
+ "vitest": "^2.1.1"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "scripts": {
41
+ "build": "tsc -p tsconfig.json",
42
+ "dev": "tsc -p tsconfig.json --watch",
43
+ "typecheck": "tsc -p tsconfig.json --noEmit",
44
+ "test": "vitest run --passWithNoTests",
45
+ "clean": "rm -rf dist .turbo *.tsbuildinfo"
46
+ }
47
+ }