@databasin/mcp-client 0.1.0 → 0.2.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.
Files changed (86) hide show
  1. package/README.md +132 -61
  2. package/dist/auth-schema.d.ts +23 -0
  3. package/dist/auth-schema.d.ts.map +1 -0
  4. package/dist/auth-schema.js +42 -0
  5. package/dist/auth-schema.js.map +1 -0
  6. package/dist/auth-tools.d.ts +10 -0
  7. package/dist/auth-tools.d.ts.map +1 -0
  8. package/dist/auth-tools.js +60 -0
  9. package/dist/auth-tools.js.map +1 -0
  10. package/dist/auth.d.ts +22 -11
  11. package/dist/auth.d.ts.map +1 -1
  12. package/dist/auth.js +71 -71
  13. package/dist/auth.js.map +1 -1
  14. package/dist/browser.d.ts +20 -1
  15. package/dist/browser.d.ts.map +1 -1
  16. package/dist/browser.js +19 -17
  17. package/dist/browser.js.map +1 -1
  18. package/dist/cli.d.ts +31 -2
  19. package/dist/cli.d.ts.map +1 -1
  20. package/dist/cli.js +148 -67
  21. package/dist/cli.js.map +1 -1
  22. package/dist/config.js +2 -2
  23. package/dist/config.js.map +1 -1
  24. package/dist/correlation.d.ts +6 -0
  25. package/dist/correlation.d.ts.map +1 -0
  26. package/dist/correlation.js +15 -0
  27. package/dist/correlation.js.map +1 -0
  28. package/dist/credential-store.d.ts +21 -0
  29. package/dist/credential-store.d.ts.map +1 -0
  30. package/dist/credential-store.js +46 -0
  31. package/dist/credential-store.js.map +1 -0
  32. package/dist/errors.d.ts +17 -3
  33. package/dist/errors.d.ts.map +1 -1
  34. package/dist/errors.js +24 -6
  35. package/dist/errors.js.map +1 -1
  36. package/dist/index.d.ts +1 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +1 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/login-url.d.ts +18 -0
  41. package/dist/login-url.d.ts.map +1 -0
  42. package/dist/login-url.js +82 -0
  43. package/dist/login-url.js.map +1 -0
  44. package/dist/mcp-endpoint.d.ts +5 -0
  45. package/dist/mcp-endpoint.d.ts.map +1 -0
  46. package/dist/mcp-endpoint.js +22 -0
  47. package/dist/mcp-endpoint.js.map +1 -0
  48. package/dist/proxy-tools.d.ts +5 -0
  49. package/dist/proxy-tools.d.ts.map +1 -0
  50. package/dist/proxy-tools.js +39 -0
  51. package/dist/proxy-tools.js.map +1 -0
  52. package/dist/remote-mcp.d.ts +27 -0
  53. package/dist/remote-mcp.d.ts.map +1 -0
  54. package/dist/remote-mcp.js +70 -0
  55. package/dist/remote-mcp.js.map +1 -0
  56. package/dist/safety.d.ts +4 -0
  57. package/dist/safety.d.ts.map +1 -1
  58. package/dist/safety.js +94 -10
  59. package/dist/safety.js.map +1 -1
  60. package/dist/server.d.ts +4 -6
  61. package/dist/server.d.ts.map +1 -1
  62. package/dist/server.js +32 -15
  63. package/dist/server.js.map +1 -1
  64. package/dist/token-validation.d.ts +5 -0
  65. package/dist/token-validation.d.ts.map +1 -0
  66. package/dist/token-validation.js +183 -0
  67. package/dist/token-validation.js.map +1 -0
  68. package/dist/version.d.ts +1 -1
  69. package/dist/version.js +1 -1
  70. package/package.json +12 -7
  71. package/dist/api-client.d.ts +0 -43
  72. package/dist/api-client.d.ts.map +0 -1
  73. package/dist/api-client.js +0 -154
  74. package/dist/api-client.js.map +0 -1
  75. package/dist/mappers.d.ts +0 -56
  76. package/dist/mappers.d.ts.map +0 -1
  77. package/dist/mappers.js +0 -171
  78. package/dist/mappers.js.map +0 -1
  79. package/dist/schemas.d.ts +0 -154
  80. package/dist/schemas.d.ts.map +0 -1
  81. package/dist/schemas.js +0 -102
  82. package/dist/schemas.js.map +0 -1
  83. package/dist/tools.d.ts +0 -17
  84. package/dist/tools.d.ts.map +0 -1
  85. package/dist/tools.js +0 -117
  86. package/dist/tools.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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"}
@@ -0,0 +1,5 @@
1
+ import { type DataBasinProfile } from './config.js';
2
+ export declare const MCP_ENDPOINT_PATH: "/mcp";
3
+ export declare function mcpEndpointForProfile(profile: DataBasinProfile): URL;
4
+ export declare function assertBuiltInProfile(profile: DataBasinProfile): void;
5
+ //# sourceMappingURL=mcp-endpoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-endpoint.d.ts","sourceRoot":"","sources":["../src/mcp-endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEhE,eAAO,MAAM,iBAAiB,EAAG,MAAe,CAAC;AAEjD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,gBAAgB,GAAG,GAAG,CAOpE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CASpE"}
@@ -0,0 +1,22 @@
1
+ import { getProfile } from './config.js';
2
+ export const MCP_ENDPOINT_PATH = '/mcp';
3
+ export function mcpEndpointForProfile(profile) {
4
+ assertBuiltInProfile(profile);
5
+ const endpoint = new URL(profile.apiBaseUrl);
6
+ endpoint.pathname = MCP_ENDPOINT_PATH;
7
+ endpoint.search = '';
8
+ endpoint.hash = '';
9
+ return endpoint;
10
+ }
11
+ export function assertBuiltInProfile(profile) {
12
+ const expected = getProfile(profile.environment);
13
+ const matches = profile.label === expected.label
14
+ && profile.apiBaseUrl === expected.apiBaseUrl
15
+ && profile.tenantId === expected.tenantId
16
+ && profile.clientId === expected.clientId
17
+ && profile.scopes.length === expected.scopes.length
18
+ && profile.scopes.every((scope, index) => scope === expected.scopes[index]);
19
+ if (!matches)
20
+ throw new Error('Only the built-in DataBasin production and NP profiles are permitted.');
21
+ }
22
+ //# sourceMappingURL=mcp-endpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-endpoint.js","sourceRoot":"","sources":["../src/mcp-endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAyB,MAAM,aAAa,CAAC;AAEhE,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAe,CAAC;AAEjD,MAAM,UAAU,qBAAqB,CAAC,OAAyB;IAC7D,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7C,QAAQ,CAAC,QAAQ,GAAG,iBAAiB,CAAC;IACtC,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC;IACrB,QAAQ,CAAC,IAAI,GAAG,EAAE,CAAC;IACnB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAyB;IAC5D,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK;WAC3C,OAAO,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU;WAC1C,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ;WACtC,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ;WACtC,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC,MAAM;WAChD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9E,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;AACzG,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type Tool } from '@modelcontextprotocol/client';
2
+ import { McpServer } from '@modelcontextprotocol/server';
3
+ import type { RemoteMcp } from './remote-mcp.js';
4
+ export declare function registerRemoteTools(server: McpServer, remote: RemoteMcp, tools: readonly Tool[]): readonly string[];
5
+ //# sourceMappingURL=proxy-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy-tools.d.ts","sourceRoot":"","sources":["../src/proxy-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,KAAK,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAC9F,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAIzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,SAAS,IAAI,EAAE,GACrB,SAAS,MAAM,EAAE,CAQnB"}
@@ -0,0 +1,39 @@
1
+ import { fromJsonSchema } from '@modelcontextprotocol/client';
2
+ import { safeCorrelationId } from './correlation.js';
3
+ import { publicError } from './errors.js';
4
+ import { LOCAL_AUTH_TOOL_NAMES } from './auth-tools.js';
5
+ export function registerRemoteTools(server, remote, tools) {
6
+ const names = new Set(LOCAL_AUTH_TOOL_NAMES);
7
+ for (const tool of tools) {
8
+ if (names.has(tool.name))
9
+ throw new Error(`The remote MCP server advertised duplicate tool "${tool.name}".`);
10
+ names.add(tool.name);
11
+ registerRemoteTool(server, remote, tool);
12
+ }
13
+ return tools.map((tool) => tool.name);
14
+ }
15
+ function registerRemoteTool(server, remote, tool) {
16
+ const outputSchema = tool.outputSchema
17
+ ? fromJsonSchema(tool.outputSchema)
18
+ : undefined;
19
+ server.registerTool(tool.name, {
20
+ ...(tool.title ? { title: tool.title } : {}),
21
+ ...(tool.description ? { description: tool.description } : {}),
22
+ inputSchema: fromJsonSchema(tool.inputSchema),
23
+ ...(outputSchema ? { outputSchema } : {}),
24
+ ...(tool.annotations ? { annotations: tool.annotations } : {}),
25
+ ...(tool.icons ? { icons: [...tool.icons] } : {}),
26
+ ...(tool._meta ? { _meta: tool._meta } : {})
27
+ }, async (args, context) => {
28
+ try {
29
+ return await remote.callTool(tool, args, context.mcpReq.signal);
30
+ }
31
+ catch (error) {
32
+ const visible = publicError(error);
33
+ const { correlationId, ...publicFields } = visible;
34
+ const safe = { ...publicFields, correlationId: safeCorrelationId(correlationId) };
35
+ return { content: [{ type: 'text', text: JSON.stringify(safe) }], isError: true };
36
+ }
37
+ });
38
+ }
39
+ //# sourceMappingURL=proxy-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy-tools.js","sourceRoot":"","sources":["../src/proxy-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { type CallToolResult, type FetchLike, type Tool } from '@modelcontextprotocol/client';
2
+ import type { DataBasinProfile } from './config.js';
3
+ export declare const REMOTE_PROTOCOL_VERSION: "2026-07-28";
4
+ export interface RemoteMcp {
5
+ connect(): Promise<readonly Tool[]>;
6
+ callTool(tool: Tool, args: unknown, signal?: AbortSignal): Promise<CallToolResult>;
7
+ close(): Promise<void>;
8
+ }
9
+ export type RemoteAuth = Readonly<{
10
+ profile: DataBasinProfile;
11
+ getAccessToken(): Promise<string>;
12
+ }>;
13
+ export type OfficialRemoteMcpOptions = Readonly<{
14
+ auth: RemoteAuth;
15
+ fetchImpl?: FetchLike;
16
+ }>;
17
+ export declare class OfficialRemoteMcp implements RemoteMcp {
18
+ private readonly client;
19
+ private readonly transport;
20
+ private connected;
21
+ constructor(options: OfficialRemoteMcpOptions);
22
+ connect(): Promise<readonly Tool[]>;
23
+ callTool(tool: Tool, args: unknown, signal?: AbortSignal): Promise<CallToolResult>;
24
+ close(): Promise<void>;
25
+ }
26
+ export declare function authenticatedFetch(auth: RemoteAuth, fetchImpl: FetchLike): FetchLike;
27
+ //# sourceMappingURL=remote-mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-mcp.d.ts","sourceRoot":"","sources":["../src/remote-mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,IAAI,EACV,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD,eAAO,MAAM,uBAAuB,EAAG,YAAqB,CAAC;AAE7D,MAAM,WAAW,SAAS;IACxB,OAAO,IAAI,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACnF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACnC,CAAC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC,CAAC;AAEH,qBAAa,iBAAkB,YAAW,SAAS;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;IAC1D,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE,wBAAwB;IAevC,OAAO,IAAI,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;IAazC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC;IAW5E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,SAAS,CAWpF"}
@@ -0,0 +1,70 @@
1
+ import { Client, StreamableHTTPClientTransport } from '@modelcontextprotocol/client';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { mcpEndpointForProfile } from './mcp-endpoint.js';
4
+ import { VERSION } from './version.js';
5
+ export const REMOTE_PROTOCOL_VERSION = '2026-07-28';
6
+ export class OfficialRemoteMcp {
7
+ client;
8
+ transport;
9
+ connected = false;
10
+ constructor(options) {
11
+ const fetchImpl = authenticatedFetch(options.auth, options.fetchImpl ?? globalThis.fetch);
12
+ this.client = new Client({ name: 'databasin-mcp-client-proxy', version: VERSION }, {
13
+ enforceStrictCapabilities: true,
14
+ versionNegotiation: { mode: { pin: REMOTE_PROTOCOL_VERSION } }
15
+ });
16
+ this.transport = new StreamableHTTPClientTransport(mcpEndpointForProfile(options.auth.profile), {
17
+ fetch: fetchImpl,
18
+ onInsufficientScope: 'throw'
19
+ });
20
+ }
21
+ async connect() {
22
+ if (!this.connected) {
23
+ try {
24
+ await this.client.connect(this.transport);
25
+ this.connected = true;
26
+ }
27
+ catch (error) {
28
+ await this.close();
29
+ throw error;
30
+ }
31
+ }
32
+ return (await this.client.listTools(undefined, { cacheMode: 'refresh' })).tools;
33
+ }
34
+ callTool(tool, args, signal) {
35
+ return this.client.callTool({ name: tool.name, arguments: asArguments(args) }, {
36
+ toolDefinition: tool,
37
+ timeout: requestTimeout(tool),
38
+ ...(signal ? { signal } : {})
39
+ });
40
+ }
41
+ async close() {
42
+ this.connected = false;
43
+ await this.client.close();
44
+ }
45
+ }
46
+ export function authenticatedFetch(auth, fetchImpl) {
47
+ return async (url, init = {}) => {
48
+ const headers = new Headers(init.headers);
49
+ if (headers.get('Mcp-Method') === 'tools/call') {
50
+ headers.set('Authorization', `Bearer ${await auth.getAccessToken()}`);
51
+ headers.set('X-Correlation-Id', randomUUID());
52
+ }
53
+ else {
54
+ headers.delete('Authorization');
55
+ }
56
+ return fetchImpl(url, { ...init, redirect: 'error', headers });
57
+ };
58
+ }
59
+ function asArguments(value) {
60
+ return value && typeof value === 'object' && !Array.isArray(value)
61
+ ? value
62
+ : {};
63
+ }
64
+ function requestTimeout(tool) {
65
+ const value = tool._meta?.['com.databasin/requestTimeoutMs'];
66
+ return typeof value === 'number' && Number.isSafeInteger(value) && value >= 1_000 && value <= 2_000_000
67
+ ? value
68
+ : 60_000;
69
+ }
70
+ //# sourceMappingURL=remote-mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-mcp.js","sourceRoot":"","sources":["../src/remote-mcp.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
@@ -1 +1 @@
1
- {"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"AAMA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAAY,GAAG,IAAI,CAK3E;AAgBD,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
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 { randomUUID } from 'node:crypto';
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
- inspectKeys(value, '$');
6
- if (Buffer.byteLength(JSON.stringify(value), 'utf8') > maxBytes) {
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 inspectKeys(value, path) {
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((child, index) => inspectKeys(child, `${path}[${index}]`));
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 (SENSITIVE_KEY.test(key)) {
19
- throw new DataBasinError('INTERNAL_ERROR', `A sensitive field was blocked at ${path}.`);
102
+ if (isSensitiveKey(key) && child !== '[REDACTED]') {
103
+ throw new DataBasinError('POLICY_DENIED', 'Sensitive material was blocked from tool output.');
20
104
  }
21
- inspectKeys(child, `${path}.${key}`);
105
+ inspect(child);
22
106
  }
23
107
  }
24
108
  export function correlationId() {
25
- return randomUUID();
109
+ return freshCorrelationId();
26
110
  }
27
111
  //# sourceMappingURL=safety.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"safety.js","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,aAAa,GAAG,oKAAoK,CAAC;AAE3L,MAAM,UAAU,gBAAgB,CAAC,KAAc,EAAE,QAAQ,GAAG,SAAS;IACnE,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACxB,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;QAChE,MAAM,IAAI,cAAc,CAAC,eAAe,EAAE,mDAAmD,CAAC,CAAC;IACjG,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,KAAc,EAAE,IAAY;IAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;QACzE,OAAO;IACT,CAAC;IACD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO;IAChD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,IAAI,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,cAAc,CAAC,gBAAgB,EAAE,oCAAoC,IAAI,GAAG,CAAC,CAAC;QAC1F,CAAC;QACD,WAAW,CAAC,KAAK,EAAE,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,UAAU,EAAE,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"safety.js","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -1,22 +1,20 @@
1
1
  import { McpServer } from '@modelcontextprotocol/server';
2
2
  import { type StdioServerHandle } from '@modelcontextprotocol/server/stdio';
3
- import { type DataBasinApi } from './api-client.js';
4
- import type { AssistantAuthResult } from './auth.js';
3
+ import { type AssistantAuthResult } from './auth.js';
5
4
  import { type DataBasinEnvironment, type DataBasinProfile } from './config.js';
5
+ import { type RemoteMcp } from './remote-mcp.js';
6
6
  export declare const SERVER_NAME = "databasin-mcp";
7
- export declare const SERVER_VERSION = "0.1.0";
7
+ export declare const SERVER_VERSION = "0.2.0";
8
8
  export declare const SERVER_INSTRUCTIONS: string;
9
9
  export interface CreateServerOptions {
10
10
  environment?: DataBasinEnvironment;
11
- profile?: DataBasinProfile;
12
11
  auth?: {
13
12
  profile: DataBasinProfile;
14
13
  getAccessToken(): Promise<string>;
15
14
  startLogin(): Promise<AssistantAuthResult>;
16
15
  getLoginStatus(): Promise<AssistantAuthResult>;
17
16
  };
18
- api?: DataBasinApi;
19
- fetchImpl?: typeof fetch;
17
+ remote?: RemoteMcp;
20
18
  }
21
19
  export declare function createDataBasinServer(options?: CreateServerOptions): Promise<McpServer>;
22
20
  export declare function serveDataBasinStdio(options?: CreateServerOptions): StdioServerHandle;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAExF,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAc,KAAK,oBAAoB,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI3F,eAAO,MAAM,WAAW,kBAAkB,CAAC;AAC3C,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC,eAAO,MAAM,mBAAmB,QAMrB,CAAC;AAEZ,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,gBAAgB,CAAC;QAC1B,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QAClC,UAAU,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAC3C,cAAc,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;KAChD,CAAC;IACF,GAAG,CAAC,EAAE,YAAY,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,wBAAsB,qBAAqB,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,SAAS,CAAC,CAcjG;AAED,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,mBAAwB,GAAG,iBAAiB,CASxF"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAExF,OAAO,EAAe,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAc,KAAK,oBAAoB,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG3F,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGpE,eAAO,MAAM,WAAW,kBAAkB,CAAC;AAC3C,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC,eAAO,MAAM,mBAAmB,QAOrB,CAAC;AAEZ,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,gBAAgB,CAAC;QAC1B,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QAClC,UAAU,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAC3C,cAAc,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;KAChD,CAAC;IACF,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAsB,qBAAqB,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,SAAS,CAAC,CAkBjG;AAED,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,mBAAwB,GAAG,iBAAiB,CAiBxF"}
package/dist/server.js CHANGED
@@ -1,35 +1,52 @@
1
1
  import { McpServer } from '@modelcontextprotocol/server';
2
2
  import { serveStdio } from '@modelcontextprotocol/server/stdio';
3
- import { DataBasinApiClient } from './api-client.js';
3
+ import { AuthManager } from './auth.js';
4
4
  import { getProfile } from './config.js';
5
- import { registerDataBasinTools } from './tools.js';
5
+ import { registerAuthTools } from './auth-tools.js';
6
+ import { registerRemoteTools } from './proxy-tools.js';
7
+ import { OfficialRemoteMcp } from './remote-mcp.js';
6
8
  import { VERSION } from './version.js';
7
9
  export const SERVER_NAME = 'databasin-mcp';
8
10
  export const SERVER_VERSION = VERSION;
9
11
  export const SERVER_INSTRUCTIONS = [
10
12
  'Call databasin_auth_status first. If needed, call databasin_login and give the user its short-lived Microsoft URL and user code; credentials must be entered only on Microsoft\'s page, never in chat.',
11
- 'After authentication, call databasin_get_context and use only resources visible to the signed-in user.',
13
+ 'After authentication, call databasin_get_capabilities and databasin_get_context before doing work; use only the server-declared capabilities and resources visible to the signed-in user.',
14
+ 'For agent work, require an explicit institutionId and use only the metadata_readonly profile with an optional projectInternalId or connectorId.',
12
15
  'Work metadata-first and keep searches and result pages bounded.',
13
- 'Never request, accept, print, or expose credentials, access tokens, connection strings, arbitrary URLs, or arbitrary headers.',
16
+ 'Never request, accept, print, or expose credentials, access tokens, connection strings, arbitrary URLs, arbitrary headers, mutating or multi-statement SQL, or shell commands; SQL is allowed only through databasin_run_query under its bounded read-only contract.',
14
17
  'The local server handles credentials and tokens outside the agent context.'
15
18
  ].join(' ');
16
19
  export async function createDataBasinServer(options = {}) {
17
- const profile = options.profile ?? getProfile(options.environment ?? 'prod');
18
- const auth = options.auth ?? new (await import('./auth.js')).AuthManager(profile);
19
- const api = options.api ?? new DataBasinApiClient({
20
- baseUrl: profile.apiBaseUrl,
21
- auth,
22
- ...(options.fetchImpl ? { fetchImpl: options.fetchImpl } : {})
23
- });
24
- const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION }, { instructions: SERVER_INSTRUCTIONS });
25
- registerDataBasinTools(server, { api, auth, profile });
26
- return server;
20
+ const profile = getProfile(options.environment ?? 'prod');
21
+ const auth = options.auth ?? new AuthManager(profile);
22
+ const remote = options.remote ?? new OfficialRemoteMcp({ auth });
23
+ try {
24
+ const remoteTools = await remote.connect();
25
+ const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION }, { instructions: SERVER_INSTRUCTIONS });
26
+ registerAuthTools(server, auth);
27
+ registerRemoteTools(server, remote, remoteTools);
28
+ server.server.onclose = () => void remote.close().catch(() => undefined);
29
+ return server;
30
+ }
31
+ catch (error) {
32
+ await remote.close().catch(() => undefined);
33
+ throw error;
34
+ }
27
35
  }
28
36
  export function serveDataBasinStdio(options = {}) {
29
- return serveStdio(async () => createDataBasinServer(options), {
37
+ const profile = getProfile(options.environment ?? 'prod');
38
+ const auth = options.auth ?? new AuthManager(profile);
39
+ const handle = serveStdio(async () => createDataBasinServer({ ...options, auth }), {
30
40
  legacy: 'serve',
31
41
  onerror: () => process.stderr.write('DataBasin MCP protocol error.\n'),
32
42
  maxSubscriptions: 32
33
43
  });
44
+ return {
45
+ close: async () => {
46
+ if (auth instanceof AuthManager)
47
+ auth.cancelPendingLogin();
48
+ await handle.close();
49
+ }
50
+ };
34
51
  }
35
52
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,UAAU,EAA0B,MAAM,oCAAoC,CAAC;AAExF,OAAO,EAAE,kBAAkB,EAAqB,MAAM,iBAAiB,CAAC;AAExE,OAAO,EAAE,UAAU,EAAoD,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC;AAC3C,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,wMAAwM;IACxM,wGAAwG;IACxG,iEAAiE;IACjE,+HAA+H;IAC/H,4EAA4E;CAC7E,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAeZ,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,UAA+B,EAAE;IAC3E,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,WAAW,IAAI,MAAM,CAAC,CAAC;IAC7E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAClF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,kBAAkB,CAAC;QAChD,OAAO,EAAE,OAAO,CAAC,UAAU;QAC3B,IAAI;QACJ,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,EAC9C,EAAE,YAAY,EAAE,mBAAmB,EAAE,CACtC,CAAC;IACF,sBAAsB,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACvD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,UAA+B,EAAE;IACnE,OAAO,UAAU,CACf,KAAK,IAAI,EAAE,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAC1C;QACE,MAAM,EAAE,OAAO;QACf,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC;QACtE,gBAAgB,EAAE,EAAE;KACrB,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { AccountInfo, AuthenticationResult } from '@azure/msal-node';
2
+ import type { DataBasinProfile } from './config.js';
3
+ export declare function accountMatchesProfile(account: AccountInfo, profile: DataBasinProfile): boolean;
4
+ export declare function validateAccessTokenResult(result: AuthenticationResult | null, profile: DataBasinProfile, nowMs: number): string;
5
+ //# sourceMappingURL=token-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-validation.d.ts","sourceRoot":"","sources":["../src/token-validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA8BpD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAG9F;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,oBAAoB,GAAG,IAAI,EACnC,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,MAAM,GACZ,MAAM,CAUR"}