@apideck/mcp-connect 0.1.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.
@@ -0,0 +1,44 @@
1
+ /**
2
+ * ConnectionStore — the persistence seam for the MCP-connect core.
3
+ *
4
+ * This is the pivotal abstraction that makes MCP-connect reusable and
5
+ * framework-agnostic. The core tool-loading / dispatch logic depends only on
6
+ * this interface — never on a specific ORM, database, tenant model, or auth
7
+ * library. A host app supplies an implementation: gtm-pilot ships a Drizzle/
8
+ * Turso store; this package ships an in-memory one (`InMemoryConnectionStore`)
9
+ * so it runs standalone with zero external dependencies.
10
+ *
11
+ * `Identity` is deliberately opaque: `tenantId` / `ownerId` are just routing
12
+ * keys the store interprets. The core passes them through and never reasons
13
+ * about tenancy itself.
14
+ */
15
+ export interface Identity {
16
+ tenantId: string;
17
+ /** The signed-in user id (used to scope per-user connections). */
18
+ ownerId: string;
19
+ }
20
+ /** A connection row as persisted — obfuscated/encrypted token + cached catalog
21
+ * + the joined server metadata. Token decryption and per-LLM tool translation
22
+ * happen in the core (loadMcpToolset), NOT in the store, so the store stays
23
+ * pure persistence with no crypto/provider knowledge. */
24
+ export interface StoredConnection {
25
+ connectionId: string;
26
+ /** The token as persisted — obfuscated (obfuscate.ts) or encrypted
27
+ * (crypto.ts). The store never decrypts; the core's injected `deobfuscate`
28
+ * function does. */
29
+ accessTokenObfuscated: string;
30
+ /** JSON blob shaped `{ tools: [...] }`, or null. */
31
+ toolCatalog: unknown;
32
+ scope: "workspace" | "per_user";
33
+ userId: string | null;
34
+ serverId: string;
35
+ serverSlug: string;
36
+ serverName: string;
37
+ mcpEndpoint: string;
38
+ }
39
+ export interface ConnectionStore {
40
+ /** All connections visible to `scope`: workspace connections are visible to
41
+ * everyone in the tenant; per-user connections only to their owner. */
42
+ listConnections(scope: Identity): Promise<StoredConnection[]>;
43
+ }
44
+ //# sourceMappingURL=connection-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-store.d.ts","sourceRoot":"","sources":["../src/connection-store.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;0DAG0D;AAC1D,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB;;yBAEqB;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oDAAoD;IACpD,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,WAAW,GAAG,UAAU,CAAC;IAChC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B;4EACwE;IACxE,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;CAC/D"}
@@ -0,0 +1,4 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright (c) 2026 Apideck
3
+ export {};
4
+ //# sourceMappingURL=connection-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-store.js","sourceRoot":"","sources":["../src/connection-store.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,6BAA6B"}
@@ -0,0 +1,27 @@
1
+ /** AES-256 key length. */
2
+ export declare const KEY_LENGTH = 32;
3
+ /**
4
+ * Encrypt `plain` under the injected 32-byte KEK. A fresh random IV is used per
5
+ * call, so encrypting the same plaintext twice yields different envelopes.
6
+ */
7
+ export declare function encryptToken(plain: string, key: Buffer): string;
8
+ /**
9
+ * Decrypt an envelope produced by `encryptToken` under the same KEK. Throws if
10
+ * the envelope is malformed, the version is unknown, or the auth tag fails
11
+ * (wrong key or tampered ciphertext).
12
+ */
13
+ export declare function decryptToken(envelope: string, key: Buffer): string;
14
+ /** Generate a fresh, cryptographically-random 32-byte KEK. Store it in your
15
+ * secret manager and inject it into encrypt/decrypt. */
16
+ export declare function generateKey(): Buffer;
17
+ /**
18
+ * Derive a 32-byte KEK from a human passphrase using scrypt. The `salt` MUST be
19
+ * stored alongside your config and reused, or derived keys won't match. Prefer
20
+ * `generateKey()` + a secret manager for production; this helper exists for
21
+ * simple single-operator deployments.
22
+ */
23
+ export declare function deriveKeyFromPassphrase(passphrase: string, salt: Buffer | string): Buffer;
24
+ /** Constant-time comparison of two secrets. Handy when a host needs to compare
25
+ * API keys / tokens without leaking timing. Returns false on length mismatch. */
26
+ export declare function safeEqual(a: string, b: string): boolean;
27
+ //# sourceMappingURL=crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAqCA,0BAA0B;AAC1B,eAAO,MAAM,UAAU,KAAK,CAAC;AAc7B;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAY/D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAoBlE;AAED;yDACyD;AACzD,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAQzF;AAED;kFACkF;AAClF,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAKvD"}
package/dist/crypto.js ADDED
@@ -0,0 +1,108 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright (c) 2026 Apideck
3
+ /**
4
+ * AES-256-GCM token encryption — the RECOMMENDED encryption-at-rest primitive.
5
+ *
6
+ * Unlike `./obfuscate.ts` (HMAC-XOR obfuscation, which only hides plaintext
7
+ * from casual scans and is NOT secure), this module provides real
8
+ * confidentiality AND integrity: AES-256 in Galois/Counter Mode authenticates
9
+ * the ciphertext, so any tampering is detected on decrypt (`decryptToken`
10
+ * throws). Use this for storing MCP access tokens at rest.
11
+ *
12
+ * Key handling follows the same injection rule as the rest of core: the key
13
+ * (a 32-byte KEK — key-encryption key) is passed in as a Buffer. Core never
14
+ * reads env. The host app resolves the KEK (a secret manager, an env var, KMS,
15
+ * …) and passes it in, which keeps this file host-agnostic and lets keys be
16
+ * rotated by the host without touching the package.
17
+ *
18
+ * Envelope format (all base64url-free base64, dot-delimited, versioned):
19
+ * `v1.<iv>.<authTag>.<ciphertext>`
20
+ * The version prefix lets us evolve the scheme without ambiguity.
21
+ */
22
+ import { createCipheriv, createDecipheriv, randomBytes, scryptSync, timingSafeEqual, } from "node:crypto";
23
+ const VERSION = "v1";
24
+ const ALGORITHM = "aes-256-gcm";
25
+ /** GCM standard nonce length. */
26
+ const IV_LENGTH = 12;
27
+ /** GCM authentication tag length. */
28
+ const AUTH_TAG_LENGTH = 16;
29
+ /** AES-256 key length. */
30
+ export const KEY_LENGTH = 32;
31
+ /** Minimum salt length for passphrase-derived keys (NIST SP 800-132 floor). */
32
+ const MIN_SALT_LENGTH = 16;
33
+ function assertKey(key) {
34
+ if (!Buffer.isBuffer(key) || key.length !== KEY_LENGTH) {
35
+ throw new Error(`AES-256-GCM requires a ${KEY_LENGTH}-byte key (KEK); received ${Buffer.isBuffer(key) ? `${key.length} bytes` : typeof key}. Generate one with generateKey() or deriveKeyFromPassphrase().`);
36
+ }
37
+ }
38
+ /**
39
+ * Encrypt `plain` under the injected 32-byte KEK. A fresh random IV is used per
40
+ * call, so encrypting the same plaintext twice yields different envelopes.
41
+ */
42
+ export function encryptToken(plain, key) {
43
+ assertKey(key);
44
+ const iv = randomBytes(IV_LENGTH);
45
+ const cipher = createCipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
46
+ const ciphertext = Buffer.concat([cipher.update(plain, "utf8"), cipher.final()]);
47
+ const authTag = cipher.getAuthTag();
48
+ return [
49
+ VERSION,
50
+ iv.toString("base64"),
51
+ authTag.toString("base64"),
52
+ ciphertext.toString("base64"),
53
+ ].join(".");
54
+ }
55
+ /**
56
+ * Decrypt an envelope produced by `encryptToken` under the same KEK. Throws if
57
+ * the envelope is malformed, the version is unknown, or the auth tag fails
58
+ * (wrong key or tampered ciphertext).
59
+ */
60
+ export function decryptToken(envelope, key) {
61
+ assertKey(key);
62
+ const parts = envelope.split(".");
63
+ if (parts.length !== 4) {
64
+ throw new Error("Malformed AES-GCM envelope: expected v1.<iv>.<tag>.<ciphertext>");
65
+ }
66
+ const [version, ivB64, tagB64, ctB64] = parts;
67
+ if (version !== VERSION) {
68
+ throw new Error(`Unsupported AES-GCM envelope version: ${version}`);
69
+ }
70
+ const iv = Buffer.from(ivB64, "base64");
71
+ const authTag = Buffer.from(tagB64, "base64");
72
+ const ciphertext = Buffer.from(ctB64, "base64");
73
+ if (iv.length !== IV_LENGTH || authTag.length !== AUTH_TAG_LENGTH) {
74
+ throw new Error("Malformed AES-GCM envelope: bad iv or auth tag length");
75
+ }
76
+ const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
77
+ decipher.setAuthTag(authTag);
78
+ // decipher.final() throws if the auth tag does not verify.
79
+ return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
80
+ }
81
+ /** Generate a fresh, cryptographically-random 32-byte KEK. Store it in your
82
+ * secret manager and inject it into encrypt/decrypt. */
83
+ export function generateKey() {
84
+ return randomBytes(KEY_LENGTH);
85
+ }
86
+ /**
87
+ * Derive a 32-byte KEK from a human passphrase using scrypt. The `salt` MUST be
88
+ * stored alongside your config and reused, or derived keys won't match. Prefer
89
+ * `generateKey()` + a secret manager for production; this helper exists for
90
+ * simple single-operator deployments.
91
+ */
92
+ export function deriveKeyFromPassphrase(passphrase, salt) {
93
+ const saltBuf = typeof salt === "string" ? Buffer.from(salt, "utf8") : salt;
94
+ if (saltBuf.length < MIN_SALT_LENGTH) {
95
+ throw new Error(`deriveKeyFromPassphrase requires a salt of at least ${MIN_SALT_LENGTH} bytes; received ${saltBuf.length}. Use a random salt (e.g. generateKey()) stored alongside your config.`);
96
+ }
97
+ return scryptSync(passphrase, saltBuf, KEY_LENGTH);
98
+ }
99
+ /** Constant-time comparison of two secrets. Handy when a host needs to compare
100
+ * API keys / tokens without leaking timing. Returns false on length mismatch. */
101
+ export function safeEqual(a, b) {
102
+ const ab = Buffer.from(a, "utf8");
103
+ const bb = Buffer.from(b, "utf8");
104
+ if (ab.length !== bb.length)
105
+ return false;
106
+ return timingSafeEqual(ab, bb);
107
+ }
108
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @apideck/mcp-connect — framework-agnostic core for connecting, namespacing,
3
+ * and dispatching Model Context Protocol (MCP) tools.
4
+ *
5
+ * Public API. Everything a host app needs to: persist connections (via the
6
+ * ConnectionStore seam), load + namespace tools, dispatch tool calls, register
7
+ * OAuth providers, and protect tokens at rest.
8
+ */
9
+ export type { ConnectionStore, Identity, StoredConnection } from "./connection-store.js";
10
+ export { InMemoryConnectionStore, type AddConnectionInput, } from "./connection-store-memory.js";
11
+ export type { ToolDef, ToolInputSchema, ServerCatalogEntry } from "./types.js";
12
+ export { buildToolset, loadMcpToolset, dispatchToolCall, safeToolName, normalizeSchema, renderMcpSystemPromptHint, McpConfigError, type McpToolset, type LoadedConnection, type DispatchOptions, type DispatchResult, } from "./toolset.js";
13
+ export { mcpListTools, mcpCallTool, McpRpcError, type McpClientOptions, type McpToolDefinition, type McpListToolsResponse, type McpCallToolResult, } from "./client.js";
14
+ export { registerOAuthProvider, getOAuthProvider, registeredOAuthProviderSlugs, type OAuthProvider, type OAuthTokenResult, } from "./oauth-provider.js";
15
+ export { encryptToken, decryptToken, generateKey, deriveKeyFromPassphrase, safeEqual, KEY_LENGTH, } from "./crypto.js";
16
+ export { obfuscateToken, deobfuscateToken } from "./obfuscate.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AAGH,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,EACL,uBAAuB,EACvB,KAAK,kBAAkB,GACxB,MAAM,8BAA8B,CAAC;AAGtC,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAG/E,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,yBAAyB,EACzB,cAAc,EACd,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,GACvB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,4BAA4B,EAC5B,KAAK,aAAa,EAClB,KAAK,gBAAgB,GACtB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,uBAAuB,EACvB,SAAS,EACT,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright (c) 2026 Apideck
3
+ export { InMemoryConnectionStore, } from "./connection-store-memory.js";
4
+ // --- Toolset: load, namespace, dispatch ------------------------------------
5
+ export { buildToolset, loadMcpToolset, dispatchToolCall, safeToolName, normalizeSchema, renderMcpSystemPromptHint, McpConfigError, } from "./toolset.js";
6
+ // --- MCP transport client --------------------------------------------------
7
+ export { mcpListTools, mcpCallTool, McpRpcError, } from "./client.js";
8
+ // --- OAuth provider plugin registry ----------------------------------------
9
+ export { registerOAuthProvider, getOAuthProvider, registeredOAuthProviderSlugs, } from "./oauth-provider.js";
10
+ // --- Token protection ------------------------------------------------------
11
+ // AES-256-GCM — RECOMMENDED encryption-at-rest.
12
+ export { encryptToken, decryptToken, generateKey, deriveKeyFromPassphrase, safeEqual, KEY_LENGTH, } from "./crypto.js";
13
+ // HMAC-XOR obfuscation — NOT encryption; kept for back-compat only.
14
+ export { obfuscateToken, deobfuscateToken } from "./obfuscate.js";
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,6BAA6B;AAa7B,OAAO,EACL,uBAAuB,GAExB,MAAM,8BAA8B,CAAC;AAKtC,8EAA8E;AAC9E,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,yBAAyB,EACzB,cAAc,GAKf,MAAM,cAAc,CAAC;AAEtB,8EAA8E;AAC9E,OAAO,EACL,YAAY,EACZ,WAAW,EACX,WAAW,GAKZ,MAAM,aAAa,CAAC;AAErB,8EAA8E;AAC9E,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,4BAA4B,GAG7B,MAAM,qBAAqB,CAAC;AAE7B,8EAA8E;AAC9E,gDAAgD;AAChD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,uBAAuB,EACvB,SAAS,EACT,UAAU,GACX,MAAM,aAAa,CAAC;AACrB,oEAAoE;AACpE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * OAuth provider registry — the vendor-neutral seam for connecting OAuth-backed
3
+ * MCP servers.
4
+ *
5
+ * Instead of branching on vendor slug literals in your connect routes, resolve
6
+ * an `OAuthProvider` from this registry. Adding a second provider becomes a
7
+ * registration in host code — never an edit to core or to the routes' control
8
+ * flow. Core holds the INTERFACE and the registry only; concrete providers are
9
+ * registered by the host app (see the provider-plugin authoring guide in the
10
+ * README).
11
+ *
12
+ * No env reads, no vendor literals, no framework imports here.
13
+ */
14
+ /** Token pair returned by a code exchange or refresh, in neutral shape. */
15
+ export interface OAuthTokenResult {
16
+ accessToken: string;
17
+ refreshToken: string | null;
18
+ tokenType: string;
19
+ /** Lifetime in seconds, or null when the provider doesn't expire tokens. */
20
+ expiresInSeconds: number | null;
21
+ scope?: string;
22
+ }
23
+ export interface OAuthProvider {
24
+ /** Catalog slug this provider handles (e.g. "front"). */
25
+ slug: string;
26
+ /** True when the required host config (env vars, secrets) is present. */
27
+ isConfigured(): boolean;
28
+ /** Message shown to the user when `isConfigured()` is false. */
29
+ notConfiguredMessage: string;
30
+ /** Derive the redirect URI to register with the vendor, from the request
31
+ * origin. Providers may honour an env override. */
32
+ deriveRedirectUri(requestOrigin: string): string;
33
+ /** Build the vendor authorize URL to redirect the user to. */
34
+ buildAuthorizeUrl(args: {
35
+ redirectUri: string;
36
+ state: string;
37
+ scope: "per_user" | "workspace";
38
+ }): string;
39
+ /** Exchange an authorization code for tokens. */
40
+ exchangeCode(args: {
41
+ code: string;
42
+ redirectUri: string;
43
+ }): Promise<OAuthTokenResult>;
44
+ /** Refresh an access token, when the provider supports it. */
45
+ refresh?(args: {
46
+ refreshToken: string;
47
+ }): Promise<OAuthTokenResult>;
48
+ }
49
+ /** Register a provider. Idempotent — re-registering the same slug replaces the
50
+ * prior entry (last registration wins). */
51
+ export declare function registerOAuthProvider(provider: OAuthProvider): void;
52
+ /** Resolve a provider by slug, or undefined when none is registered. */
53
+ export declare function getOAuthProvider(slug: string): OAuthProvider | undefined;
54
+ /** Slugs with a registered provider — handy for tests / diagnostics. */
55
+ export declare function registeredOAuthProviderSlugs(): string[];
56
+ //# sourceMappingURL=oauth-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-provider.d.ts","sourceRoot":"","sources":["../src/oauth-provider.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AAEH,2EAA2E;AAC3E,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,YAAY,IAAI,OAAO,CAAC;IACxB,gEAAgE;IAChE,oBAAoB,EAAE,MAAM,CAAC;IAC7B;wDACoD;IACpD,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;IACjD,8DAA8D;IAC9D,iBAAiB,CAAC,IAAI,EAAE;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,UAAU,GAAG,WAAW,CAAC;KACjC,GAAG,MAAM,CAAC;IACX,iDAAiD;IACjD,YAAY,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACrF,8DAA8D;IAC9D,OAAO,CAAC,CAAC,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACrE;AAID;4CAC4C;AAC5C,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAEnE;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAExE;AAED,wEAAwE;AACxE,wBAAgB,4BAA4B,IAAI,MAAM,EAAE,CAEvD"}
@@ -0,0 +1,17 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright (c) 2026 Apideck
3
+ const registry = new Map();
4
+ /** Register a provider. Idempotent — re-registering the same slug replaces the
5
+ * prior entry (last registration wins). */
6
+ export function registerOAuthProvider(provider) {
7
+ registry.set(provider.slug, provider);
8
+ }
9
+ /** Resolve a provider by slug, or undefined when none is registered. */
10
+ export function getOAuthProvider(slug) {
11
+ return registry.get(slug);
12
+ }
13
+ /** Slugs with a registered provider — handy for tests / diagnostics. */
14
+ export function registeredOAuthProviderSlugs() {
15
+ return [...registry.keys()];
16
+ }
17
+ //# sourceMappingURL=oauth-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-provider.js","sourceRoot":"","sources":["../src/oauth-provider.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,6BAA6B;AAgD7B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAC;AAElD;4CAC4C;AAC5C,MAAM,UAAU,qBAAqB,CAAC,QAAuB;IAC3D,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACxC,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,4BAA4B;IAC1C,OAAO,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function obfuscateToken(plain: string, key: Buffer): string;
2
+ export declare function deobfuscateToken(obfuscated: string, key: Buffer): string;
3
+ //# sourceMappingURL=obfuscate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obfuscate.d.ts","sourceRoot":"","sources":["../src/obfuscate.ts"],"names":[],"mappings":"AAoDA,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAIjE;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMxE"}
@@ -0,0 +1,62 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright (c) 2026 Apideck
3
+ /**
4
+ * Token obfuscation primitives — the pure, framework-agnostic core.
5
+ *
6
+ * NOT real encryption-at-rest. This is HMAC-XOR OBFUSCATION: it keeps MCP
7
+ * access tokens from showing up in plain text when the DB file is cat'd,
8
+ * dumped, or scanned by a generic secrets scanner. It is intentionally cheap
9
+ * and dependency-free, and it is preserved for back-compat with data written
10
+ * by earlier versions.
11
+ *
12
+ * For a real encryption-at-rest posture use the AES-256-GCM module in
13
+ * `./crypto.ts` (encryptToken / decryptToken), which provides confidentiality
14
+ * AND tamper-detection under an injected key (KEK). Never describe this
15
+ * obfuscation as "encryption".
16
+ *
17
+ * Backed by an HMAC-SHA256 keystream seeded with the caller-supplied key + a
18
+ * per-token random salt. The chain MUST mix the key into every block — earlier
19
+ * versions chained only on `(prev_block, salt)` which made the keystream
20
+ * key-independent after the first 32 bytes.
21
+ *
22
+ * The key is INJECTED (a Buffer). Core never reads env: the host app resolves
23
+ * the key (env var + prod-throw + dev fallback) and passes it in. Keeping key
24
+ * resolution out of core is what lets this file live in a standalone package.
25
+ */
26
+ import { createHmac, randomBytes } from "node:crypto";
27
+ /**
28
+ * XOR a buffer with an HMAC-SHA256 keystream seeded from `key` + salt.
29
+ * Each 32-byte block is `HMAC_key(salt || counter)`, so the key is
30
+ * mixed into every block of the stream.
31
+ */
32
+ function xorStream(input, salt, key) {
33
+ const out = Buffer.alloc(input.length);
34
+ let counter = 0;
35
+ let block = createHmac("sha256", key).update(salt).update(Buffer.from([0, 0, 0, 0])).digest();
36
+ let blockIdx = 0;
37
+ for (let i = 0; i < input.length; i++) {
38
+ if (blockIdx >= block.length) {
39
+ counter++;
40
+ const ctr = Buffer.alloc(4);
41
+ ctr.writeUInt32BE(counter);
42
+ block = createHmac("sha256", key).update(salt).update(ctr).digest();
43
+ blockIdx = 0;
44
+ }
45
+ out[i] = input[i] ^ block[blockIdx++];
46
+ }
47
+ return out;
48
+ }
49
+ export function obfuscateToken(plain, key) {
50
+ const salt = randomBytes(16);
51
+ const cipher = xorStream(Buffer.from(plain, "utf8"), salt, key);
52
+ return `${salt.toString("base64")}.${cipher.toString("base64")}`;
53
+ }
54
+ export function deobfuscateToken(obfuscated, key) {
55
+ const dot = obfuscated.indexOf(".");
56
+ if (dot < 0)
57
+ throw new Error("Malformed obfuscated token");
58
+ const salt = Buffer.from(obfuscated.slice(0, dot), "base64");
59
+ const cipher = Buffer.from(obfuscated.slice(dot + 1), "base64");
60
+ return xorStream(cipher, salt, key).toString("utf8");
61
+ }
62
+ //# sourceMappingURL=obfuscate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obfuscate.js","sourceRoot":"","sources":["../src/obfuscate.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,6BAA6B;AAE7B;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD;;;;GAIG;AACH,SAAS,SAAS,CAAC,KAAa,EAAE,IAAY,EAAE,GAAW;IACzD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC9F,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,QAAQ,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAC7B,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC5B,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YAC3B,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;YACpE,QAAQ,GAAG,CAAC,CAAC;QACf,CAAC;QACD,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,GAAW;IACvD,MAAM,IAAI,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IAChE,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,UAAkB,EAAE,GAAW;IAC9D,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,GAAG,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAChE,OAAO,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACvD,CAAC"}
@@ -0,0 +1,95 @@
1
+ import type { ConnectionStore, Identity, StoredConnection } from "./connection-store.js";
2
+ import type { ToolDef, ToolInputSchema } from "./types.js";
3
+ /**
4
+ * Recoverable per-server config error. When `resolveHeaders` throws this, the
5
+ * dispatcher turns it into a tool_result error (the loop survives and the model
6
+ * can tell the user what's misconfigured) rather than crashing the request. Any
7
+ * other thrown error propagates. Host adapters translate their own config
8
+ * errors (e.g. a missing app id) into this neutral type.
9
+ */
10
+ export declare class McpConfigError extends Error {
11
+ constructor(message: string);
12
+ }
13
+ export interface LoadedConnection {
14
+ serverSlug: string;
15
+ serverName: string;
16
+ endpoint: string;
17
+ /** Decrypted at load-time so the loop doesn't pay the cost per call. */
18
+ accessToken: string;
19
+ /** Original tool definitions from the cached catalog. */
20
+ tools: Array<{
21
+ name: string;
22
+ description?: string;
23
+ inputSchema?: Record<string, unknown>;
24
+ }>;
25
+ }
26
+ export interface McpToolset {
27
+ /** Neutral tool definitions. Empty array if the caller has no connections. */
28
+ toolDefs: ToolDef[];
29
+ /** Namespaced-tool-name → connection. Built once so dispatch is O(1). */
30
+ byToolName: Map<string, {
31
+ connection: LoadedConnection;
32
+ originalName: string;
33
+ }>;
34
+ /** Mostly for system-prompt hints. */
35
+ serverSummaries: Array<{
36
+ slug: string;
37
+ name: string;
38
+ toolCount: number;
39
+ }>;
40
+ /** The identity captured at load-time — routing keys the host uses to derive
41
+ * per-server headers WITHOUT trusting any client-supplied value. */
42
+ identity: Identity;
43
+ }
44
+ export declare function safeToolName(slug: string, original: string): string | null;
45
+ /**
46
+ * MCP servers sometimes emit `additionalProperties: false`, oneOf wrappers,
47
+ * etc. Downstream LLM tool APIs generally accept those but reject a missing
48
+ * top-level type. This preserves the original schema and forces
49
+ * `type: "object"` at the root.
50
+ */
51
+ export declare function normalizeSchema(schema: Record<string, unknown> | undefined): ToolInputSchema;
52
+ /**
53
+ * Build a toolset from already-fetched connection rows. Pure (no I/O): the
54
+ * caller supplies the rows and a `deobfuscate` function. Tokens that fail to
55
+ * deobfuscate are skipped (logged) so one bad row can't take down the loop.
56
+ */
57
+ export declare function buildToolset(rows: StoredConnection[], deobfuscate: (obfuscated: string) => string, identity: Identity): McpToolset;
58
+ /**
59
+ * Load all MCP tools visible to `identity`. Workspace-scope connections are
60
+ * visible to everyone in the workspace; per-user connections only to their
61
+ * owner (the ConnectionStore enforces that). Persistence goes through the
62
+ * store seam — this function never knows about a specific database.
63
+ */
64
+ export declare function loadMcpToolset(store: ConnectionStore, identity: Identity, deobfuscate: (obfuscated: string) => string): Promise<McpToolset>;
65
+ export interface DispatchOptions {
66
+ /** Resolve the extra HTTP headers a given server slug needs. May throw
67
+ * `McpConfigError` to surface a recoverable config problem as a tool_result
68
+ * error; any other throw propagates. */
69
+ resolveHeaders: (serverSlug: string) => Record<string, string>;
70
+ timeoutMs?: number;
71
+ }
72
+ export type DispatchResult = {
73
+ text: string;
74
+ isError: boolean;
75
+ serverSlug: string;
76
+ originalName: string;
77
+ } | {
78
+ text: string;
79
+ isError: true;
80
+ serverSlug: null;
81
+ originalName: null;
82
+ };
83
+ /**
84
+ * Dispatch a single inbound tool call. Returns a string that goes into the
85
+ * tool_result content block. Any failure becomes a stringified error so the
86
+ * model can recover (rather than killing the whole loop).
87
+ */
88
+ export declare function dispatchToolCall(toolset: McpToolset, toolName: string, input: Record<string, unknown>, opts: DispatchOptions): Promise<DispatchResult>;
89
+ /**
90
+ * Render a system-prompt snippet describing the available MCP tools. Returns
91
+ * empty string when the caller has no connections — keeps single-shot system
92
+ * prompts unchanged in that case.
93
+ */
94
+ export declare function renderMcpSystemPromptHint(toolset: McpToolset): string;
95
+ //# sourceMappingURL=toolset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolset.d.ts","sourceRoot":"","sources":["../src/toolset.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE3D;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;CAC7F;AAED,MAAM,WAAW,UAAU;IACzB,8EAA8E;IAC9E,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,yEAAyE;IACzE,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,gBAAgB,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChF,sCAAsC;IACtC,eAAe,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E;yEACqE;IACrE,QAAQ,EAAE,QAAQ,CAAC;CACpB;AASD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiB1E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,eAAe,CAO5F;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,gBAAgB,EAAE,EACxB,WAAW,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,EAC3C,QAAQ,EAAE,QAAQ,GACjB,UAAU,CAsEZ;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAC1C,OAAO,CAAC,UAAU,CAAC,CAGrB;AAED,MAAM,WAAW,eAAe;IAC9B;;6CAEyC;IACzC,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC5E;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,IAAI,CAAC;IAAC,YAAY,EAAE,IAAI,CAAA;CAAE,CAAC;AAE1E;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,cAAc,CAAC,CA4DzB;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAYrE"}
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolset.js","sourceRoot":"","sources":["../src/toolset.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Vendor-neutral core types for MCP-connect.
3
+ *
4
+ * Nothing here knows about any specific LLM vendor, marketplace, ORM, or web
5
+ * framework. The neutral `ToolDef` is what the core toolset produces; a
6
+ * per-LLM adapter (in the host app) maps it into a provider-specific shape.
7
+ * The persistence + identity seam re-exports live here so a consumer imports a
8
+ * single `types` module rather than reaching into sub-files.
9
+ */
10
+ export type { Identity, ConnectionStore, StoredConnection } from "./connection-store.js";
11
+ /**
12
+ * JSON-Schema-ish object schema for a tool's input. We only constrain the
13
+ * top-level `type: "object"` (every LLM tool API we target requires it); the
14
+ * rest of the schema is passed through untouched.
15
+ */
16
+ export interface ToolInputSchema {
17
+ type: "object";
18
+ properties?: Record<string, unknown>;
19
+ required?: string[];
20
+ [key: string]: unknown;
21
+ }
22
+ /**
23
+ * Vendor-neutral tool definition. `name` is already namespaced
24
+ * (`slug__tool`) and charset-safe. Adapters translate this into e.g. the
25
+ * Anthropic `{ name, description, input_schema }` shape.
26
+ */
27
+ export interface ToolDef {
28
+ name: string;
29
+ description: string;
30
+ inputSchema: ToolInputSchema;
31
+ }
32
+ /**
33
+ * Vendor-neutral catalog entry — the generic fields every marketplace server
34
+ * carries. Host apps extend this with their own presentation/config fields
35
+ * (icon, beta flags, oauthConfig, DB-sync machinery, …).
36
+ */
37
+ export interface ServerCatalogEntry {
38
+ /** Stable id. */
39
+ id: string;
40
+ /** URL slug — unique. */
41
+ slug: string;
42
+ name: string;
43
+ description: string;
44
+ /** MCP endpoint URL. */
45
+ mcpEndpoint: string;
46
+ /** Auth mechanism the server supports. */
47
+ authType: "oauth" | "api_key" | "hybrid";
48
+ /** Default connection scope. */
49
+ scopeDefault: "per_user" | "workspace";
50
+ enabled: boolean;
51
+ }
52
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzF;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,eAAe,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,iBAAiB;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;IACzC,gCAAgC;IAChC,YAAY,EAAE,UAAU,GAAG,WAAW,CAAC;IACvC,OAAO,EAAE,OAAO,CAAC;CAClB"}
package/dist/types.js ADDED
@@ -0,0 +1,4 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright (c) 2026 Apideck
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,6BAA6B"}