@mcpolyglot/cli 0.1.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 +18 -4
- 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 +87 -6
- 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 +115 -23
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +46 -9
- 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/commands/tools.d.ts.map +1 -1
- package/dist/commands/tools.js +6 -4
- package/dist/commands/tools.js.map +1 -1
- 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 +46 -5
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +141 -30
- package/dist/ui.js.map +1 -1
- package/package.json +10 -8
package/dist/commands/doctor.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
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';
|
|
4
|
-
import {
|
|
5
|
+
import { doctorAgents } from './doctor-agents.js';
|
|
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;
|
|
7
|
-
|
|
9
|
+
headerBar({
|
|
10
|
+
version: '0.0.1',
|
|
11
|
+
command: 'doctor',
|
|
12
|
+
subtitle: 'validate config, resolve secrets, ping each source',
|
|
13
|
+
}, stdoutSink);
|
|
8
14
|
let cfg;
|
|
9
15
|
try {
|
|
10
16
|
cfg = await loadConfig(opts.config);
|
|
@@ -23,9 +29,18 @@ export async function doctorCommand(opts) {
|
|
|
23
29
|
warn(`${s.id}: url looks like a literal credential`, 'use ${env:NAME}, ${file:./path}, or ${keychain:item}', stdoutSink);
|
|
24
30
|
}
|
|
25
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
|
+
}
|
|
26
41
|
section('Sources', stdoutSink);
|
|
27
42
|
const { connectors, server } = await buildServerFromConfig(cfg);
|
|
28
|
-
for (const c of connectors) {
|
|
43
|
+
for (const [i, c] of connectors.entries()) {
|
|
29
44
|
try {
|
|
30
45
|
await c.init({
|
|
31
46
|
logger: { debug: () => { }, info: () => { }, warn: () => { }, error: () => { } },
|
|
@@ -43,6 +58,20 @@ export async function doctorCommand(opts) {
|
|
|
43
58
|
for (const t of tools) {
|
|
44
59
|
process.stdout.write(` ${sym.bullet} ${pc.bold(t.name)} ${pc.dim('[')}${pc.cyan(t.scopes.join(', '))}${pc.dim(']')}\n`);
|
|
45
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
|
+
}
|
|
46
75
|
await c.close();
|
|
47
76
|
}
|
|
48
77
|
catch (e) {
|
|
@@ -50,16 +79,68 @@ export async function doctorCommand(opts) {
|
|
|
50
79
|
err(c.id, e.message, stdoutSink);
|
|
51
80
|
}
|
|
52
81
|
}
|
|
82
|
+
doctorAgents(cfg, connectors);
|
|
53
83
|
await server.stop().catch(() => { });
|
|
54
84
|
section('Summary', stdoutSink);
|
|
55
85
|
if (allOk) {
|
|
56
|
-
|
|
86
|
+
stdoutSink(` ${chip('READY', 'ready')} mcpolyglot is ready to serve`);
|
|
57
87
|
}
|
|
58
88
|
else {
|
|
59
89
|
err('one or more checks failed', 'see errors above', stdoutSink);
|
|
60
90
|
}
|
|
61
|
-
|
|
62
|
-
process.stdout.write('\n');
|
|
91
|
+
footerBar([`run: ${pc.cyan('mcpolyglot serve')}`, `docs: ${pc.cyan('github.com/ishay60/mcpolyglot')}`], stdoutSink);
|
|
63
92
|
return allOk;
|
|
64
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
|
+
}
|
|
65
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,11 +2,54 @@ 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 {
|
|
5
|
+
import { looksLikeLiteralCredential, resolveSecrets } from '@mcpolyglot/config';
|
|
6
|
+
import { MysqlDialect, PostgresDialect, SqliteDialect, } from '@mcpolyglot/connector-sql';
|
|
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
|
-
|
|
8
|
-
|
|
45
|
+
headerBar({
|
|
46
|
+
version: '0.0.1',
|
|
47
|
+
command: 'init',
|
|
48
|
+
subtitle: 'scaffold mcpolyglot.config.ts in this directory',
|
|
49
|
+
}, stdoutSink);
|
|
9
50
|
const target = resolve(opts.cwd, 'mcpolyglot.config.ts');
|
|
51
|
+
if (opts.url)
|
|
52
|
+
return initFromUrl(opts, opts.url, target);
|
|
10
53
|
if (existsSync(target)) {
|
|
11
54
|
const proceed = await p.confirm({
|
|
12
55
|
message: `mcpolyglot.config.ts already exists in ${opts.cwd}. Overwrite?`,
|
|
@@ -17,6 +60,7 @@ export async function initCommand(opts) {
|
|
|
17
60
|
return;
|
|
18
61
|
}
|
|
19
62
|
}
|
|
63
|
+
step(1, 3, 'Pick a data source', stdoutSink);
|
|
20
64
|
const kind = await p.select({
|
|
21
65
|
message: 'Pick a data source to start with:',
|
|
22
66
|
options: [
|
|
@@ -28,13 +72,15 @@ export async function initCommand(opts) {
|
|
|
28
72
|
p.cancel('Aborted.');
|
|
29
73
|
return;
|
|
30
74
|
}
|
|
75
|
+
step(2, 3, 'Name the source', stdoutSink);
|
|
31
76
|
const id = await p.text({
|
|
32
77
|
message: 'Source id (used in tool names):',
|
|
33
78
|
initialValue: kind === 'postgres' ? 'pg.main' : 'sqlite.local',
|
|
34
|
-
validate: (v) => /^[a-z0-9._-]+$/i.test(v) ? undefined : 'Use letters, digits, dot, hyphen, underscore.',
|
|
79
|
+
validate: (v) => v && /^[a-z0-9._-]+$/i.test(v) ? undefined : 'Use letters, digits, dot, hyphen, underscore.',
|
|
35
80
|
});
|
|
36
81
|
if (p.isCancel(id))
|
|
37
82
|
return;
|
|
83
|
+
step(3, 3, 'Connection', stdoutSink);
|
|
38
84
|
let url;
|
|
39
85
|
if (kind === 'postgres') {
|
|
40
86
|
url = '${env:DATABASE_URL}';
|
|
@@ -44,7 +90,7 @@ export async function initCommand(opts) {
|
|
|
44
90
|
const path = await p.text({
|
|
45
91
|
message: 'Path to SQLite file:',
|
|
46
92
|
placeholder: './data.db',
|
|
47
|
-
validate: (v) => (v.length > 0 ? undefined : 'Required.'),
|
|
93
|
+
validate: (v) => (v && v.length > 0 ? undefined : 'Required.'),
|
|
48
94
|
});
|
|
49
95
|
if (p.isCancel(path))
|
|
50
96
|
return;
|
|
@@ -52,24 +98,54 @@ export async function initCommand(opts) {
|
|
|
52
98
|
}
|
|
53
99
|
const config = renderConfig({ kind: kind, id: id, url });
|
|
54
100
|
writeFileSync(target, config, 'utf8');
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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);
|
|
68
121
|
}
|
|
69
|
-
function
|
|
70
|
-
|
|
122
|
+
function printNext(target) {
|
|
123
|
+
stdoutSink('');
|
|
124
|
+
stdoutSink(` ${chip('OK', 'ok')} wrote ${pc.bold(target)}`);
|
|
125
|
+
panel({
|
|
126
|
+
title: 'Next',
|
|
127
|
+
lines: [
|
|
128
|
+
`${pc.dim('▸')} ${pc.bold('Validate'.padEnd(10))} ${pc.cyan('mcpolyglot doctor')}`,
|
|
129
|
+
`${pc.dim('▸')} ${pc.bold('List'.padEnd(10))} ${pc.cyan('mcpolyglot tools')}`,
|
|
130
|
+
`${pc.dim('▸')} ${pc.bold('Run'.padEnd(10))} ${pc.cyan('mcpolyglot serve')}`,
|
|
131
|
+
],
|
|
132
|
+
}, stdoutSink);
|
|
133
|
+
panel({
|
|
134
|
+
title: 'Wire into your agent',
|
|
135
|
+
lines: [
|
|
136
|
+
`${pc.bold('Claude Desktop')} ${pc.dim('~/Library/Application Support/Claude/claude_desktop_config.json')}`,
|
|
137
|
+
`${pc.bold('Cursor')} ${pc.dim('~/.cursor/mcp.json')}`,
|
|
138
|
+
`${pc.bold('Claude Code')} ${pc.dim('claude mcp add mcpolyglot -- npx -y @mcpolyglot/cli serve')}`,
|
|
139
|
+
],
|
|
140
|
+
}, stdoutSink);
|
|
141
|
+
footerBar(['docs: github.com/ishay60/mcpolyglot'], stdoutSink);
|
|
142
|
+
}
|
|
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';
|
|
71
147
|
|
|
72
|
-
export default
|
|
148
|
+
export default {
|
|
73
149
|
server: { name: 'mcpolyglot', version: '0.0.1' },
|
|
74
150
|
transport: { kind: 'stdio' },
|
|
75
151
|
sources: [
|
|
@@ -83,13 +159,29 @@ export default defineConfig({
|
|
|
83
159
|
redact: {
|
|
84
160
|
columns: [],
|
|
85
161
|
patterns: [],
|
|
86
|
-
}
|
|
162
|
+
},${opts.policy ? renderPolicy(opts.policy) : ''}
|
|
87
163
|
},
|
|
88
164
|
],
|
|
89
165
|
audit: { path: '~/.mcpolyglot/audit.log' },
|
|
90
166
|
rateLimit: { defaultPerMinute: 30, maxConcurrent: 5 },
|
|
91
167
|
security: { wrapMode: 'strict' },
|
|
92
|
-
}
|
|
168
|
+
} satisfies McpolyglotConfig;
|
|
93
169
|
`;
|
|
94
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
|
+
}
|
|
95
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,11 +2,12 @@ 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';
|
|
9
|
-
import {
|
|
10
|
+
import { headerBar, section, kv, ready, footerBar, sym, link } from '../ui.js';
|
|
10
11
|
export async function serveCommand(opts) {
|
|
11
12
|
const startedAt = Date.now();
|
|
12
13
|
if (extname(opts.config) === '.ts' || extname(opts.config) === '.mts') {
|
|
@@ -17,7 +18,11 @@ export async function serveCommand(opts) {
|
|
|
17
18
|
// tsx unavailable — config loader will throw a clear error if it tries.
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
+
headerBar({
|
|
22
|
+
version: '0.0.1',
|
|
23
|
+
command: 'serve',
|
|
24
|
+
subtitle: 'one config, every database your agent needs',
|
|
25
|
+
});
|
|
21
26
|
const cfg = await loadConfig(opts.config);
|
|
22
27
|
const { server, connectors } = await buildServerFromConfig(cfg);
|
|
23
28
|
section('Sources');
|
|
@@ -30,31 +35,63 @@ export async function serveCommand(opts) {
|
|
|
30
35
|
const wantHttp = opts.http || cfg.transport.kind === 'http';
|
|
31
36
|
const httpHost = cfg.transport.kind === 'http' && !opts.http ? cfg.transport.host : opts.host;
|
|
32
37
|
const httpPort = cfg.transport.kind === 'http' && !opts.http ? cfg.transport.port : opts.port;
|
|
33
|
-
const
|
|
34
|
-
? cfg.transport.auth.token
|
|
35
|
-
: undefined;
|
|
38
|
+
const httpAuth = cfg.transport.kind === 'http' ? cfg.transport.auth : { type: 'bearer' };
|
|
36
39
|
let transport;
|
|
37
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
|
+
}
|
|
38
44
|
const httpTransport = new StreamableHttpTransport({
|
|
39
45
|
host: httpHost,
|
|
40
46
|
port: httpPort,
|
|
41
|
-
|
|
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
|
+
},
|
|
42
60
|
});
|
|
43
61
|
transport = httpTransport;
|
|
44
62
|
kv('Mode', pc.cyan('streamable-http'));
|
|
45
63
|
kv('URL', link(`http://${httpHost}:${httpPort}/mcp`));
|
|
46
64
|
kv('Health', link(`http://${httpHost}:${httpPort}/healthz`));
|
|
47
|
-
|
|
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') {
|
|
69
|
+
kv('Auth', pc.cyan(`oauth · ${httpAuth.issuer}`));
|
|
70
|
+
kv('Audience', pc.dim(httpAuth.audience));
|
|
71
|
+
}
|
|
72
|
+
else if (httpTransport.bearerToken) {
|
|
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));
|
|
77
|
+
}
|
|
48
78
|
kv('Config', pc.dim(basename(opts.config)));
|
|
49
79
|
}
|
|
50
80
|
else {
|
|
51
81
|
transport = new StdioTransport();
|
|
52
82
|
kv('Mode', pc.cyan('stdio'));
|
|
83
|
+
if (cfg.agents)
|
|
84
|
+
kv('Agents', pc.yellow('ignored under stdio (single local user)'));
|
|
53
85
|
kv('Config', pc.dim(basename(opts.config)));
|
|
54
86
|
}
|
|
55
87
|
await server.start(transport);
|
|
56
88
|
ready(Date.now() - startedAt);
|
|
57
|
-
|
|
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'}`]);
|
|
58
95
|
const shutdown = async () => {
|
|
59
96
|
process.stderr.write(pc.dim('\n shutting down…\n'));
|
|
60
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,EAAE,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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/commands/tools.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/commands/tools.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCpE"}
|
package/dist/commands/tools.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import pc from 'picocolors';
|
|
2
2
|
import { loadConfig } from '@mcpolyglot/config';
|
|
3
3
|
import { buildServerFromConfig } from '../factory.js';
|
|
4
|
-
import {
|
|
4
|
+
import { headerBar, section, table, footerBar, stdoutSink } from '../ui.js';
|
|
5
5
|
export async function toolsCommand(opts) {
|
|
6
|
-
|
|
6
|
+
headerBar({ version: '0.0.1', command: 'tools', subtitle: 'preview generated MCP tools' }, stdoutSink);
|
|
7
7
|
const cfg = await loadConfig(opts.config);
|
|
8
8
|
const { connectors } = await buildServerFromConfig(cfg);
|
|
9
9
|
const rows = [];
|
|
@@ -23,7 +23,9 @@ export async function toolsCommand(opts) {
|
|
|
23
23
|
}
|
|
24
24
|
section(`${rows.length} tool(s)`, stdoutSink);
|
|
25
25
|
table([{ header: 'NAME' }, { header: 'MODE' }, { header: 'SCOPES' }, { header: 'DESCRIPTION' }], rows, stdoutSink);
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
footerBar([
|
|
27
|
+
`serve: ${pc.cyan('mcpolyglot serve --config ' + opts.config)}`,
|
|
28
|
+
`docs: ${pc.cyan('github.com/ishay60/mcpolyglot')}`,
|
|
29
|
+
], stdoutSink);
|
|
28
30
|
}
|
|
29
31
|
//# sourceMappingURL=tools.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/commands/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/commands/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAM5E,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAkB;IACnD,SAAS,CACP,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,6BAA6B,EAAE,EAC/E,UAAU,CACX,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAExD,MAAM,IAAI,GAAe,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,CAAC,CAAC,IAAI,CAAC;YACX,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE;SAC7E,CAAC,CAAC;QACH,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,kBAAkB,EAAE,EAAE,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC;gBACR,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;gBAClB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC;gBAC/D,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/B,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;aACzB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,UAAU,EAAE,UAAU,CAAC,CAAC;IAC9C,KAAK,CACH,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,EACzF,IAAI,EACJ,UAAU,CACX,CAAC;IACF,SAAS,CACP;QACE,UAAU,EAAE,CAAC,IAAI,CAAC,4BAA4B,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE;QAC/D,SAAS,EAAE,CAAC,IAAI,CAAC,+BAA+B,CAAC,EAAE;KACpD,EACD,UAAU,CACX,CAAC;AACJ,CAAC"}
|