@databasin/mcp-client 0.1.0 → 0.2.0-beta.1
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 +128 -61
- package/dist/abort.d.ts +5 -0
- package/dist/abort.d.ts.map +1 -0
- package/dist/abort.js +25 -0
- package/dist/abort.js.map +1 -0
- package/dist/api-client.d.ts +49 -34
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +142 -145
- package/dist/api-client.js.map +1 -1
- package/dist/api-contract.d.ts +59 -0
- package/dist/api-contract.d.ts.map +1 -0
- package/dist/api-contract.js +47 -0
- package/dist/api-contract.js.map +1 -0
- package/dist/api-profile.d.ts +5 -0
- package/dist/api-profile.d.ts.map +1 -0
- package/dist/api-profile.js +38 -0
- package/dist/api-profile.js.map +1 -0
- package/dist/api-request.d.ts +27 -0
- package/dist/api-request.d.ts.map +1 -0
- package/dist/api-request.js +147 -0
- package/dist/api-request.js.map +1 -0
- package/dist/api-response.d.ts +9 -0
- package/dist/api-response.d.ts.map +1 -0
- package/dist/api-response.js +206 -0
- package/dist/api-response.js.map +1 -0
- package/dist/auth.d.ts +22 -11
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +71 -71
- package/dist/auth.js.map +1 -1
- package/dist/browser.d.ts +20 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +19 -17
- package/dist/browser.js.map +1 -1
- package/dist/cli.d.ts +31 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +147 -67
- package/dist/cli.js.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/correlation.d.ts +6 -0
- package/dist/correlation.d.ts.map +1 -0
- package/dist/correlation.js +15 -0
- package/dist/correlation.js.map +1 -0
- package/dist/credential-store.d.ts +21 -0
- package/dist/credential-store.d.ts.map +1 -0
- package/dist/credential-store.js +46 -0
- package/dist/credential-store.js.map +1 -0
- package/dist/errors.d.ts +17 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +24 -6
- package/dist/errors.js.map +1 -1
- package/dist/login-url.d.ts +18 -0
- package/dist/login-url.d.ts.map +1 -0
- package/dist/login-url.js +82 -0
- package/dist/login-url.js.map +1 -0
- package/dist/safety.d.ts +4 -0
- package/dist/safety.d.ts.map +1 -1
- package/dist/safety.js +94 -10
- package/dist/safety.js.map +1 -1
- package/dist/schemas.d.ts +326 -49
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +242 -55
- package/dist/schemas.js.map +1 -1
- package/dist/server.d.ts +2 -4
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +17 -10
- package/dist/server.js.map +1 -1
- package/dist/token-validation.d.ts +5 -0
- package/dist/token-validation.d.ts.map +1 -0
- package/dist/token-validation.js +183 -0
- package/dist/token-validation.js.map +1 -0
- package/dist/tools.d.ts +12 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +286 -75
- package/dist/tools.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +10 -6
- package/dist/mappers.d.ts +0 -56
- package/dist/mappers.d.ts.map +0 -1
- package/dist/mappers.js +0 -171
- package/dist/mappers.js.map +0 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Microsoft-owned device sign-in locations. Entra has changed the
|
|
3
|
+
* verification URI it returns over time — the original pin of exactly
|
|
4
|
+
* microsoft.com/devicelogin rejected Microsoft's own current response
|
|
5
|
+
* (login.microsoft.com/device, observed 2026-08-26), making sign-in
|
|
6
|
+
* impossible. Every entry is a first-party Microsoft host with its exact
|
|
7
|
+
* expected path; anything else is still rejected, and the returned value is
|
|
8
|
+
* the canonical form, never the raw input.
|
|
9
|
+
*/
|
|
10
|
+
const DEVICE_LOGIN_LOCATIONS = new Map([
|
|
11
|
+
['microsoft.com', new Set(['/devicelogin', '/devicelogin/'])],
|
|
12
|
+
['www.microsoft.com', new Set(['/devicelogin', '/devicelogin/'])],
|
|
13
|
+
['login.microsoft.com', new Set(['/device', '/device/'])]
|
|
14
|
+
]);
|
|
15
|
+
const INTERACTIVE_SUFFIX = '/oauth2/v2.0/authorize';
|
|
16
|
+
export function projectDevicePrompt(response) {
|
|
17
|
+
const verificationUri = validateDeviceLoginUrl(response.verificationUri);
|
|
18
|
+
const userCode = validateUserCode(response.userCode);
|
|
19
|
+
const expiresIn = validateExpiresIn(response.expiresIn);
|
|
20
|
+
return Object.freeze({ userCode, verificationUri, expiresIn });
|
|
21
|
+
}
|
|
22
|
+
export function validateDeviceLoginUrl(value) {
|
|
23
|
+
const url = parseUrl(value);
|
|
24
|
+
assertSafeHttpsUrl(url);
|
|
25
|
+
const paths = DEVICE_LOGIN_LOCATIONS.get(url.hostname);
|
|
26
|
+
if (!paths || !paths.has(url.pathname)) {
|
|
27
|
+
throw new Error('Microsoft returned an unexpected device sign-in URL.');
|
|
28
|
+
}
|
|
29
|
+
if (url.search || url.hash)
|
|
30
|
+
throw new Error('Microsoft returned an unexpected device sign-in URL.');
|
|
31
|
+
return `https://${url.hostname}${url.pathname.replace(/\/$/u, '')}`;
|
|
32
|
+
}
|
|
33
|
+
export function validateInteractiveLoginUrl(rawUrl, profile) {
|
|
34
|
+
const url = parseUrl(rawUrl);
|
|
35
|
+
assertSafeHttpsUrl(url);
|
|
36
|
+
if (url.hash)
|
|
37
|
+
throw new Error('Refusing to open an unexpected OAuth URL.');
|
|
38
|
+
const segments = url.pathname.split('/').filter(Boolean);
|
|
39
|
+
const expectedTenant = profile?.tenantId.toLowerCase();
|
|
40
|
+
const tenant = segments[0]?.toLowerCase();
|
|
41
|
+
const expectedPath = tenant === undefined ? '' : `/${tenant}${INTERACTIVE_SUFFIX}`;
|
|
42
|
+
const validTenant = expectedTenant === undefined ? isUuid(tenant) : tenant === expectedTenant;
|
|
43
|
+
if (url.hostname !== 'login.microsoftonline.com' || !validTenant || url.pathname.toLowerCase() !== expectedPath) {
|
|
44
|
+
throw new Error('Refusing to open an unexpected OAuth URL.');
|
|
45
|
+
}
|
|
46
|
+
if (profile && url.searchParams.get('client_id') !== profile.clientId) {
|
|
47
|
+
throw new Error('Refusing to open an OAuth URL for an unexpected client.');
|
|
48
|
+
}
|
|
49
|
+
return url.toString();
|
|
50
|
+
}
|
|
51
|
+
function parseUrl(value) {
|
|
52
|
+
if (typeof value !== 'string' || value.length > 4_096)
|
|
53
|
+
throw new Error('Microsoft returned an invalid sign-in URL.');
|
|
54
|
+
try {
|
|
55
|
+
return new URL(value);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
throw new Error('Microsoft returned an invalid sign-in URL.');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function assertSafeHttpsUrl(url) {
|
|
62
|
+
if (url.protocol !== 'https:' || url.username || url.password || url.port) {
|
|
63
|
+
throw new Error('Microsoft returned an unsafe sign-in URL.');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function validateUserCode(value) {
|
|
67
|
+
if (typeof value !== 'string' || !/^[A-Z0-9-]{4,32}$/iu.test(value)) {
|
|
68
|
+
throw new Error('Microsoft returned an invalid device sign-in code.');
|
|
69
|
+
}
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
function validateExpiresIn(value) {
|
|
73
|
+
if (typeof value !== 'number' || !Number.isInteger(value) || value < 1 || value > 1_800) {
|
|
74
|
+
throw new Error('Microsoft returned an invalid device sign-in expiry.');
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
function isUuid(value) {
|
|
79
|
+
return value !== undefined
|
|
80
|
+
&& /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu.test(value);
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=login-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login-url.js","sourceRoot":"","sources":["../src/login-url.ts"],"names":[],"mappings":"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"}
|
package/dist/safety.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export declare function isSensitiveKey(key: string): boolean;
|
|
2
|
+
export declare function containsSensitiveMaterial(value: string): boolean;
|
|
3
|
+
export declare function redactSensitiveText(value: string): string;
|
|
4
|
+
export declare function sanitizeOutput(value: unknown): unknown;
|
|
1
5
|
export declare function assertSafeOutput(value: unknown, maxBytes?: number): void;
|
|
2
6
|
export declare function correlationId(): string;
|
|
3
7
|
//# sourceMappingURL=safety.d.ts.map
|
package/dist/safety.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"AA0BA,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAShE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASzD;AAMD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEtD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAAY,GAAG,IAAI,CAM3E;AA8CD,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
|
package/dist/safety.js
CHANGED
|
@@ -1,27 +1,111 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { freshCorrelationId } from './correlation.js';
|
|
2
2
|
import { DataBasinError } from './errors.js';
|
|
3
|
-
const SENSITIVE_KEY = /(?:pass(word)?|secret|token|api[-_]?key|credential|authorization|cookie|webhook|signed[-_]?url|connection[-_]?string|private[-_]?key|client[-_]?secret|keyvault)/iu;
|
|
3
|
+
const SENSITIVE_KEY = /(?:pass(?:word|wd)?|pwd|secret|token|api[-_]?key|credential|authorization|cookie|webhook|signed[-_]?url|connection[-_]?string|private[-_]?key|client[-_]?secret|keyvault)/iu;
|
|
4
|
+
const JWT_SOURCE = String.raw `\beyJ[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}\b`;
|
|
5
|
+
const BEARER_SOURCE = String.raw `\bbearer\s+[a-z0-9._~+/=-]{12,}`;
|
|
6
|
+
const JDBC_SOURCE = String.raw `\bjdbc:[^\s"'<>]+`;
|
|
7
|
+
const DATABASE_URI_SOURCE = String.raw `\b(?:postgres(?:ql)?|mysql|mariadb|mongodb(?:\+srv)?|sqlserver|redis):\/\/[^\s"'<>]+`;
|
|
8
|
+
const PEM_SOURCE = String.raw `-----BEGIN [A-Z0-9 ]*(?:PRIVATE KEY|CERTIFICATE)-----[\s\S]*?-----END [A-Z0-9 ]*(?:PRIVATE KEY|CERTIFICATE)-----`;
|
|
9
|
+
const KEY_VALUE_SOURCE = String.raw `\b(?:password|passwd|pwd|secret|token|access[_-]?token|refresh[_-]?token|id[_-]?token|api[_-]?key|client[_-]?secret)\b\s*[:=]\s*(?:"[^"]*"|'[^']*'|[^\s,;]+)`;
|
|
10
|
+
const JWT = new RegExp(JWT_SOURCE, 'u');
|
|
11
|
+
const BEARER = new RegExp(BEARER_SOURCE, 'iu');
|
|
12
|
+
const JDBC = new RegExp(JDBC_SOURCE, 'iu');
|
|
13
|
+
const DATABASE_URI = new RegExp(DATABASE_URI_SOURCE, 'iu');
|
|
14
|
+
const PEM = new RegExp(PEM_SOURCE, 'u');
|
|
15
|
+
const KEY_VALUE = new RegExp(KEY_VALUE_SOURCE, 'iu');
|
|
16
|
+
const REDACTED_KEY_VALUE = /\b(?:password|passwd|pwd|secret|token|access[_-]?token|refresh[_-]?token|id[_-]?token|api[_-]?key|client[_-]?secret)\b\s*[:=]\s*(?:"\[REDACTED\]"|'\[REDACTED\]'|\[REDACTED\])/giu;
|
|
17
|
+
const DB_LOCATION_FIELD = /\b(?:server|host|data source|database)\s*=/iu;
|
|
18
|
+
const DB_CREDENTIAL_FIELD = /\b(?:password|pwd|user id|uid)\s*=/iu;
|
|
19
|
+
const REDACT_PEM = new RegExp(PEM_SOURCE, 'gu');
|
|
20
|
+
const REDACT_JWT = new RegExp(JWT_SOURCE, 'gu');
|
|
21
|
+
const REDACT_BEARER = new RegExp(BEARER_SOURCE, 'giu');
|
|
22
|
+
const REDACT_JDBC = new RegExp(JDBC_SOURCE, 'giu');
|
|
23
|
+
const REDACT_DATABASE_URI = new RegExp(DATABASE_URI_SOURCE, 'giu');
|
|
24
|
+
const REDACT_KEY_VALUE = new RegExp(KEY_VALUE_SOURCE.replace('(?:password', '(password'), 'giu');
|
|
25
|
+
export function isSensitiveKey(key) {
|
|
26
|
+
return SENSITIVE_KEY.test(key);
|
|
27
|
+
}
|
|
28
|
+
export function containsSensitiveMaterial(value) {
|
|
29
|
+
const candidate = value.replace(REDACTED_KEY_VALUE, '');
|
|
30
|
+
return JWT.test(candidate)
|
|
31
|
+
|| BEARER.test(candidate)
|
|
32
|
+
|| JDBC.test(candidate)
|
|
33
|
+
|| DATABASE_URI.test(candidate)
|
|
34
|
+
|| PEM.test(candidate)
|
|
35
|
+
|| KEY_VALUE.test(candidate)
|
|
36
|
+
|| isDatabaseConnectionString(candidate);
|
|
37
|
+
}
|
|
38
|
+
export function redactSensitiveText(value) {
|
|
39
|
+
if (isDatabaseConnectionString(value))
|
|
40
|
+
return '[REDACTED]';
|
|
41
|
+
return value
|
|
42
|
+
.replace(REDACT_PEM, '[REDACTED]')
|
|
43
|
+
.replace(REDACT_JWT, '[REDACTED]')
|
|
44
|
+
.replace(REDACT_BEARER, 'Bearer [REDACTED]')
|
|
45
|
+
.replace(REDACT_JDBC, '[REDACTED]')
|
|
46
|
+
.replace(REDACT_DATABASE_URI, '[REDACTED]')
|
|
47
|
+
.replace(REDACT_KEY_VALUE, '$1=[REDACTED]');
|
|
48
|
+
}
|
|
49
|
+
function isDatabaseConnectionString(value) {
|
|
50
|
+
return DB_LOCATION_FIELD.test(value) && DB_CREDENTIAL_FIELD.test(value);
|
|
51
|
+
}
|
|
52
|
+
export function sanitizeOutput(value) {
|
|
53
|
+
return sanitize(value);
|
|
54
|
+
}
|
|
4
55
|
export function assertSafeOutput(value, maxBytes = 1_048_576) {
|
|
5
|
-
|
|
6
|
-
|
|
56
|
+
inspect(value);
|
|
57
|
+
const serialized = JSON.stringify(value);
|
|
58
|
+
if (serialized === undefined || Buffer.byteLength(serialized, 'utf8') > maxBytes) {
|
|
7
59
|
throw new DataBasinError('POLICY_DENIED', 'The tool output exceeded the response-size limit.');
|
|
8
60
|
}
|
|
9
61
|
}
|
|
10
|
-
function
|
|
62
|
+
function sanitize(value) {
|
|
63
|
+
if (Array.isArray(value))
|
|
64
|
+
return value.map(sanitize);
|
|
65
|
+
if (typeof value === 'string')
|
|
66
|
+
return redactSensitiveText(value);
|
|
67
|
+
if (!value || typeof value !== 'object')
|
|
68
|
+
return value;
|
|
69
|
+
return sanitizeRecord(value);
|
|
70
|
+
}
|
|
71
|
+
function sanitizeRecord(object) {
|
|
72
|
+
const output = {};
|
|
73
|
+
const fieldName = namedField(object);
|
|
74
|
+
for (const [key, child] of Object.entries(object)) {
|
|
75
|
+
output[key] = shouldRedact(key, fieldName) ? '[REDACTED]' : sanitize(child);
|
|
76
|
+
}
|
|
77
|
+
return output;
|
|
78
|
+
}
|
|
79
|
+
function namedField(object) {
|
|
80
|
+
if (typeof object.name === 'string')
|
|
81
|
+
return object.name;
|
|
82
|
+
return typeof object.key === 'string' ? object.key : undefined;
|
|
83
|
+
}
|
|
84
|
+
function shouldRedact(key, fieldName) {
|
|
85
|
+
if (isSensitiveKey(key))
|
|
86
|
+
return true;
|
|
87
|
+
return key === 'value' && fieldName !== undefined && isSensitiveKey(fieldName);
|
|
88
|
+
}
|
|
89
|
+
function inspect(value) {
|
|
11
90
|
if (Array.isArray(value)) {
|
|
12
|
-
value.forEach(
|
|
91
|
+
value.forEach(inspect);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (typeof value === 'string') {
|
|
95
|
+
if (containsSensitiveMaterial(value))
|
|
96
|
+
throw new DataBasinError('POLICY_DENIED', 'Sensitive material was blocked from tool output.');
|
|
13
97
|
return;
|
|
14
98
|
}
|
|
15
99
|
if (!value || typeof value !== 'object')
|
|
16
100
|
return;
|
|
17
101
|
for (const [key, child] of Object.entries(value)) {
|
|
18
|
-
if (
|
|
19
|
-
throw new DataBasinError('
|
|
102
|
+
if (isSensitiveKey(key) && child !== '[REDACTED]') {
|
|
103
|
+
throw new DataBasinError('POLICY_DENIED', 'Sensitive material was blocked from tool output.');
|
|
20
104
|
}
|
|
21
|
-
|
|
105
|
+
inspect(child);
|
|
22
106
|
}
|
|
23
107
|
}
|
|
24
108
|
export function correlationId() {
|
|
25
|
-
return
|
|
109
|
+
return freshCorrelationId();
|
|
26
110
|
}
|
|
27
111
|
//# sourceMappingURL=safety.js.map
|
package/dist/safety.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safety.js","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"safety.js","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"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"}
|