@datacules/agent-identity-mcp-client 0.10.0 → 0.11.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/LICENSE ADDED
@@ -0,0 +1,109 @@
1
+ Datacules Agent Identity License — Version 1.0
2
+ Copyright (c) 2026 Datacules LLC. All rights reserved.
3
+
4
+ ─────────────────────────────────────────────────────────────────────────────
5
+ PREAMBLE
6
+ ─────────────────────────────────────────────────────────────────────────────
7
+
8
+ This software — Agent Identity & Auth Patterns — is developed and owned by
9
+ Datacules LLC. It is made available to the public as open-source software
10
+ under the permissive terms below.
11
+
12
+ Datacules LLC retains ownership and authorship of this software while
13
+ granting broad, royalty-free rights for anyone to use, copy, modify, and
14
+ distribute it — in commercial or non-commercial contexts — without requiring
15
+ that derivative works also become open source.
16
+
17
+ ─────────────────────────────────────────────────────────────────────────────
18
+ TERMS AND CONDITIONS
19
+ ─────────────────────────────────────────────────────────────────────────────
20
+
21
+ 1. PERMISSION TO USE
22
+
23
+ Permission is hereby granted, free of charge, to any person or
24
+ organization obtaining a copy of this software and associated
25
+ documentation files (the "Software"), to use, copy, modify, merge,
26
+ publish, distribute, sublicense, and/or sell copies of the Software,
27
+ and to permit persons to whom the Software is furnished to do so,
28
+ subject to the conditions below.
29
+
30
+ 2. ATTRIBUTION
31
+
32
+ a. Redistributions of source code must retain this copyright notice,
33
+ this list of conditions, and the disclaimer below.
34
+
35
+ b. Redistributions in binary form or as a product must reproduce this
36
+ copyright notice, this list of conditions, and the disclaimer in the
37
+ documentation and/or other materials provided with the distribution.
38
+
39
+ c. Neither the name "Datacules LLC" nor the names of its contributors
40
+ may be used to endorse or promote products derived from this Software
41
+ without prior written permission from Datacules LLC.
42
+
43
+ 3. COMMERCIAL USE
44
+
45
+ Use of this Software in commercial products, SaaS platforms, internal
46
+ enterprise tools, or any revenue-generating context is explicitly
47
+ permitted without royalty, fee, or additional licensing agreement,
48
+ provided that the conditions in Section 2 (Attribution) are met.
49
+
50
+ 4. NO COPYLEFT / NO VIRAL REQUIREMENT
51
+
52
+ This license does NOT require that derivative works, modifications,
53
+ or software that uses or embeds this Software be made open source.
54
+ You may incorporate this Software into proprietary or closed-source
55
+ products under your own license terms.
56
+
57
+ 5. MODIFICATIONS
58
+
59
+ Modified versions of the Software may be distributed under the same
60
+ terms as this license or under any other permissive open-source
61
+ license (e.g. MIT, Apache 2.0, BSD), provided that:
62
+
63
+ a. The original copyright notice of Datacules LLC is preserved.
64
+ b. Modifications are clearly documented and distinguished from the
65
+ original work.
66
+
67
+ 6. COMPATIBILITY
68
+
69
+ This license is compatible with other permissive open-source licenses
70
+ such as MIT, BSD 2-Clause, BSD 3-Clause, and Apache License 2.0. It
71
+ is also GPL-compatible — this Software may coexist with GPL-licensed
72
+ code, though this Software itself is not distributed under the GPL.
73
+
74
+ ─────────────────────────────────────────────────────────────────────────────
75
+ DISCLAIMER
76
+ ─────────────────────────────────────────────────────────────────────────────
77
+
78
+ THIS SOFTWARE IS PROVIDED BY DATACULES LLC AND CONTRIBUTORS "AS IS" AND
79
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
80
+ IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
81
+ AND NON-INFRINGEMENT ARE DISCLAIMED.
82
+
83
+ IN NO EVENT SHALL DATACULES LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
84
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
85
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
86
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
89
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90
+
91
+ ─────────────────────────────────────────────────────────────────────────────
92
+ SUMMARY (non-binding)
93
+ ─────────────────────────────────────────────────────────────────────────────
94
+
95
+ ✔ Use freely — commercial, proprietary, or open-source projects
96
+ ✔ Modify and distribute with or without changes
97
+ ✔ Sell products built on this Software
98
+ ✔ No royalties or fees
99
+ ✔ No requirement to open-source your own code
100
+ ✔ Attribution to Datacules LLC required in source and binary distributions
101
+ ✗ Do not use "Datacules LLC" to endorse derived products without permission
102
+
103
+ ─────────────────────────────────────────────────────────────────────────────
104
+ CONTACT
105
+ ─────────────────────────────────────────────────────────────────────────────
106
+
107
+ Datacules LLC
108
+ For licensing enquiries: legal@datacules.com
109
+ Product: https://github.com/hvrcharon1/agent-identity
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ /**
3
+ * McpToolCaller — utility for calling arbitrary tools on a connected
4
+ * agent-identity MCP server from application code.
5
+ *
6
+ * While McpCredentialStore handles the CredentialStore contract,
7
+ * McpToolCaller lets you call any tool (resolve_credential,
8
+ * resolve_migration_credential, health, etc.) directly — useful
9
+ * when you want the MCP server to perform the resolution and return
10
+ * the result without going through a local CredentialRouter.
11
+ *
12
+ * Example:
13
+ * const caller = new McpToolCaller({ transport: 'http', serverUrl: 'http://localhost:3002' });
14
+ * const result = await caller.resolveCredential({ userId: 'u1', ... });
15
+ * await caller.disconnect();
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.McpToolCaller = void 0;
19
+ const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
20
+ const sse_js_1 = require("@modelcontextprotocol/sdk/client/sse.js");
21
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
22
+ /**
23
+ * Thin wrapper around the MCP SDK Client for calling agent-identity
24
+ * MCP tools directly. Connection is lazy and cached after first call.
25
+ */
26
+ class McpToolCaller {
27
+ constructor(options) {
28
+ this.client = null;
29
+ this.connectPromise = null;
30
+ this.options = options;
31
+ }
32
+ // ── High-level helpers ─────────────────────────────────────────────────────
33
+ /** Resolve a credential via the remote MCP server */
34
+ async resolveCredential(ctx) {
35
+ return this.callTool('resolve_credential', ctx);
36
+ }
37
+ /** Resolve a migration credential pair via the remote MCP server */
38
+ async resolveMigrationCredential(ctx) {
39
+ return this.callTool('resolve_migration_credential', ctx);
40
+ }
41
+ /** Check the health of the remote agent-identity MCP server */
42
+ async health() {
43
+ return this.callTool('health', {});
44
+ }
45
+ // ── Generic tool call ────────────────────────────────────────────────────────
46
+ async callTool(toolName, args) {
47
+ await this.ensureConnected();
48
+ const result = await this.client.callTool({ name: toolName, arguments: args });
49
+ const text = result.content
50
+ .filter((c) => c.type === 'text')
51
+ .map((c) => c.text)
52
+ .join('');
53
+ let parsed;
54
+ try {
55
+ parsed = JSON.parse(text);
56
+ }
57
+ catch {
58
+ throw new Error(`[McpToolCaller] Tool "${toolName}" returned non-JSON: ${text.slice(0, 200)}`);
59
+ }
60
+ if (parsed?.error) {
61
+ throw new Error(`[McpToolCaller] Tool "${toolName}" error: ${parsed.error}`);
62
+ }
63
+ return parsed;
64
+ }
65
+ /** Disconnect from the remote MCP server */
66
+ async disconnect() {
67
+ if (this.client) {
68
+ await this.client.close();
69
+ this.client = null;
70
+ }
71
+ }
72
+ // ── Connection lifecycle ─────────────────────────────────────────────────
73
+ async ensureConnected() {
74
+ if (this.client)
75
+ return;
76
+ if (!this.connectPromise)
77
+ this.connectPromise = this._connect();
78
+ await this.connectPromise;
79
+ this.connectPromise = null;
80
+ }
81
+ async _connect() {
82
+ const opts = this.options;
83
+ this.client = new index_js_1.Client({ name: opts.clientName ?? 'agent-identity-mcp-caller', version: opts.clientVersion ?? '0.1.0' }, { capabilities: {} });
84
+ if (opts.transport === 'http') {
85
+ const sseUrl = new URL('/sse', opts.serverUrl);
86
+ const headers = {};
87
+ if (opts.authToken)
88
+ headers['Authorization'] = `Bearer ${opts.authToken}`;
89
+ await this.client.connect(new sse_js_1.SSEClientTransport(sseUrl, { requestInit: { headers } }));
90
+ }
91
+ else {
92
+ await this.client.connect(new stdio_js_1.StdioClientTransport({
93
+ command: opts.command,
94
+ args: opts.args ?? [],
95
+ env: opts.env,
96
+ }));
97
+ }
98
+ }
99
+ }
100
+ exports.McpToolCaller = McpToolCaller;
101
+ //# sourceMappingURL=caller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caller.js","sourceRoot":"","sources":["../../src/caller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ /**
3
+ * @datacules/agent-identity-mcp-client
4
+ *
5
+ * Consumes external MCP servers as CredentialStores — the outbound direction
6
+ * of the agent-identity MCP integration.
7
+ *
8
+ * Exports:
9
+ * McpCredentialStore — CredentialStore impl that fetches credentials from
10
+ * any MCP server exposing a list_credentials tool
11
+ * McpToolCaller — thin client for calling any agent-identity MCP tool
12
+ * directly (resolve_credential, health, etc.)
13
+ *
14
+ * Both classes support two transports:
15
+ * http — SSE to a running HTTP+SSE agent-identity-mcp server
16
+ * stdio — spawns an MCP server process and communicates over stdio
17
+ *
18
+ * Example — plug McpCredentialStore into a CredentialRouter:
19
+ *
20
+ * import { McpCredentialStore } from '@datacules/agent-identity-mcp-client';
21
+ * import { createRouterFromStore } from '@datacules/agent-identity';
22
+ *
23
+ * const store = new McpCredentialStore({
24
+ * transport: 'http',
25
+ * serverUrl: 'http://vault-mcp.internal:3002',
26
+ * authToken: process.env.MCP_AUTH_TOKEN,
27
+ * });
28
+ *
29
+ * const router = createRouterFromStore(store, rules, logger);
30
+ * const resolved = await router.resolveAsync(ctx); // async path via store
31
+ *
32
+ * // Clean up when done
33
+ * process.on('SIGTERM', () => store.disconnect());
34
+ *
35
+ * Example — call the MCP server directly (no local router):
36
+ *
37
+ * import { McpToolCaller } from '@datacules/agent-identity-mcp-client';
38
+ *
39
+ * const caller = new McpToolCaller({
40
+ * transport: 'http',
41
+ * serverUrl: 'http://localhost:3002',
42
+ * });
43
+ * const result = await caller.resolveCredential({ userId: 'u1', ... });
44
+ * await caller.disconnect();
45
+ */
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.McpToolCaller = exports.McpCredentialStore = void 0;
48
+ var store_js_1 = require("./store.js");
49
+ Object.defineProperty(exports, "McpCredentialStore", { enumerable: true, get: function () { return store_js_1.McpCredentialStore; } });
50
+ var caller_js_1 = require("./caller.js");
51
+ Object.defineProperty(exports, "McpToolCaller", { enumerable: true, get: function () { return caller_js_1.McpToolCaller; } });
52
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;;;AAEH,uCAAgD;AAAvC,8GAAA,kBAAkB,OAAA;AAE3B,yCAA4C;AAAnC,0GAAA,aAAa,OAAA"}
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ /**
3
+ * McpCredentialStore — CredentialStore implementation that fetches
4
+ * credentials from an external MCP server.
5
+ *
6
+ * Implements the full CredentialStore interface from @datacules/agent-identity
7
+ * so it can be dropped into any CredentialRouter without any other changes:
8
+ *
9
+ * import { McpCredentialStore } from '@datacules/agent-identity-mcp-client';
10
+ * import { createRouterFromStore } from '@datacules/agent-identity';
11
+ *
12
+ * const store = new McpCredentialStore({
13
+ * serverUrl: 'http://localhost:3002',
14
+ * authToken: process.env.MCP_AUTH_TOKEN,
15
+ * });
16
+ * const router = createRouterFromStore(store, rules, logger);
17
+ *
18
+ * The MCP server this client connects to MUST expose a `list_credentials`
19
+ * tool (i.e. another @datacules/agent-identity-mcp instance, a Vault MCP
20
+ * server, a 1Password MCP server, or any custom server following the same
21
+ * tool contract).
22
+ *
23
+ * Transport:
24
+ * - For a remote HTTP+SSE server: provide serverUrl
25
+ * - For an in-process stdio server (test / monorepo): provide serverProcess
26
+ */
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.McpCredentialStore = void 0;
29
+ const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
30
+ const sse_js_1 = require("@modelcontextprotocol/sdk/client/sse.js");
31
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
32
+ // ─── McpCredentialStore ─────────────────────────────────────────────────────────
33
+ /**
34
+ * CredentialStore implementation that pulls credentials from an external
35
+ * MCP server by calling its `list_credentials` tool.
36
+ *
37
+ * Credentials are cached in-memory for `cacheTtlMs` (default 60s) to avoid
38
+ * a round-trip on every router.resolve() call. Call invalidateCache() to
39
+ * force a fresh fetch on the next operation.
40
+ *
41
+ * The MCP client connection is lazy — the first store operation connects
42
+ * and caches the connection. Call disconnect() when the store is no longer
43
+ * needed (e.g. on process shutdown).
44
+ */
45
+ class McpCredentialStore {
46
+ constructor(options) {
47
+ this.client = null;
48
+ this.cache = null;
49
+ this.connectPromise = null;
50
+ this.options = options;
51
+ this.cacheTtlMs = options.cacheTtlMs ?? 60000;
52
+ }
53
+ // ── Public CredentialStore interface ────────────────────────────────────────
54
+ async findByRef(ref) {
55
+ const all = await this.listActive();
56
+ return all.find((c) => c.ref === ref && c.status === 'active') ?? null;
57
+ }
58
+ async listActive() {
59
+ const cached = this.getFromCache();
60
+ if (cached)
61
+ return cached.filter((c) => c.status === 'active');
62
+ const fresh = await this.fetchFromServer();
63
+ return fresh.filter((c) => c.status === 'active');
64
+ }
65
+ async listByKind(kind) {
66
+ const all = await this.listActive();
67
+ return all.filter((c) => c.kind === kind);
68
+ }
69
+ // ── Cache management ──────────────────────────────────────────────────────
70
+ /** Force the next store operation to fetch fresh credentials from the server */
71
+ invalidateCache() {
72
+ this.cache = null;
73
+ }
74
+ getFromCache() {
75
+ if (!this.cache)
76
+ return null;
77
+ if (Date.now() > this.cache.expiresAt) {
78
+ this.cache = null;
79
+ return null;
80
+ }
81
+ return this.cache.credentials;
82
+ }
83
+ setCache(credentials) {
84
+ this.cache = { credentials, expiresAt: Date.now() + this.cacheTtlMs };
85
+ }
86
+ // ── MCP client lifecycle ─────────────────────────────────────────────────
87
+ async ensureConnected() {
88
+ if (this.client)
89
+ return;
90
+ // Serialize concurrent callers so we only connect once
91
+ if (!this.connectPromise)
92
+ this.connectPromise = this._connect();
93
+ await this.connectPromise;
94
+ this.connectPromise = null;
95
+ }
96
+ async _connect() {
97
+ const opts = this.options;
98
+ const clientName = opts.clientName ?? 'agent-identity-mcp-client';
99
+ const clientVersion = opts.clientVersion ?? '0.1.0';
100
+ this.client = new index_js_1.Client({ name: clientName, version: clientVersion }, { capabilities: {} });
101
+ if (opts.transport === 'http') {
102
+ const sseUrl = new URL('/sse', opts.serverUrl);
103
+ const headers = {};
104
+ if (opts.authToken)
105
+ headers['Authorization'] = `Bearer ${opts.authToken}`;
106
+ const transport = new sse_js_1.SSEClientTransport(sseUrl, { requestInit: { headers } });
107
+ await this.client.connect(transport);
108
+ }
109
+ else {
110
+ const transport = new stdio_js_1.StdioClientTransport({
111
+ command: opts.command,
112
+ args: opts.args ?? [],
113
+ env: opts.env,
114
+ });
115
+ await this.client.connect(transport);
116
+ }
117
+ }
118
+ /** Disconnect the MCP client and clear the cache. Call on process shutdown. */
119
+ async disconnect() {
120
+ this.invalidateCache();
121
+ if (this.client) {
122
+ await this.client.close();
123
+ this.client = null;
124
+ }
125
+ }
126
+ // ── Remote fetch ───────────────────────────────────────────────────────────
127
+ async fetchFromServer() {
128
+ await this.ensureConnected();
129
+ const result = await this.client.callTool({
130
+ name: 'list_credentials',
131
+ arguments: {},
132
+ });
133
+ const text = result.content
134
+ .filter((c) => c.type === 'text')
135
+ .map((c) => c.text)
136
+ .join('');
137
+ let parsed;
138
+ try {
139
+ parsed = JSON.parse(text);
140
+ }
141
+ catch {
142
+ throw new Error(`[McpCredentialStore] MCP server returned non-JSON response from list_credentials: ${text.slice(0, 200)}`);
143
+ }
144
+ if (!Array.isArray(parsed.credentials)) {
145
+ throw new Error('[McpCredentialStore] MCP server list_credentials response missing credentials array');
146
+ }
147
+ this.setCache(parsed.credentials);
148
+ return parsed.credentials;
149
+ }
150
+ }
151
+ exports.McpCredentialStore = McpCredentialStore;
152
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * McpToolCaller — utility for calling arbitrary tools on a connected
3
+ * agent-identity MCP server from application code.
4
+ *
5
+ * While McpCredentialStore handles the CredentialStore contract,
6
+ * McpToolCaller lets you call any tool (resolve_credential,
7
+ * resolve_migration_credential, health, etc.) directly — useful
8
+ * when you want the MCP server to perform the resolution and return
9
+ * the result without going through a local CredentialRouter.
10
+ *
11
+ * Example:
12
+ * const caller = new McpToolCaller({ transport: 'http', serverUrl: 'http://localhost:3002' });
13
+ * const result = await caller.resolveCredential({ userId: 'u1', ... });
14
+ * await caller.disconnect();
15
+ */
16
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
17
+ import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
18
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
19
+ /**
20
+ * Thin wrapper around the MCP SDK Client for calling agent-identity
21
+ * MCP tools directly. Connection is lazy and cached after first call.
22
+ */
23
+ export class McpToolCaller {
24
+ constructor(options) {
25
+ this.client = null;
26
+ this.connectPromise = null;
27
+ this.options = options;
28
+ }
29
+ // ── High-level helpers ─────────────────────────────────────────────────────
30
+ /** Resolve a credential via the remote MCP server */
31
+ async resolveCredential(ctx) {
32
+ return this.callTool('resolve_credential', ctx);
33
+ }
34
+ /** Resolve a migration credential pair via the remote MCP server */
35
+ async resolveMigrationCredential(ctx) {
36
+ return this.callTool('resolve_migration_credential', ctx);
37
+ }
38
+ /** Check the health of the remote agent-identity MCP server */
39
+ async health() {
40
+ return this.callTool('health', {});
41
+ }
42
+ // ── Generic tool call ────────────────────────────────────────────────────────
43
+ async callTool(toolName, args) {
44
+ await this.ensureConnected();
45
+ const result = await this.client.callTool({ name: toolName, arguments: args });
46
+ const text = result.content
47
+ .filter((c) => c.type === 'text')
48
+ .map((c) => c.text)
49
+ .join('');
50
+ let parsed;
51
+ try {
52
+ parsed = JSON.parse(text);
53
+ }
54
+ catch {
55
+ throw new Error(`[McpToolCaller] Tool "${toolName}" returned non-JSON: ${text.slice(0, 200)}`);
56
+ }
57
+ if (parsed?.error) {
58
+ throw new Error(`[McpToolCaller] Tool "${toolName}" error: ${parsed.error}`);
59
+ }
60
+ return parsed;
61
+ }
62
+ /** Disconnect from the remote MCP server */
63
+ async disconnect() {
64
+ if (this.client) {
65
+ await this.client.close();
66
+ this.client = null;
67
+ }
68
+ }
69
+ // ── Connection lifecycle ─────────────────────────────────────────────────
70
+ async ensureConnected() {
71
+ if (this.client)
72
+ return;
73
+ if (!this.connectPromise)
74
+ this.connectPromise = this._connect();
75
+ await this.connectPromise;
76
+ this.connectPromise = null;
77
+ }
78
+ async _connect() {
79
+ const opts = this.options;
80
+ this.client = new Client({ name: opts.clientName ?? 'agent-identity-mcp-caller', version: opts.clientVersion ?? '0.1.0' }, { capabilities: {} });
81
+ if (opts.transport === 'http') {
82
+ const sseUrl = new URL('/sse', opts.serverUrl);
83
+ const headers = {};
84
+ if (opts.authToken)
85
+ headers['Authorization'] = `Bearer ${opts.authToken}`;
86
+ await this.client.connect(new SSEClientTransport(sseUrl, { requestInit: { headers } }));
87
+ }
88
+ else {
89
+ await this.client.connect(new StdioClientTransport({
90
+ command: opts.command,
91
+ args: opts.args ?? [],
92
+ env: opts.env,
93
+ }));
94
+ }
95
+ }
96
+ }
97
+ //# sourceMappingURL=caller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caller.js","sourceRoot":"","sources":["../../src/caller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AA2BjF;;;GAGG;AACH,MAAM,OAAO,aAAa;IAKxB,YAAY,OAA6B;QAJjC,WAAM,GAAkB,IAAI,CAAC;QAC7B,mBAAc,GAAyB,IAAI,CAAC;QAIlD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,8EAA8E;IAE9E,qDAAqD;IACrD,KAAK,CAAC,iBAAiB,CACrB,GAA4B;QAE5B,OAAO,IAAI,CAAC,QAAQ,CAA2B,oBAAoB,EAAE,GAAG,CAAC,CAAC;IAC5E,CAAC;IAED,oEAAoE;IACpE,KAAK,CAAC,0BAA0B,CAC9B,GAA4B;QAE5B,OAAO,IAAI,CAAC,QAAQ,CAA0B,8BAA8B,EAAE,GAAG,CAAC,CAAC;IACrF,CAAC;IAED,+DAA+D;IAC/D,KAAK,CAAC,MAAM;QACV,OAAO,IAAI,CAAC,QAAQ,CAAe,QAAQ,EAAE,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,gFAAgF;IAEhF,KAAK,CAAC,QAAQ,CACZ,QAAgB,EAChB,IAA6B;QAE7B,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEhF,MAAM,IAAI,GAAI,MAAM,CAAC,OAAiD;aACnE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aAClB,IAAI,CAAC,EAAE,CAAC,CAAC;QAEZ,IAAI,MAAS,CAAC;QACd,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,yBAAyB,QAAQ,wBAAwB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAC9E,CAAC;QACJ,CAAC;QAED,IAAK,MAAc,EAAE,KAAK,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,YAAa,MAAc,CAAC,KAAK,EAAE,CAAC,CAAC;QACxF,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,4CAA4C;IAC5C,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;IACH,CAAC;IAED,4EAA4E;IAEpE,KAAK,CAAC,eAAe;QAC3B,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChE,MAAM,IAAI,CAAC,cAAc,CAAC;QAC1B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,QAAQ;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CACtB,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,IAAI,2BAA2B,EAAE,OAAO,EAAE,IAAI,CAAC,aAAa,IAAI,OAAO,EAAE,EAChG,EAAE,YAAY,EAAE,EAAE,EAAE,CACrB,CAAC;QAEF,IAAI,IAAI,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC/C,MAAM,OAAO,GAA2B,EAAE,CAAC;YAC3C,IAAI,IAAI,CAAC,SAAS;gBAAE,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1E,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,kBAAkB,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QAC1F,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CACvB,IAAI,oBAAoB,CAAC;gBACvB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;gBACrB,GAAG,EAAE,IAAI,CAAC,GAAG;aACd,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @datacules/agent-identity-mcp-client
3
+ *
4
+ * Consumes external MCP servers as CredentialStores — the outbound direction
5
+ * of the agent-identity MCP integration.
6
+ *
7
+ * Exports:
8
+ * McpCredentialStore — CredentialStore impl that fetches credentials from
9
+ * any MCP server exposing a list_credentials tool
10
+ * McpToolCaller — thin client for calling any agent-identity MCP tool
11
+ * directly (resolve_credential, health, etc.)
12
+ *
13
+ * Both classes support two transports:
14
+ * http — SSE to a running HTTP+SSE agent-identity-mcp server
15
+ * stdio — spawns an MCP server process and communicates over stdio
16
+ *
17
+ * Example — plug McpCredentialStore into a CredentialRouter:
18
+ *
19
+ * import { McpCredentialStore } from '@datacules/agent-identity-mcp-client';
20
+ * import { createRouterFromStore } from '@datacules/agent-identity';
21
+ *
22
+ * const store = new McpCredentialStore({
23
+ * transport: 'http',
24
+ * serverUrl: 'http://vault-mcp.internal:3002',
25
+ * authToken: process.env.MCP_AUTH_TOKEN,
26
+ * });
27
+ *
28
+ * const router = createRouterFromStore(store, rules, logger);
29
+ * const resolved = await router.resolveAsync(ctx); // async path via store
30
+ *
31
+ * // Clean up when done
32
+ * process.on('SIGTERM', () => store.disconnect());
33
+ *
34
+ * Example — call the MCP server directly (no local router):
35
+ *
36
+ * import { McpToolCaller } from '@datacules/agent-identity-mcp-client';
37
+ *
38
+ * const caller = new McpToolCaller({
39
+ * transport: 'http',
40
+ * serverUrl: 'http://localhost:3002',
41
+ * });
42
+ * const result = await caller.resolveCredential({ userId: 'u1', ... });
43
+ * await caller.disconnect();
44
+ */
45
+ export { McpCredentialStore } from './store.js';
46
+ export { McpToolCaller } from './caller.js';
47
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}