@acr-js/meta-mcp 0.8.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.
- package/README.md +212 -0
- package/dist/apps/cli/src/index.d.ts +3 -0
- package/dist/apps/cli/src/index.d.ts.map +1 -0
- package/dist/apps/cli/src/index.js +326 -0
- package/dist/apps/cli/src/index.js.map +1 -0
- package/dist/apps/control-plane-api/src/audit.d.ts +20 -0
- package/dist/apps/control-plane-api/src/audit.d.ts.map +1 -0
- package/dist/apps/control-plane-api/src/audit.js +26 -0
- package/dist/apps/control-plane-api/src/audit.js.map +1 -0
- package/dist/apps/control-plane-api/src/index.d.ts +2 -0
- package/dist/apps/control-plane-api/src/index.d.ts.map +1 -0
- package/dist/apps/control-plane-api/src/index.js +20 -0
- package/dist/apps/control-plane-api/src/index.js.map +1 -0
- package/dist/apps/control-plane-api/src/server.d.ts +17 -0
- package/dist/apps/control-plane-api/src/server.d.ts.map +1 -0
- package/dist/apps/control-plane-api/src/server.js +268 -0
- package/dist/apps/control-plane-api/src/server.js.map +1 -0
- package/dist/apps/control-plane-api/src/service.d.ts +63 -0
- package/dist/apps/control-plane-api/src/service.d.ts.map +1 -0
- package/dist/apps/control-plane-api/src/service.js +298 -0
- package/dist/apps/control-plane-api/src/service.js.map +1 -0
- package/dist/apps/control-plane-api/test/api.test.d.ts +2 -0
- package/dist/apps/control-plane-api/test/api.test.d.ts.map +1 -0
- package/dist/apps/control-plane-api/test/api.test.js +130 -0
- package/dist/apps/control-plane-api/test/api.test.js.map +1 -0
- package/dist/apps/control-plane-api/test/context7-e2e.test.d.ts +2 -0
- package/dist/apps/control-plane-api/test/context7-e2e.test.d.ts.map +1 -0
- package/dist/apps/control-plane-api/test/context7-e2e.test.js +166 -0
- package/dist/apps/control-plane-api/test/context7-e2e.test.js.map +1 -0
- package/dist/packages/auth-vault/src/crypto.d.ts +25 -0
- package/dist/packages/auth-vault/src/crypto.d.ts.map +1 -0
- package/dist/packages/auth-vault/src/crypto.js +117 -0
- package/dist/packages/auth-vault/src/crypto.js.map +1 -0
- package/dist/packages/auth-vault/src/db.d.ts +33 -0
- package/dist/packages/auth-vault/src/db.d.ts.map +1 -0
- package/dist/packages/auth-vault/src/db.js +154 -0
- package/dist/packages/auth-vault/src/db.js.map +1 -0
- package/dist/packages/auth-vault/src/index.d.ts +5 -0
- package/dist/packages/auth-vault/src/index.d.ts.map +1 -0
- package/dist/packages/auth-vault/src/index.js +5 -0
- package/dist/packages/auth-vault/src/index.js.map +1 -0
- package/dist/packages/auth-vault/src/types.d.ts +48 -0
- package/dist/packages/auth-vault/src/types.d.ts.map +1 -0
- package/dist/packages/auth-vault/src/types.js +2 -0
- package/dist/packages/auth-vault/src/types.js.map +1 -0
- package/dist/packages/auth-vault/src/vault.d.ts +21 -0
- package/dist/packages/auth-vault/src/vault.d.ts.map +1 -0
- package/dist/packages/auth-vault/src/vault.js +88 -0
- package/dist/packages/auth-vault/src/vault.js.map +1 -0
- package/dist/packages/auth-vault/test/vault.test.d.ts +2 -0
- package/dist/packages/auth-vault/test/vault.test.d.ts.map +1 -0
- package/dist/packages/auth-vault/test/vault.test.js +89 -0
- package/dist/packages/auth-vault/test/vault.test.js.map +1 -0
- package/dist/packages/catalog-projector/src/index.d.ts +3 -0
- package/dist/packages/catalog-projector/src/index.d.ts.map +1 -0
- package/dist/packages/catalog-projector/src/index.js +3 -0
- package/dist/packages/catalog-projector/src/index.js.map +1 -0
- package/dist/packages/catalog-projector/src/projector.d.ts +28 -0
- package/dist/packages/catalog-projector/src/projector.d.ts.map +1 -0
- package/dist/packages/catalog-projector/src/projector.js +85 -0
- package/dist/packages/catalog-projector/src/projector.js.map +1 -0
- package/dist/packages/catalog-projector/src/types.d.ts +33 -0
- package/dist/packages/catalog-projector/src/types.d.ts.map +1 -0
- package/dist/packages/catalog-projector/src/types.js +2 -0
- package/dist/packages/catalog-projector/src/types.js.map +1 -0
- package/dist/packages/catalog-projector/test/catalog.test.d.ts +2 -0
- package/dist/packages/catalog-projector/test/catalog.test.d.ts.map +1 -0
- package/dist/packages/catalog-projector/test/catalog.test.js +41 -0
- package/dist/packages/catalog-projector/test/catalog.test.js.map +1 -0
- package/dist/packages/config-parser/src/index.d.ts +5 -0
- package/dist/packages/config-parser/src/index.d.ts.map +1 -0
- package/dist/packages/config-parser/src/index.js +5 -0
- package/dist/packages/config-parser/src/index.js.map +1 -0
- package/dist/packages/config-parser/src/manifest.d.ts +3 -0
- package/dist/packages/config-parser/src/manifest.d.ts.map +1 -0
- package/dist/packages/config-parser/src/manifest.js +33 -0
- package/dist/packages/config-parser/src/manifest.js.map +1 -0
- package/dist/packages/config-parser/src/parser.d.ts +9 -0
- package/dist/packages/config-parser/src/parser.d.ts.map +1 -0
- package/dist/packages/config-parser/src/parser.js +69 -0
- package/dist/packages/config-parser/src/parser.js.map +1 -0
- package/dist/packages/config-parser/src/sanitizer.d.ts +7 -0
- package/dist/packages/config-parser/src/sanitizer.d.ts.map +1 -0
- package/dist/packages/config-parser/src/sanitizer.js +40 -0
- package/dist/packages/config-parser/src/sanitizer.js.map +1 -0
- package/dist/packages/config-parser/src/types.d.ts +47 -0
- package/dist/packages/config-parser/src/types.d.ts.map +1 -0
- package/dist/packages/config-parser/src/types.js +2 -0
- package/dist/packages/config-parser/src/types.js.map +1 -0
- package/dist/packages/config-parser/test/parser.test.d.ts +2 -0
- package/dist/packages/config-parser/test/parser.test.d.ts.map +1 -0
- package/dist/packages/config-parser/test/parser.test.js +35 -0
- package/dist/packages/config-parser/test/parser.test.js.map +1 -0
- package/dist/packages/policy-engine/src/engine.d.ts +12 -0
- package/dist/packages/policy-engine/src/engine.d.ts.map +1 -0
- package/dist/packages/policy-engine/src/engine.js +127 -0
- package/dist/packages/policy-engine/src/engine.js.map +1 -0
- package/dist/packages/policy-engine/src/index.d.ts +3 -0
- package/dist/packages/policy-engine/src/index.d.ts.map +1 -0
- package/dist/packages/policy-engine/src/index.js +3 -0
- package/dist/packages/policy-engine/src/index.js.map +1 -0
- package/dist/packages/policy-engine/src/types.d.ts +33 -0
- package/dist/packages/policy-engine/src/types.d.ts.map +1 -0
- package/dist/packages/policy-engine/src/types.js +2 -0
- package/dist/packages/policy-engine/src/types.js.map +1 -0
- package/dist/packages/policy-engine/test/policy.test.d.ts +2 -0
- package/dist/packages/policy-engine/test/policy.test.d.ts.map +1 -0
- package/dist/packages/policy-engine/test/policy.test.js +48 -0
- package/dist/packages/policy-engine/test/policy.test.js.map +1 -0
- package/dist/packages/registry-core/src/index.d.ts +3 -0
- package/dist/packages/registry-core/src/index.d.ts.map +1 -0
- package/dist/packages/registry-core/src/index.js +3 -0
- package/dist/packages/registry-core/src/index.js.map +1 -0
- package/dist/packages/registry-core/src/registry.d.ts +20 -0
- package/dist/packages/registry-core/src/registry.d.ts.map +1 -0
- package/dist/packages/registry-core/src/registry.js +65 -0
- package/dist/packages/registry-core/src/registry.js.map +1 -0
- package/dist/packages/registry-core/src/types.d.ts +26 -0
- package/dist/packages/registry-core/src/types.d.ts.map +1 -0
- package/dist/packages/registry-core/src/types.js +2 -0
- package/dist/packages/registry-core/src/types.js.map +1 -0
- package/dist/packages/registry-core/test/registry.test.d.ts +2 -0
- package/dist/packages/registry-core/test/registry.test.d.ts.map +1 -0
- package/dist/packages/registry-core/test/registry.test.js +25 -0
- package/dist/packages/registry-core/test/registry.test.js.map +1 -0
- package/dist/packages/sandbox-runtime/src/executor.d.ts +13 -0
- package/dist/packages/sandbox-runtime/src/executor.d.ts.map +1 -0
- package/dist/packages/sandbox-runtime/src/executor.js +84 -0
- package/dist/packages/sandbox-runtime/src/executor.js.map +1 -0
- package/dist/packages/sandbox-runtime/src/index.d.ts +4 -0
- package/dist/packages/sandbox-runtime/src/index.d.ts.map +1 -0
- package/dist/packages/sandbox-runtime/src/index.js +4 -0
- package/dist/packages/sandbox-runtime/src/index.js.map +1 -0
- package/dist/packages/sandbox-runtime/src/profiles.d.ts +4 -0
- package/dist/packages/sandbox-runtime/src/profiles.d.ts.map +1 -0
- package/dist/packages/sandbox-runtime/src/profiles.js +66 -0
- package/dist/packages/sandbox-runtime/src/profiles.js.map +1 -0
- package/dist/packages/sandbox-runtime/src/types.d.ts +24 -0
- package/dist/packages/sandbox-runtime/src/types.d.ts.map +1 -0
- package/dist/packages/sandbox-runtime/src/types.js +2 -0
- package/dist/packages/sandbox-runtime/src/types.js.map +1 -0
- package/dist/packages/sandbox-runtime/test/sandbox.test.d.ts +2 -0
- package/dist/packages/sandbox-runtime/test/sandbox.test.d.ts.map +1 -0
- package/dist/packages/sandbox-runtime/test/sandbox.test.js +30 -0
- package/dist/packages/sandbox-runtime/test/sandbox.test.js.map +1 -0
- package/dist/packages/transport-bridge/src/bridge.d.ts +30 -0
- package/dist/packages/transport-bridge/src/bridge.d.ts.map +1 -0
- package/dist/packages/transport-bridge/src/bridge.js +60 -0
- package/dist/packages/transport-bridge/src/bridge.js.map +1 -0
- package/dist/packages/transport-bridge/src/http-adapter.d.ts +30 -0
- package/dist/packages/transport-bridge/src/http-adapter.d.ts.map +1 -0
- package/dist/packages/transport-bridge/src/http-adapter.js +61 -0
- package/dist/packages/transport-bridge/src/http-adapter.js.map +1 -0
- package/dist/packages/transport-bridge/src/index.d.ts +5 -0
- package/dist/packages/transport-bridge/src/index.d.ts.map +1 -0
- package/dist/packages/transport-bridge/src/index.js +5 -0
- package/dist/packages/transport-bridge/src/index.js.map +1 -0
- package/dist/packages/transport-bridge/src/stdio-adapter.d.ts +36 -0
- package/dist/packages/transport-bridge/src/stdio-adapter.d.ts.map +1 -0
- package/dist/packages/transport-bridge/src/stdio-adapter.js +100 -0
- package/dist/packages/transport-bridge/src/stdio-adapter.js.map +1 -0
- package/dist/packages/transport-bridge/src/types.d.ts +35 -0
- package/dist/packages/transport-bridge/src/types.d.ts.map +1 -0
- package/dist/packages/transport-bridge/src/types.js +2 -0
- package/dist/packages/transport-bridge/src/types.js.map +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { describe, it, after } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { existsSync, unlinkSync } from 'node:fs';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { AuthVault } from '../src/vault.js';
|
|
7
|
+
import { deriveKey, encryptSecret, decryptSecret } from '../src/crypto.js';
|
|
8
|
+
describe('Auth Vault (SQLite3MultipleCiphers & SQLCipher Engine)', () => {
|
|
9
|
+
const testDbFile = join(tmpdir(), `acr_test_vault_${Date.now()}.db`);
|
|
10
|
+
after(() => {
|
|
11
|
+
if (existsSync(testDbFile)) {
|
|
12
|
+
try {
|
|
13
|
+
unlinkSync(testDbFile);
|
|
14
|
+
}
|
|
15
|
+
catch { }
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
it('1. should encrypt and decrypt across AES-256-GCM, ChaCha20-Poly1305, and SQLCipher-v4', () => {
|
|
19
|
+
const keys = deriveKey('super-master-key-007', 'test-salt-123');
|
|
20
|
+
// AES-256-GCM
|
|
21
|
+
const gcmPayload = encryptSecret('secret-gcm-data', keys, 'aes-256-gcm');
|
|
22
|
+
assert.equal(gcmPayload.algorithm, 'aes-256-gcm');
|
|
23
|
+
assert.equal(decryptSecret(gcmPayload, keys), 'secret-gcm-data');
|
|
24
|
+
// ChaCha20-Poly1305
|
|
25
|
+
const chachaPayload = encryptSecret('secret-chacha-data', keys, 'chacha20-poly1305');
|
|
26
|
+
assert.equal(chachaPayload.algorithm, 'chacha20-poly1305');
|
|
27
|
+
assert.equal(decryptSecret(chachaPayload, keys), 'secret-chacha-data');
|
|
28
|
+
// SQLCipher-v4 (AES-256-CBC + HMAC-SHA512)
|
|
29
|
+
const sqlcipherPayload = encryptSecret('secret-sqlcipher-data', keys, 'sqlcipher-v4');
|
|
30
|
+
assert.equal(sqlcipherPayload.algorithm, 'sqlcipher-v4');
|
|
31
|
+
assert.equal(decryptSecret(sqlcipherPayload, keys), 'secret-sqlcipher-data');
|
|
32
|
+
});
|
|
33
|
+
it('2. should persist secrets to isolated database file and reload across instances', () => {
|
|
34
|
+
const vault1 = new AuthVault({
|
|
35
|
+
dbPath: testDbFile,
|
|
36
|
+
masterSecret: 'vault-master-passphrase-99',
|
|
37
|
+
cipher: 'aes-256-gcm',
|
|
38
|
+
});
|
|
39
|
+
vault1.storeSecret('sec_ref_context7_token', 'context7', 'CONTEXT7_API_KEY', 'dynamic-ctx7-key-value', 'personal', 'chacha20-poly1305');
|
|
40
|
+
vault1.storeSecret('sec_ref_gitee_token', 'gitee-cloud', 'GITEE_TOKEN', 'dynamic-gitee-token-value', 'org', 'sqlcipher-v4');
|
|
41
|
+
assert.ok(existsSync(testDbFile), 'Database file should be created on disk');
|
|
42
|
+
// Reopen with instance 2
|
|
43
|
+
const vault2 = new AuthVault({
|
|
44
|
+
dbPath: testDbFile,
|
|
45
|
+
masterSecret: 'vault-master-passphrase-99',
|
|
46
|
+
});
|
|
47
|
+
assert.equal(vault2.getSecret('sec_ref_context7_token'), 'dynamic-ctx7-key-value');
|
|
48
|
+
assert.equal(vault2.getSecret('sec_ref_gitee_token'), 'dynamic-gitee-token-value');
|
|
49
|
+
});
|
|
50
|
+
it('3. should reject database opening with invalid master key (tamper protection)', () => {
|
|
51
|
+
assert.throws(() => {
|
|
52
|
+
new AuthVault({
|
|
53
|
+
dbPath: testDbFile,
|
|
54
|
+
masterSecret: 'wrong-master-passphrase',
|
|
55
|
+
});
|
|
56
|
+
}, /Database decryption failed/);
|
|
57
|
+
});
|
|
58
|
+
it('4. should rotate master key and re-encrypt all stored database records', () => {
|
|
59
|
+
const vault = new AuthVault({
|
|
60
|
+
dbPath: testDbFile,
|
|
61
|
+
masterSecret: 'vault-master-passphrase-99',
|
|
62
|
+
});
|
|
63
|
+
vault.rotateMasterKey('new-stronger-passphrase-2026');
|
|
64
|
+
// Reopen with new passphrase
|
|
65
|
+
const reloadedVault = new AuthVault({
|
|
66
|
+
dbPath: testDbFile,
|
|
67
|
+
masterSecret: 'new-stronger-passphrase-2026',
|
|
68
|
+
});
|
|
69
|
+
assert.equal(reloadedVault.getSecret('sec_ref_context7_token'), 'dynamic-ctx7-key-value');
|
|
70
|
+
assert.equal(reloadedVault.getSecret('sec_ref_gitee_token'), 'dynamic-gitee-token-value');
|
|
71
|
+
});
|
|
72
|
+
it('5. should enforce domain boundaries on secret resolution', () => {
|
|
73
|
+
const vault = new AuthVault({
|
|
74
|
+
dbPath: testDbFile,
|
|
75
|
+
masterSecret: 'new-stronger-passphrase-2026',
|
|
76
|
+
});
|
|
77
|
+
const envMap = {
|
|
78
|
+
TOKEN: 'sec_ref_gitee_token',
|
|
79
|
+
};
|
|
80
|
+
// Allowed for org domain
|
|
81
|
+
const resolved = vault.resolveSecretRefs(envMap, ['org', 'enterprise']);
|
|
82
|
+
assert.equal(resolved.TOKEN, 'dynamic-gitee-token-value');
|
|
83
|
+
// Rejected if domain not in allowed scope
|
|
84
|
+
assert.throws(() => {
|
|
85
|
+
vault.resolveSecretRefs(envMap, ['personal']);
|
|
86
|
+
}, /Domain violation/);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=vault.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.test.js","sourceRoot":"","sources":["../../../../packages/auth-vault/test/vault.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../packages/catalog-projector/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/catalog-projector/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { PolicyCatalog, ProjectedCatalog, RawCatalog } from './types.js';
|
|
2
|
+
export declare function namespaceTool(serverId: string, originalName: string): string;
|
|
3
|
+
export declare function denamespaceTool(namespacedName: string): {
|
|
4
|
+
serverId: string;
|
|
5
|
+
originalName: string;
|
|
6
|
+
};
|
|
7
|
+
export interface CatalogProjectorOptions {
|
|
8
|
+
isServerEnabled?: (serverId: string) => boolean;
|
|
9
|
+
isToolEnabled?: (toolName: string) => boolean;
|
|
10
|
+
isServerQuarantined?: (serverId: string) => boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare class CatalogProjector {
|
|
13
|
+
private readonly options;
|
|
14
|
+
constructor(options?: CatalogProjectorOptions);
|
|
15
|
+
buildRawCatalog(serverToolMap: Record<string, Array<{
|
|
16
|
+
name: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
inputSchema?: any;
|
|
19
|
+
}>>): RawCatalog;
|
|
20
|
+
buildPolicyCatalog(rawCatalog: RawCatalog): PolicyCatalog;
|
|
21
|
+
projectForCaller(policyCatalog: PolicyCatalog, caller: {
|
|
22
|
+
did: string;
|
|
23
|
+
role: string;
|
|
24
|
+
capabilities?: string[];
|
|
25
|
+
allowedPrefixes?: string[];
|
|
26
|
+
}): ProjectedCatalog;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=projector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projector.d.ts","sourceRoot":"","sources":["../../../../packages/catalog-projector/src/projector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,aAAa,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5F,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAO5E;AAED,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAQlG;AAED,MAAM,WAAW,uBAAuB;IACtC,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAChD,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,mBAAmB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;CACrD;AAED,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,OAAO;IAApC,YAA6B,OAAO,GAAE,uBAA4B,EAAI;IAE/D,eAAe,CACpB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC,GAC9F,UAAU,CAuBZ;IAEM,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,aAAa,CAoB/D;IAEM,gBAAgB,CACrB,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GACzF,gBAAgB,CAwBlB;CACF"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export function namespaceTool(serverId, originalName) {
|
|
2
|
+
// If already namespaced, don't duplicate
|
|
3
|
+
if (originalName.startsWith(`${serverId}__`)) {
|
|
4
|
+
return originalName;
|
|
5
|
+
}
|
|
6
|
+
const cleanServer = serverId.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
7
|
+
return `${cleanServer}__${originalName}`;
|
|
8
|
+
}
|
|
9
|
+
export function denamespaceTool(namespacedName) {
|
|
10
|
+
const parts = namespacedName.split('__');
|
|
11
|
+
if (parts.length < 2) {
|
|
12
|
+
return { serverId: 'default', originalName: namespacedName };
|
|
13
|
+
}
|
|
14
|
+
const serverId = parts[0];
|
|
15
|
+
const originalName = parts.slice(1).join('__');
|
|
16
|
+
return { serverId, originalName };
|
|
17
|
+
}
|
|
18
|
+
export class CatalogProjector {
|
|
19
|
+
options;
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
this.options = options;
|
|
22
|
+
}
|
|
23
|
+
buildRawCatalog(serverToolMap) {
|
|
24
|
+
const tools = [];
|
|
25
|
+
const serverCounts = {};
|
|
26
|
+
for (const [serverId, rawTools] of Object.entries(serverToolMap)) {
|
|
27
|
+
serverCounts[serverId] = rawTools.length;
|
|
28
|
+
for (const t of rawTools) {
|
|
29
|
+
tools.push({
|
|
30
|
+
name: namespaceTool(serverId, t.name),
|
|
31
|
+
originalName: t.name,
|
|
32
|
+
serverId,
|
|
33
|
+
description: t.description || `Tool ${t.name} from server ${serverId}`,
|
|
34
|
+
inputSchema: t.inputSchema || { type: 'object' },
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
tools,
|
|
40
|
+
totalDiscovered: tools.length,
|
|
41
|
+
serverCounts,
|
|
42
|
+
generatedAt: new Date().toISOString(),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
buildPolicyCatalog(rawCatalog) {
|
|
46
|
+
const isServerEnabled = this.options.isServerEnabled ?? (() => true);
|
|
47
|
+
const isToolEnabled = this.options.isToolEnabled ?? (() => true);
|
|
48
|
+
const isServerQuarantined = this.options.isServerQuarantined ?? (() => false);
|
|
49
|
+
const filtered = [];
|
|
50
|
+
for (const tool of rawCatalog.tools) {
|
|
51
|
+
if (!isServerEnabled(tool.serverId))
|
|
52
|
+
continue;
|
|
53
|
+
if (isServerQuarantined(tool.serverId))
|
|
54
|
+
continue;
|
|
55
|
+
if (!isToolEnabled(tool.name))
|
|
56
|
+
continue;
|
|
57
|
+
filtered.push(tool);
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
tools: filtered,
|
|
61
|
+
totalPolicyAllowed: filtered.length,
|
|
62
|
+
totalFiltered: rawCatalog.totalDiscovered - filtered.length,
|
|
63
|
+
generatedAt: new Date().toISOString(),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
projectForCaller(policyCatalog, caller) {
|
|
67
|
+
let visible = policyCatalog.tools;
|
|
68
|
+
// Filter by allowed prefixes if configured
|
|
69
|
+
if (caller.allowedPrefixes && caller.allowedPrefixes.length > 0) {
|
|
70
|
+
visible = visible.filter((t) => caller.allowedPrefixes.some((prefix) => t.serverId === prefix || t.name.startsWith(`${prefix}__`)));
|
|
71
|
+
}
|
|
72
|
+
// Role-based filtering: guests only see read-only tools
|
|
73
|
+
if (caller.role === 'guest') {
|
|
74
|
+
visible = visible.filter((t) => /get|list|read|inspect|search|find|status/i.test(t.originalName));
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
callerDid: caller.did,
|
|
78
|
+
role: caller.role,
|
|
79
|
+
tools: visible,
|
|
80
|
+
totalVisible: visible.length,
|
|
81
|
+
generatedAt: new Date().toISOString(),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=projector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projector.js","sourceRoot":"","sources":["../../../../packages/catalog-projector/src/projector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface McpToolDefinition {
|
|
2
|
+
name: string;
|
|
3
|
+
originalName: string;
|
|
4
|
+
serverId: string;
|
|
5
|
+
description: string;
|
|
6
|
+
inputSchema: {
|
|
7
|
+
type: 'object';
|
|
8
|
+
properties?: Record<string, unknown>;
|
|
9
|
+
required?: string[];
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
};
|
|
12
|
+
tags?: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface RawCatalog {
|
|
15
|
+
tools: McpToolDefinition[];
|
|
16
|
+
totalDiscovered: number;
|
|
17
|
+
serverCounts: Record<string, number>;
|
|
18
|
+
generatedAt: string;
|
|
19
|
+
}
|
|
20
|
+
export interface PolicyCatalog {
|
|
21
|
+
tools: McpToolDefinition[];
|
|
22
|
+
totalPolicyAllowed: number;
|
|
23
|
+
totalFiltered: number;
|
|
24
|
+
generatedAt: string;
|
|
25
|
+
}
|
|
26
|
+
export interface ProjectedCatalog {
|
|
27
|
+
callerDid: string;
|
|
28
|
+
role: string;
|
|
29
|
+
tools: McpToolDefinition[];
|
|
30
|
+
totalVisible: number;
|
|
31
|
+
generatedAt: string;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../packages/catalog-projector/src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../packages/catalog-projector/src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.test.d.ts","sourceRoot":"","sources":["../../../../packages/catalog-projector/test/catalog.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { CatalogProjector, namespaceTool, denamespaceTool } from '../src/index.js';
|
|
4
|
+
describe('Catalog Projector (3-Tier Catalog Pipeline)', () => {
|
|
5
|
+
it('should namespace and denamespace tool identifiers deterministically', () => {
|
|
6
|
+
const ns = namespaceTool('gitee-server', 'create_issue');
|
|
7
|
+
assert.equal(ns, 'gitee-server__create_issue');
|
|
8
|
+
const { serverId, originalName } = denamespaceTool(ns);
|
|
9
|
+
assert.equal(serverId, 'gitee-server');
|
|
10
|
+
assert.equal(originalName, 'create_issue');
|
|
11
|
+
});
|
|
12
|
+
it('should transform Raw -> Policy -> Projected catalog accurately', () => {
|
|
13
|
+
const rawToolsMap = {
|
|
14
|
+
github: [
|
|
15
|
+
{ name: 'list_repos', description: 'List repositories' },
|
|
16
|
+
{ name: 'delete_repo', description: 'Delete repository' },
|
|
17
|
+
],
|
|
18
|
+
internal_db: [
|
|
19
|
+
{ name: 'read_metrics', description: 'Read system metrics' }
|
|
20
|
+
]
|
|
21
|
+
};
|
|
22
|
+
const projector = new CatalogProjector({
|
|
23
|
+
isServerEnabled: (s) => s === 'github' || s === 'internal_db',
|
|
24
|
+
isServerQuarantined: () => false,
|
|
25
|
+
isToolEnabled: (t) => t !== 'github__delete_repo'
|
|
26
|
+
});
|
|
27
|
+
const raw = projector.buildRawCatalog(rawToolsMap);
|
|
28
|
+
assert.equal(raw.totalDiscovered, 3);
|
|
29
|
+
const policy = projector.buildPolicyCatalog(raw);
|
|
30
|
+
assert.equal(policy.totalPolicyAllowed, 2);
|
|
31
|
+
assert.equal(policy.totalFiltered, 1);
|
|
32
|
+
assert.ok(policy.tools.every(t => t.name !== 'github__delete_repo'));
|
|
33
|
+
const projected = projector.projectForCaller(policy, {
|
|
34
|
+
did: 'did:key:agent-readonly',
|
|
35
|
+
role: 'guest'
|
|
36
|
+
});
|
|
37
|
+
// Guest should only see read/list tools
|
|
38
|
+
assert.equal(projected.totalVisible, 2);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=catalog.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.test.js","sourceRoot":"","sources":["../../../../packages/catalog-projector/test/catalog.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEnF,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;IAC3D,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,EAAE,GAAG,aAAa,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;QACzD,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,4BAA4B,CAAC,CAAC;QAE/C,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QACvD,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,WAAW,GAAG;YAClB,MAAM,EAAE;gBACN,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,mBAAmB,EAAE;gBACxD,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,EAAE;aAC1D;YACD,WAAW,EAAE;gBACX,EAAE,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE,qBAAqB,EAAE;aAC7D;SACF,CAAC;QAEF,MAAM,SAAS,GAAG,IAAI,gBAAgB,CAAC;YACrC,eAAe,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,aAAa;YAC7D,mBAAmB,EAAE,GAAG,EAAE,CAAC,KAAK;YAChC,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,qBAAqB;SAClD,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,SAAS,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;QAErC,MAAM,MAAM,GAAG,SAAS,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,qBAAqB,CAAC,CAAC,CAAC;QAErE,MAAM,SAAS,GAAG,SAAS,CAAC,gBAAgB,CAAC,MAAM,EAAE;YACnD,GAAG,EAAE,wBAAwB;YAC7B,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;QAEH,wCAAwC;QACxC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../packages/config-parser/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/config-parser/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../../packages/config-parser/src/manifest.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAuB,MAAM,YAAY,CAAC;AAGhF,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,GAAG,YAAY,EAC5B,MAAM,GAAE,UAAU,GAAG,KAAK,GAAG,YAAY,GAAG,WAAwB,GACnE,eAAe,CAkCjB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { parseAndSanitizeServer, parseRawConfig } from './parser.js';
|
|
3
|
+
export function compileInstallManifest(input, domain = 'personal') {
|
|
4
|
+
const raw = parseRawConfig(input);
|
|
5
|
+
const mcpServers = raw.mcpServers ?? {};
|
|
6
|
+
const servers = [];
|
|
7
|
+
let totalSecretRefs = 0;
|
|
8
|
+
for (const [serverId, config] of Object.entries(mcpServers)) {
|
|
9
|
+
const sanitized = parseAndSanitizeServer(serverId, config, domain);
|
|
10
|
+
servers.push(sanitized);
|
|
11
|
+
totalSecretRefs += sanitized.secretRefs.length;
|
|
12
|
+
}
|
|
13
|
+
// Deterministic canonical payload for SHA-256 fingerprint
|
|
14
|
+
const canonicalPayload = JSON.stringify({
|
|
15
|
+
v: '1.0.0',
|
|
16
|
+
servers: servers.map((s) => ({
|
|
17
|
+
id: s.serverId,
|
|
18
|
+
transport: s.transport,
|
|
19
|
+
stdio: s.stdioSpec,
|
|
20
|
+
remote: s.remoteSpec,
|
|
21
|
+
})),
|
|
22
|
+
});
|
|
23
|
+
const fingerprintSha256 = createHash('sha256').update(canonicalPayload).digest('hex');
|
|
24
|
+
return {
|
|
25
|
+
manifestVersion: '1.0.0',
|
|
26
|
+
generatedAt: new Date().toISOString(),
|
|
27
|
+
fingerprintSha256,
|
|
28
|
+
servers,
|
|
29
|
+
totalServers: servers.length,
|
|
30
|
+
totalSecretRefs,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../../packages/config-parser/src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAErE,MAAM,UAAU,sBAAsB,CACpC,KAA4B,EAC5B,MAAM,GAAoD,UAAU;IAEpE,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC;IAExC,MAAM,OAAO,GAA0B,EAAE,CAAC;IAC1C,IAAI,eAAe,GAAG,CAAC,CAAC;IAExB,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5D,MAAM,SAAS,GAAG,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxB,eAAe,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;IACjD,CAAC;IAED,0DAA0D;IAC1D,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC;QACtC,CAAC,EAAE,OAAO;QACV,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3B,EAAE,EAAE,CAAC,CAAC,QAAQ;YACd,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,KAAK,EAAE,CAAC,CAAC,SAAS;YAClB,MAAM,EAAE,CAAC,CAAC,UAAU;SACrB,CAAC,CAAC;KACJ,CAAC,CAAC;IAEH,MAAM,iBAAiB,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEtF,OAAO;QACL,eAAe,EAAE,OAAO;QACxB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,iBAAiB;QACjB,OAAO;QACP,YAAY,EAAE,OAAO,CAAC,MAAM;QAC5B,eAAe;KAChB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { RawMcpConfig, RawServerConfig, SanitizedServerSpec, TransportType } from './types.js';
|
|
2
|
+
export declare class ConfigParseError extends Error {
|
|
3
|
+
readonly details?: unknown;
|
|
4
|
+
constructor(message: string, details?: unknown);
|
|
5
|
+
}
|
|
6
|
+
export declare function parseRawConfig(input: string | RawMcpConfig): RawMcpConfig;
|
|
7
|
+
export declare function deduceTransport(config: RawServerConfig): TransportType;
|
|
8
|
+
export declare function parseAndSanitizeServer(serverId: string, config: RawServerConfig, domain?: 'personal' | 'org' | 'enterprise' | 'ephemeral'): SanitizedServerSpec;
|
|
9
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../../packages/config-parser/src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG/F,qBAAa,gBAAiB,SAAQ,KAAK;aACI,OAAO,CAAC,EAAE,OAAO;IAA9D,YAAY,OAAO,EAAE,MAAM,EAAkB,OAAO,CAAC,EAAE,OAAO,EAG7D;CACF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,YAAY,CASzE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,aAAa,CAWtE;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,eAAe,EACvB,MAAM,GAAE,UAAU,GAAG,KAAK,GAAG,YAAY,GAAG,WAAwB,GACnE,mBAAmB,CAyCrB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { sanitizeEnvAndHeaders } from './sanitizer.js';
|
|
2
|
+
export class ConfigParseError extends Error {
|
|
3
|
+
details;
|
|
4
|
+
constructor(message, details) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.details = details;
|
|
7
|
+
this.name = 'ConfigParseError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export function parseRawConfig(input) {
|
|
11
|
+
if (typeof input === 'string') {
|
|
12
|
+
try {
|
|
13
|
+
return JSON.parse(input);
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
throw new ConfigParseError(`Invalid JSON syntax in MCP configuration: ${err.message}`, err);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return input;
|
|
20
|
+
}
|
|
21
|
+
export function deduceTransport(config) {
|
|
22
|
+
if ('command' in config && typeof config.command === 'string') {
|
|
23
|
+
return 'stdio';
|
|
24
|
+
}
|
|
25
|
+
if ('url' in config && typeof config.url === 'string') {
|
|
26
|
+
if (config.transport === 'streamable_http' || config.url.includes('/mcp')) {
|
|
27
|
+
return 'streamable_http';
|
|
28
|
+
}
|
|
29
|
+
return 'sse';
|
|
30
|
+
}
|
|
31
|
+
throw new ConfigParseError('Unable to deduce transport: entry must contain either "command" or "url".', config);
|
|
32
|
+
}
|
|
33
|
+
export function parseAndSanitizeServer(serverId, config, domain = 'personal') {
|
|
34
|
+
const transport = deduceTransport(config);
|
|
35
|
+
if (transport === 'stdio') {
|
|
36
|
+
const stdioConf = config;
|
|
37
|
+
if (!stdioConf.command || typeof stdioConf.command !== 'string') {
|
|
38
|
+
throw new ConfigParseError(`Server "${serverId}" has missing or invalid "command" field.`);
|
|
39
|
+
}
|
|
40
|
+
const { sanitized, secretRefs } = sanitizeEnvAndHeaders(serverId, stdioConf.env, domain);
|
|
41
|
+
return {
|
|
42
|
+
serverId,
|
|
43
|
+
displayName: serverId,
|
|
44
|
+
transport: 'stdio',
|
|
45
|
+
stdioSpec: {
|
|
46
|
+
command: stdioConf.command,
|
|
47
|
+
args: Array.isArray(stdioConf.args) ? stdioConf.args : [],
|
|
48
|
+
envRefs: sanitized,
|
|
49
|
+
},
|
|
50
|
+
secretRefs,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const remoteConf = config;
|
|
54
|
+
if (!remoteConf.url || typeof remoteConf.url !== 'string') {
|
|
55
|
+
throw new ConfigParseError(`Server "${serverId}" has missing or invalid "url" field.`);
|
|
56
|
+
}
|
|
57
|
+
const { sanitized, secretRefs } = sanitizeEnvAndHeaders(serverId, remoteConf.headers, domain);
|
|
58
|
+
return {
|
|
59
|
+
serverId,
|
|
60
|
+
displayName: serverId,
|
|
61
|
+
transport,
|
|
62
|
+
remoteSpec: {
|
|
63
|
+
url: remoteConf.url,
|
|
64
|
+
headerRefs: sanitized,
|
|
65
|
+
},
|
|
66
|
+
secretRefs,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../../packages/config-parser/src/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SecretRef } from './types.js';
|
|
2
|
+
export declare function isSensitiveKey(key: string): boolean;
|
|
3
|
+
export declare function sanitizeEnvAndHeaders(serverId: string, envOrHeaders: Record<string, string> | undefined, defaultDomain?: 'personal' | 'org' | 'enterprise' | 'ephemeral'): {
|
|
4
|
+
sanitized: Record<string, string>;
|
|
5
|
+
secretRefs: SecretRef[];
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=sanitizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../../../../packages/config-parser/src/sanitizer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAavC,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAChD,aAAa,GAAE,UAAU,GAAG,KAAK,GAAG,YAAY,GAAG,WAAwB,GAC1E;IAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,UAAU,EAAE,SAAS,EAAE,CAAA;CAAE,CA0BhE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
const SENSITIVE_KEY_PATTERNS = [
|
|
3
|
+
/token/i,
|
|
4
|
+
/secret/i,
|
|
5
|
+
/key/i,
|
|
6
|
+
/password/i,
|
|
7
|
+
/auth/i,
|
|
8
|
+
/bearer/i,
|
|
9
|
+
/credential/i,
|
|
10
|
+
/api[_-]?key/i,
|
|
11
|
+
];
|
|
12
|
+
export function isSensitiveKey(key) {
|
|
13
|
+
return SENSITIVE_KEY_PATTERNS.some((pattern) => pattern.test(key));
|
|
14
|
+
}
|
|
15
|
+
export function sanitizeEnvAndHeaders(serverId, envOrHeaders, defaultDomain = 'personal') {
|
|
16
|
+
if (!envOrHeaders) {
|
|
17
|
+
return { sanitized: {}, secretRefs: [] };
|
|
18
|
+
}
|
|
19
|
+
const sanitized = {};
|
|
20
|
+
const secretRefs = [];
|
|
21
|
+
for (const [k, v] of Object.entries(envOrHeaders)) {
|
|
22
|
+
if (isSensitiveKey(k) || (typeof v === 'string' && v.length > 24 && /^[a-zA-Z0-9_\-\.]+$/.test(v))) {
|
|
23
|
+
const hash = createHash('sha256').update(`${serverId}:${k}:${v}`).digest('hex').slice(0, 12);
|
|
24
|
+
const refId = `sec_ref_${hash}`;
|
|
25
|
+
sanitized[k] = refId;
|
|
26
|
+
secretRefs.push({
|
|
27
|
+
refId,
|
|
28
|
+
key: k,
|
|
29
|
+
serverId,
|
|
30
|
+
domain: defaultDomain,
|
|
31
|
+
originalValue: v,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
sanitized[k] = v;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { sanitized, secretRefs };
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=sanitizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitizer.js","sourceRoot":"","sources":["../../../../packages/config-parser/src/sanitizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAe,MAAM,aAAa,CAAC;AAGtD,MAAM,sBAAsB,GAAG;IAC7B,QAAQ;IACR,SAAS;IACT,MAAM;IACN,WAAW;IACX,OAAO;IACP,SAAS;IACT,aAAa;IACb,cAAc;CACf,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,sBAAsB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,QAAgB,EAChB,YAAgD,EAChD,aAAa,GAAoD,UAAU;IAE3E,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC3C,CAAC;IAED,MAAM,SAAS,GAA2B,EAAE,CAAC;IAC7C,MAAM,UAAU,GAAgB,EAAE,CAAC;IAEnC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QAClD,IAAI,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,IAAI,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACnG,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,QAAQ,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7F,MAAM,KAAK,GAAG,WAAW,IAAI,EAAE,CAAC;YAChC,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;YACrB,UAAU,CAAC,IAAI,CAAC;gBACd,KAAK;gBACL,GAAG,EAAE,CAAC;gBACN,QAAQ;gBACR,MAAM,EAAE,aAAa;gBACrB,aAAa,EAAE,CAAC;aACjB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export type TransportType = 'stdio' | 'sse' | 'streamable_http';
|
|
2
|
+
export interface StdioServerConfig {
|
|
3
|
+
command: string;
|
|
4
|
+
args?: string[];
|
|
5
|
+
env?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
export interface RemoteServerConfig {
|
|
8
|
+
url: string;
|
|
9
|
+
headers?: Record<string, string>;
|
|
10
|
+
transport?: 'sse' | 'streamable_http';
|
|
11
|
+
}
|
|
12
|
+
export type RawServerConfig = StdioServerConfig | RemoteServerConfig;
|
|
13
|
+
export interface RawMcpConfig {
|
|
14
|
+
mcpServers?: Record<string, RawServerConfig>;
|
|
15
|
+
$schema?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface SecretRef {
|
|
18
|
+
refId: string;
|
|
19
|
+
key: string;
|
|
20
|
+
serverId: string;
|
|
21
|
+
domain: 'personal' | 'org' | 'enterprise' | 'ephemeral';
|
|
22
|
+
originalValue: string;
|
|
23
|
+
}
|
|
24
|
+
export interface SanitizedServerSpec {
|
|
25
|
+
serverId: string;
|
|
26
|
+
displayName: string;
|
|
27
|
+
transport: TransportType;
|
|
28
|
+
stdioSpec?: {
|
|
29
|
+
command: string;
|
|
30
|
+
args: string[];
|
|
31
|
+
envRefs: Record<string, string>;
|
|
32
|
+
};
|
|
33
|
+
remoteSpec?: {
|
|
34
|
+
url: string;
|
|
35
|
+
headerRefs: Record<string, string>;
|
|
36
|
+
};
|
|
37
|
+
secretRefs: SecretRef[];
|
|
38
|
+
}
|
|
39
|
+
export interface InstallManifest {
|
|
40
|
+
manifestVersion: string;
|
|
41
|
+
generatedAt: string;
|
|
42
|
+
fingerprintSha256: string;
|
|
43
|
+
servers: SanitizedServerSpec[];
|
|
44
|
+
totalServers: number;
|
|
45
|
+
totalSecretRefs: number;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../packages/config-parser/src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,KAAK,GAAG,iBAAiB,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,KAAK,GAAG,iBAAiB,CAAC;CACvC;AAED,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,kBAAkB,CAAC;AAErE,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,UAAU,GAAG,KAAK,GAAG,YAAY,GAAG,WAAW,CAAC;IACxD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,aAAa,CAAC;IACzB,SAAS,CAAC,EAAE;QACV,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACjC,CAAC;IACF,UAAU,CAAC,EAAE;QACX,GAAG,EAAE,MAAM,CAAC;QACZ,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACpC,CAAC;IACF,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../packages/config-parser/src/types.ts"],"names":[],"mappings":""}
|