@mcpolyglot/cli 0.2.0 → 0.3.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 +27 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/agents.test.d.ts +2 -0
- package/dist/__tests__/agents.test.d.ts.map +1 -0
- package/dist/__tests__/agents.test.js +172 -0
- package/dist/__tests__/agents.test.js.map +1 -0
- package/dist/__tests__/examples.test.d.ts +2 -0
- package/dist/__tests__/examples.test.d.ts.map +1 -0
- package/dist/__tests__/examples.test.js +140 -0
- package/dist/__tests__/examples.test.js.map +1 -0
- package/dist/__tests__/init-doctor.test.d.ts +2 -0
- package/dist/__tests__/init-doctor.test.d.ts.map +1 -0
- package/dist/__tests__/init-doctor.test.js +79 -0
- package/dist/__tests__/init-doctor.test.js.map +1 -0
- package/dist/bin.js +16 -3
- package/dist/bin.js.map +1 -1
- package/dist/commands/doctor-agents.d.ts +5 -0
- package/dist/commands/doctor-agents.d.ts.map +1 -0
- package/dist/commands/doctor-agents.js +33 -0
- package/dist/commands/doctor-agents.js.map +1 -0
- package/dist/commands/doctor.d.ts +10 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +79 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts +16 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +85 -5
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +34 -12
- package/dist/commands/serve.js.map +1 -1
- package/dist/commands/token.d.ts +5 -0
- package/dist/commands/token.d.ts.map +1 -0
- package/dist/commands/token.js +23 -0
- package/dist/commands/token.js.map +1 -0
- package/dist/factory.d.ts +6 -2
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +84 -12
- package/dist/factory.js.map +1 -1
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +0 -2
- package/dist/ui.js.map +1 -1
- package/package.json +8 -6
package/dist/commands/doctor.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import pc from 'picocolors';
|
|
2
2
|
import { loadConfig, looksLikeLiteralCredential } from '@mcpolyglot/config';
|
|
3
|
+
import { isColumnDenied, PolicySchema, tableAccess, } from '@mcpolyglot/connector-sql';
|
|
3
4
|
import { buildServerFromConfig } from '../factory.js';
|
|
5
|
+
import { doctorAgents } from './doctor-agents.js';
|
|
4
6
|
import { headerBar, section, ok, err, warn, bullet, footerBar, stdoutSink, sym, chip, } from '../ui.js';
|
|
5
7
|
export async function doctorCommand(opts) {
|
|
6
8
|
let allOk = true;
|
|
@@ -27,9 +29,18 @@ export async function doctorCommand(opts) {
|
|
|
27
29
|
warn(`${s.id}: url looks like a literal credential`, 'use ${env:NAME}, ${file:./path}, or ${keychain:item}', stdoutSink);
|
|
28
30
|
}
|
|
29
31
|
}
|
|
32
|
+
// An invalid policy stops the server from starting, so report it before building one.
|
|
33
|
+
for (const s of cfg.sources) {
|
|
34
|
+
const parsed = 'policy' in s ? PolicySchema.safeParse(s.policy ?? {}) : undefined;
|
|
35
|
+
if (parsed && !parsed.success) {
|
|
36
|
+
section('Policy', stdoutSink);
|
|
37
|
+
err(`${s.id}: invalid policy`, parsed.error.issues.map((i) => i.message).join('; '), stdoutSink);
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
30
41
|
section('Sources', stdoutSink);
|
|
31
42
|
const { connectors, server } = await buildServerFromConfig(cfg);
|
|
32
|
-
for (const c of connectors) {
|
|
43
|
+
for (const [i, c] of connectors.entries()) {
|
|
33
44
|
try {
|
|
34
45
|
await c.init({
|
|
35
46
|
logger: { debug: () => { }, info: () => { }, warn: () => { }, error: () => { } },
|
|
@@ -47,6 +58,20 @@ export async function doctorCommand(opts) {
|
|
|
47
58
|
for (const t of tools) {
|
|
48
59
|
process.stdout.write(` ${sym.bullet} ${pc.bold(t.name)} ${pc.dim('[')}${pc.cyan(t.scopes.join(', '))}${pc.dim(']')}\n`);
|
|
49
60
|
}
|
|
61
|
+
const src = cfg.sources[i];
|
|
62
|
+
if (c.kind === 'sql' && src && src.kind !== 'mongo' && src.kind !== 'openapi') {
|
|
63
|
+
const snap = await c.introspect();
|
|
64
|
+
if (snap.kind === 'sql' && !printPolicyReport(checkPolicy(src.policy, snap.tables))) {
|
|
65
|
+
allOk = false;
|
|
66
|
+
}
|
|
67
|
+
// The classifier is defense-in-depth; the DB grant is the control. A user that can
|
|
68
|
+
// read server files or is superuser makes the policy advisory, so doctor fails.
|
|
69
|
+
const privs = await c.auditPrivileges();
|
|
70
|
+
for (const p of privs) {
|
|
71
|
+
allOk = false;
|
|
72
|
+
err('privileges', p, stdoutSink);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
50
75
|
await c.close();
|
|
51
76
|
}
|
|
52
77
|
catch (e) {
|
|
@@ -54,6 +79,7 @@ export async function doctorCommand(opts) {
|
|
|
54
79
|
err(c.id, e.message, stdoutSink);
|
|
55
80
|
}
|
|
56
81
|
}
|
|
82
|
+
doctorAgents(cfg, connectors);
|
|
57
83
|
await server.stop().catch(() => { });
|
|
58
84
|
section('Summary', stdoutSink);
|
|
59
85
|
if (allOk) {
|
|
@@ -65,4 +91,56 @@ export async function doctorCommand(opts) {
|
|
|
65
91
|
footerBar([`run: ${pc.cyan('mcpolyglot serve')}`, `docs: ${pc.cyan('github.com/ishay60/mcpolyglot')}`], stdoutSink);
|
|
66
92
|
return allOk;
|
|
67
93
|
}
|
|
94
|
+
/** Check a source's policy against its live schema. `policy` must already parse. */
|
|
95
|
+
export function checkPolicy(raw, tables) {
|
|
96
|
+
const policy = PolicySchema.parse(raw ?? {});
|
|
97
|
+
const name = (t) => (t.schema ? `${t.schema}.${t.name}` : t.name);
|
|
98
|
+
const matches = (key, t) => {
|
|
99
|
+
const k = key.toLowerCase();
|
|
100
|
+
return k === t.name.toLowerCase() || k === name(t).toLowerCase();
|
|
101
|
+
};
|
|
102
|
+
const report = {
|
|
103
|
+
problems: [],
|
|
104
|
+
readable: [],
|
|
105
|
+
writable: [],
|
|
106
|
+
hidden: [],
|
|
107
|
+
hiddenColumns: [],
|
|
108
|
+
};
|
|
109
|
+
for (const key of Object.keys(policy.tables)) {
|
|
110
|
+
if (!tables.some((t) => matches(key, t))) {
|
|
111
|
+
report.problems.push(`policy.tables names "${key}", which is not in the schema`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
for (const entry of policy.denyColumns) {
|
|
115
|
+
const dot = entry.lastIndexOf('.');
|
|
116
|
+
const [table, column] = [entry.slice(0, dot), entry.slice(dot + 1).toLowerCase()];
|
|
117
|
+
const bare = table.split('.').pop().toLowerCase();
|
|
118
|
+
const candidates = table === '*' ? tables : tables.filter((t) => t.name.toLowerCase() === bare);
|
|
119
|
+
if (!candidates.some((t) => t.columns.some((c) => c.name.toLowerCase() === column))) {
|
|
120
|
+
report.problems.push(`denyColumns has "${entry}", which matches no column in the schema`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
for (const t of tables) {
|
|
124
|
+
const access = tableAccess(policy, t.schema ?? 'null', t.name);
|
|
125
|
+
const bucket = access === 'write' ? 'writable' : access === 'read' ? 'readable' : 'hidden';
|
|
126
|
+
report[bucket].push(name(t));
|
|
127
|
+
if (access !== 'none') {
|
|
128
|
+
for (const c of t.columns) {
|
|
129
|
+
if (isColumnDenied(policy, t.name, c.name))
|
|
130
|
+
report.hiddenColumns.push(`${name(t)}.${c.name}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return report;
|
|
135
|
+
}
|
|
136
|
+
function printPolicyReport(r) {
|
|
137
|
+
const list = (xs) => (xs.length ? xs.join(', ') : pc.dim('none'));
|
|
138
|
+
bullet(pc.dim('readable'), list(r.readable), stdoutSink);
|
|
139
|
+
bullet(pc.dim('writable'), list(r.writable), stdoutSink);
|
|
140
|
+
bullet(pc.dim('hidden'), list(r.hidden), stdoutSink);
|
|
141
|
+
bullet(pc.dim('hidden columns'), list(r.hiddenColumns), stdoutSink);
|
|
142
|
+
for (const p of r.problems)
|
|
143
|
+
err('policy', p, stdoutSink);
|
|
144
|
+
return r.problems.length === 0;
|
|
145
|
+
}
|
|
68
146
|
//# sourceMappingURL=doctor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
|
+
import type { TableSchema } from '@mcpolyglot/core';
|
|
2
|
+
import { type Policy, type SqlDialect } from '@mcpolyglot/connector-sql';
|
|
3
|
+
type SqlKind = SqlDialect['kind'];
|
|
1
4
|
export interface InitOptions {
|
|
2
5
|
cwd: string;
|
|
6
|
+
/** DB URL (or SQLite path). When set, init introspects it and skips the prompts. */
|
|
7
|
+
url?: string;
|
|
8
|
+
id?: string;
|
|
3
9
|
}
|
|
10
|
+
export declare function inferKind(url: string): SqlKind;
|
|
11
|
+
/** Every table explicitly `read`, unknown tables hidden, sensitive-looking columns denied. */
|
|
12
|
+
export declare function generatePolicy(tables: TableSchema[]): Pick<Policy, 'tables' | 'defaultAccess' | 'denyColumns'>;
|
|
4
13
|
export declare function initCommand(opts: InitOptions): Promise<void>;
|
|
14
|
+
export declare function renderConfig(opts: {
|
|
15
|
+
kind: SqlKind;
|
|
16
|
+
id: string;
|
|
17
|
+
url: string;
|
|
18
|
+
policy?: ReturnType<typeof generatePolicy>;
|
|
19
|
+
}): string;
|
|
20
|
+
export {};
|
|
5
21
|
//# sourceMappingURL=init.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAIL,KAAK,MAAM,EACX,KAAK,UAAU,EAChB,MAAM,2BAA2B,CAAC;AAGnC,KAAK,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;AAElC,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,oFAAoF;IACpF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAOD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAK9C;AAED,8FAA8F;AAC9F,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EAAE,GACpB,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,eAAe,GAAG,aAAa,CAAC,CAS1D;AAkBD,wBAAsB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAkElE;AAyDD,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;CAC5C,GAAG,MAAM,CA2BT"}
|
package/dist/commands/init.js
CHANGED
|
@@ -2,7 +2,45 @@ import { writeFileSync, existsSync } from 'node:fs';
|
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
3
|
import * as p from '@clack/prompts';
|
|
4
4
|
import pc from 'picocolors';
|
|
5
|
+
import { looksLikeLiteralCredential, resolveSecrets } from '@mcpolyglot/config';
|
|
6
|
+
import { MysqlDialect, PostgresDialect, SqliteDialect, } from '@mcpolyglot/connector-sql';
|
|
5
7
|
import { headerBar, panel, footerBar, step, chip, stdoutSink } from '../ui.js';
|
|
8
|
+
/** Column names that usually hold secrets or PII. A suggestion, not a guarantee. */
|
|
9
|
+
// ponytail: name-only heuristic; misses e.g. `notes` holding secrets. Values are never sampled.
|
|
10
|
+
const SENSITIVE_COLUMN = /pass(word|wd)?|pwd|secret|token|ssn|social_?security|api_?key|hash|salt|private_?key|card_?number|cvv|otp|mfa/i;
|
|
11
|
+
export function inferKind(url) {
|
|
12
|
+
if (/^postgres(ql)?:\/\//i.test(url))
|
|
13
|
+
return 'postgres';
|
|
14
|
+
if (/^mysql:\/\//i.test(url))
|
|
15
|
+
return 'mysql';
|
|
16
|
+
if (/^mariadb:\/\//i.test(url))
|
|
17
|
+
return 'mariadb';
|
|
18
|
+
return 'sqlite';
|
|
19
|
+
}
|
|
20
|
+
/** Every table explicitly `read`, unknown tables hidden, sensitive-looking columns denied. */
|
|
21
|
+
export function generatePolicy(tables) {
|
|
22
|
+
const key = (t) => (t.schema ? `${t.schema}.${t.name}` : t.name);
|
|
23
|
+
return {
|
|
24
|
+
defaultAccess: 'none',
|
|
25
|
+
tables: Object.fromEntries(tables.map((t) => [key(t), 'read'])),
|
|
26
|
+
denyColumns: tables.flatMap((t) => t.columns.filter((c) => SENSITIVE_COLUMN.test(c.name)).map((c) => `${key(t)}.${c.name}`)),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
async function introspect(kind, url) {
|
|
30
|
+
const resolved = await resolveSecrets(url);
|
|
31
|
+
const dialect = kind === 'postgres'
|
|
32
|
+
? new PostgresDialect(resolved)
|
|
33
|
+
: kind === 'sqlite'
|
|
34
|
+
? new SqliteDialect(resolved)
|
|
35
|
+
: new MysqlDialect(resolved);
|
|
36
|
+
await dialect.connect();
|
|
37
|
+
try {
|
|
38
|
+
return await dialect.listTables();
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
await dialect.close();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
6
44
|
export async function initCommand(opts) {
|
|
7
45
|
headerBar({
|
|
8
46
|
version: '0.0.1',
|
|
@@ -10,6 +48,8 @@ export async function initCommand(opts) {
|
|
|
10
48
|
subtitle: 'scaffold mcpolyglot.config.ts in this directory',
|
|
11
49
|
}, stdoutSink);
|
|
12
50
|
const target = resolve(opts.cwd, 'mcpolyglot.config.ts');
|
|
51
|
+
if (opts.url)
|
|
52
|
+
return initFromUrl(opts, opts.url, target);
|
|
13
53
|
if (existsSync(target)) {
|
|
14
54
|
const proceed = await p.confirm({
|
|
15
55
|
message: `mcpolyglot.config.ts already exists in ${opts.cwd}. Overwrite?`,
|
|
@@ -58,6 +98,28 @@ export async function initCommand(opts) {
|
|
|
58
98
|
}
|
|
59
99
|
const config = renderConfig({ kind: kind, id: id, url });
|
|
60
100
|
writeFileSync(target, config, 'utf8');
|
|
101
|
+
printNext(target);
|
|
102
|
+
}
|
|
103
|
+
async function initFromUrl(opts, url, target) {
|
|
104
|
+
if (existsSync(target)) {
|
|
105
|
+
throw new Error(`${target} already exists; move it aside first.`);
|
|
106
|
+
}
|
|
107
|
+
const kind = inferKind(url);
|
|
108
|
+
step(1, 2, `Introspect ${kind}`, stdoutSink);
|
|
109
|
+
const tables = await introspect(kind, url);
|
|
110
|
+
const policy = generatePolicy(tables);
|
|
111
|
+
stdoutSink(` ${chip('OK', 'ok')} ${tables.length} tables, ${policy.denyColumns.length} sensitive-looking columns`);
|
|
112
|
+
step(2, 2, 'Write config', stdoutSink);
|
|
113
|
+
// Never write a literal password into the config; point at the env var instead.
|
|
114
|
+
const safeUrl = kind !== 'sqlite' && looksLikeLiteralCredential(url) ? '${env:DATABASE_URL}' : url;
|
|
115
|
+
if (safeUrl !== url) {
|
|
116
|
+
p.note(`Set ${pc.cyan('DATABASE_URL')} to your connection string before serving.`, 'Secret');
|
|
117
|
+
}
|
|
118
|
+
const id = opts.id ?? (kind === 'sqlite' ? 'sqlite.local' : `${kind}.main`);
|
|
119
|
+
writeFileSync(target, renderConfig({ kind, id, url: safeUrl, policy }), 'utf8');
|
|
120
|
+
printNext(target);
|
|
121
|
+
}
|
|
122
|
+
function printNext(target) {
|
|
61
123
|
stdoutSink('');
|
|
62
124
|
stdoutSink(` ${chip('OK', 'ok')} wrote ${pc.bold(target)}`);
|
|
63
125
|
panel({
|
|
@@ -78,10 +140,12 @@ export async function initCommand(opts) {
|
|
|
78
140
|
}, stdoutSink);
|
|
79
141
|
footerBar(['docs: github.com/ishay60/mcpolyglot'], stdoutSink);
|
|
80
142
|
}
|
|
81
|
-
function renderConfig(opts) {
|
|
82
|
-
|
|
143
|
+
export function renderConfig(opts) {
|
|
144
|
+
// Type-only import: erased at load time, so the file runs under npx without
|
|
145
|
+
// @mcpolyglot/config installed next to it. Install it for editor autocomplete.
|
|
146
|
+
return `import type { McpolyglotConfig } from '@mcpolyglot/config';
|
|
83
147
|
|
|
84
|
-
export default
|
|
148
|
+
export default {
|
|
85
149
|
server: { name: 'mcpolyglot', version: '0.0.1' },
|
|
86
150
|
transport: { kind: 'stdio' },
|
|
87
151
|
sources: [
|
|
@@ -95,13 +159,29 @@ export default defineConfig({
|
|
|
95
159
|
redact: {
|
|
96
160
|
columns: [],
|
|
97
161
|
patterns: [],
|
|
98
|
-
}
|
|
162
|
+
},${opts.policy ? renderPolicy(opts.policy) : ''}
|
|
99
163
|
},
|
|
100
164
|
],
|
|
101
165
|
audit: { path: '~/.mcpolyglot/audit.log' },
|
|
102
166
|
rateLimit: { defaultPerMinute: 30, maxConcurrent: 5 },
|
|
103
167
|
security: { wrapMode: 'strict' },
|
|
104
|
-
}
|
|
168
|
+
} satisfies McpolyglotConfig;
|
|
105
169
|
`;
|
|
106
170
|
}
|
|
171
|
+
function renderPolicy(policy) {
|
|
172
|
+
const q = JSON.stringify;
|
|
173
|
+
const tables = Object.keys(policy.tables).map((t) => `\n ${q(t)}: 'read',`);
|
|
174
|
+
const denies = policy.denyColumns.map((c) => `\n ${q(c)},`);
|
|
175
|
+
return `
|
|
176
|
+
policy: {
|
|
177
|
+
// Tables not listed below are hidden. Add new tables here explicitly.
|
|
178
|
+
defaultAccess: 'none',
|
|
179
|
+
// Every table is read-only. Set a table to 'write' only if an agent must modify it.
|
|
180
|
+
tables: {${tables.join('')}
|
|
181
|
+
},
|
|
182
|
+
// Suggested from column names (password, token, ssn, hash, ...). Review: keep, add, remove.
|
|
183
|
+
denyColumns: [${denies.join('')}
|
|
184
|
+
],
|
|
185
|
+
},`;
|
|
186
|
+
}
|
|
107
187
|
//# sourceMappingURL=init.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAuGpE"}
|
package/dist/commands/serve.js
CHANGED
|
@@ -2,7 +2,8 @@ import { register } from 'node:module';
|
|
|
2
2
|
import { pathToFileURL } from 'node:url';
|
|
3
3
|
import { extname, basename } from 'node:path';
|
|
4
4
|
import pc from 'picocolors';
|
|
5
|
-
import { loadConfig } from '@mcpolyglot/config';
|
|
5
|
+
import { loadConfig, resolveSecrets } from '@mcpolyglot/config';
|
|
6
|
+
import { ConfigError } from '@mcpolyglot/core';
|
|
6
7
|
import { StdioTransport } from '@mcpolyglot/core/transports/stdio';
|
|
7
8
|
import { StreamableHttpTransport } from '@mcpolyglot/core/transports/streamable-http';
|
|
8
9
|
import { buildServerFromConfig } from '../factory.js';
|
|
@@ -37,39 +38,60 @@ export async function serveCommand(opts) {
|
|
|
37
38
|
const httpAuth = cfg.transport.kind === 'http' ? cfg.transport.auth : { type: 'bearer' };
|
|
38
39
|
let transport;
|
|
39
40
|
if (wantHttp) {
|
|
41
|
+
if (cfg.agents && httpAuth.type === 'oauth') {
|
|
42
|
+
throw new ConfigError('`agents` uses per-agent bearer tokens; it cannot be combined with OAuth.');
|
|
43
|
+
}
|
|
40
44
|
const httpTransport = new StreamableHttpTransport({
|
|
41
45
|
host: httpHost,
|
|
42
46
|
port: httpPort,
|
|
43
|
-
auth:
|
|
44
|
-
? {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
auth: cfg.agents
|
|
48
|
+
? { kind: 'agents', agents: cfg.agents }
|
|
49
|
+
: httpAuth.type === 'oauth'
|
|
50
|
+
? {
|
|
51
|
+
kind: 'oauth',
|
|
52
|
+
issuer: httpAuth.issuer,
|
|
53
|
+
audience: httpAuth.audience,
|
|
54
|
+
...(httpAuth.jwksUri ? { jwksUri: httpAuth.jwksUri } : {}),
|
|
55
|
+
}
|
|
56
|
+
: {
|
|
57
|
+
kind: 'bearer',
|
|
58
|
+
...(httpAuth.token ? { token: await resolveSecrets(httpAuth.token) } : {}),
|
|
59
|
+
},
|
|
51
60
|
});
|
|
52
61
|
transport = httpTransport;
|
|
53
62
|
kv('Mode', pc.cyan('streamable-http'));
|
|
54
63
|
kv('URL', link(`http://${httpHost}:${httpPort}/mcp`));
|
|
55
64
|
kv('Health', link(`http://${httpHost}:${httpPort}/healthz`));
|
|
56
|
-
if (
|
|
65
|
+
if (cfg.agents) {
|
|
66
|
+
kv('Auth', pc.cyan(`agents · ${cfg.agents.map((a) => a.id).join(', ')}`));
|
|
67
|
+
}
|
|
68
|
+
else if (httpTransport.authKind === 'oauth' && httpAuth.type === 'oauth') {
|
|
57
69
|
kv('Auth', pc.cyan(`oauth · ${httpAuth.issuer}`));
|
|
58
70
|
kv('Audience', pc.dim(httpAuth.audience));
|
|
59
71
|
}
|
|
60
72
|
else if (httpTransport.bearerToken) {
|
|
61
|
-
|
|
73
|
+
// Only echo a generated token; a configured one would leak into container logs.
|
|
74
|
+
kv('Token', 'token' in httpAuth && httpAuth.token
|
|
75
|
+
? pc.dim('from config')
|
|
76
|
+
: pc.yellow(httpTransport.bearerToken));
|
|
62
77
|
}
|
|
63
78
|
kv('Config', pc.dim(basename(opts.config)));
|
|
64
79
|
}
|
|
65
80
|
else {
|
|
66
81
|
transport = new StdioTransport();
|
|
67
82
|
kv('Mode', pc.cyan('stdio'));
|
|
83
|
+
if (cfg.agents)
|
|
84
|
+
kv('Agents', pc.yellow('ignored under stdio (single local user)'));
|
|
68
85
|
kv('Config', pc.dim(basename(opts.config)));
|
|
69
86
|
}
|
|
70
87
|
await server.start(transport);
|
|
71
88
|
ready(Date.now() - startedAt);
|
|
72
|
-
|
|
89
|
+
const auditSinks = [
|
|
90
|
+
cfg.audit.console && (cfg.transport.kind === 'stdio' ? 'stderr' : 'stdout'),
|
|
91
|
+
cfg.audit.path,
|
|
92
|
+
cfg.audit.webhookUrl && 'webhook',
|
|
93
|
+
].filter(Boolean);
|
|
94
|
+
footerBar(['Ctrl+C to stop', `audit: ${auditSinks.join(', ') || 'off'}`]);
|
|
73
95
|
const shutdown = async () => {
|
|
74
96
|
process.stderr.write(pc.dim('\n shutting down…\n'));
|
|
75
97
|
await server.stop().catch(() => { });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAyB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Mint a token. The only place mcpolyglot ever prints one; config stores just the hash. */
|
|
2
|
+
export declare function tokenCreateCommand(agentId: string): void;
|
|
3
|
+
/** Hash a token read from stdin (trailing newline ignored). */
|
|
4
|
+
export declare function tokenHashCommand(): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/commands/token.ts"],"names":[],"mappings":"AAIA,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAYxD;AAED,+DAA+D;AAC/D,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAItD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { text } from 'node:stream/consumers';
|
|
3
|
+
import { hashToken } from '@mcpolyglot/core/transports/streamable-http';
|
|
4
|
+
/** Mint a token. The only place mcpolyglot ever prints one; config stores just the hash. */
|
|
5
|
+
export function tokenCreateCommand(agentId) {
|
|
6
|
+
const token = `mcpg_${randomBytes(32).toString('base64url')}`;
|
|
7
|
+
const hash = hashToken(token);
|
|
8
|
+
const label = new Date().toISOString().slice(0, 10);
|
|
9
|
+
process.stdout.write(`token (shown once, give it to the agent): ${token}\n` +
|
|
10
|
+
`sha256: ${hash}\n\n` +
|
|
11
|
+
`add to the agent in your config:\n` +
|
|
12
|
+
` agents: [{ id: '${agentId}', tokens: [{ hash: '${hash}', label: '${label}' }], sources: { … } }]\n` +
|
|
13
|
+
`rotate: add this hash next to the old one, move clients over, then set the old one's revoked: true.\n` +
|
|
14
|
+
`restart \`mcpolyglot serve\` to apply.\n`);
|
|
15
|
+
}
|
|
16
|
+
/** Hash a token read from stdin (trailing newline ignored). */
|
|
17
|
+
export async function tokenHashCommand() {
|
|
18
|
+
const token = (await text(process.stdin)).replace(/\r?\n$/, '');
|
|
19
|
+
if (!token)
|
|
20
|
+
throw new Error('no token on stdin');
|
|
21
|
+
process.stdout.write(hashToken(token) + '\n');
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/commands/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,6CAA6C,CAAC;AAExE,4FAA4F;AAC5F,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,KAAK,GAAG,QAAQ,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;IAC9D,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6CAA6C,KAAK,IAAI;QACpD,WAAW,IAAI,MAAM;QACrB,oCAAoC;QACpC,qBAAqB,OAAO,wBAAwB,IAAI,cAAc,KAAK,2BAA2B;QACtG,uGAAuG;QACvG,0CAA0C,CAC7C,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAChE,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;AAChD,CAAC"}
|
package/dist/factory.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { McpolyglotServer, type Connector, type SecurityHooks } from '@mcpolyglot/core';
|
|
2
|
-
import { type McpolyglotConfig } from '@mcpolyglot/config';
|
|
1
|
+
import { McpolyglotServer, type AgentGrant, type Connector, type Scope, type SecurityHooks } from '@mcpolyglot/core';
|
|
2
|
+
import { type McpolyglotConfig, type SourceConfig, type AgentConfig } from '@mcpolyglot/config';
|
|
3
3
|
export interface BuiltServer {
|
|
4
4
|
server: McpolyglotServer;
|
|
5
5
|
hooks: SecurityHooks;
|
|
6
6
|
connectors: Connector[];
|
|
7
|
+
/** Present when `cfg.agents` is set. */
|
|
8
|
+
agents?: AgentGrant[];
|
|
7
9
|
perEntity: Record<string, {
|
|
8
10
|
enabled: boolean;
|
|
9
11
|
include?: string[];
|
|
@@ -16,4 +18,6 @@ export declare function buildServerFromConfig(cfg: McpolyglotConfig, logger?: {
|
|
|
16
18
|
warn: (msg: string, fields?: Record<string, unknown>) => void;
|
|
17
19
|
error: (msg: string, fields?: Record<string, unknown>) => void;
|
|
18
20
|
}): Promise<BuiltServer>;
|
|
21
|
+
/** An agent never gets a scope its sources don't grant. */
|
|
22
|
+
export declare function agentScopes(agent: AgentConfig, sources: SourceConfig[]): Scope[];
|
|
19
23
|
//# sourceMappingURL=factory.d.ts.map
|
package/dist/factory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,KAAK,SAAS,EACd,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,gBAAgB,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,KAAK,EACV,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAEjB,KAAK,WAAW,EAEjB,MAAM,oBAAoB,CAAC;AAY5B,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,wCAAwC;IACxC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACzF;AAED,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,gBAAgB,EACrB,MAAM;iBAyM6B,MAAM,WAAW,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBAAxC,MAAM,WAAW,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBAAxC,MAAM,WAAW,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;iBAAxC,MAAM,WAAW,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAzMhD,GAC1B,OAAO,CAAC,WAAW,CAAC,CA+DtB;AA8FD,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,KAAK,EAAE,CAGhF"}
|