@id-wispera/mcp-server 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.
Files changed (46) hide show
  1. package/README.md +161 -0
  2. package/dist/index.d.ts +7 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +196 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/middleware/auth.d.ts +24 -0
  7. package/dist/middleware/auth.d.ts.map +1 -0
  8. package/dist/middleware/auth.js +47 -0
  9. package/dist/middleware/auth.js.map +1 -0
  10. package/dist/middleware/policy-enforce.d.ts +26 -0
  11. package/dist/middleware/policy-enforce.d.ts.map +1 -0
  12. package/dist/middleware/policy-enforce.js +53 -0
  13. package/dist/middleware/policy-enforce.js.map +1 -0
  14. package/dist/resources/audit-resource.d.ts +35 -0
  15. package/dist/resources/audit-resource.d.ts.map +1 -0
  16. package/dist/resources/audit-resource.js +46 -0
  17. package/dist/resources/audit-resource.js.map +1 -0
  18. package/dist/resources/passport-resource.d.ts +42 -0
  19. package/dist/resources/passport-resource.d.ts.map +1 -0
  20. package/dist/resources/passport-resource.js +54 -0
  21. package/dist/resources/passport-resource.js.map +1 -0
  22. package/dist/tools/check-policy.d.ts +43 -0
  23. package/dist/tools/check-policy.d.ts.map +1 -0
  24. package/dist/tools/check-policy.js +47 -0
  25. package/dist/tools/check-policy.js.map +1 -0
  26. package/dist/tools/get-credential.d.ts +39 -0
  27. package/dist/tools/get-credential.d.ts.map +1 -0
  28. package/dist/tools/get-credential.js +53 -0
  29. package/dist/tools/get-credential.js.map +1 -0
  30. package/dist/tools/handler.d.ts +12 -0
  31. package/dist/tools/handler.d.ts.map +1 -0
  32. package/dist/tools/handler.js +20 -0
  33. package/dist/tools/handler.js.map +1 -0
  34. package/dist/tools/list-passports.d.ts +64 -0
  35. package/dist/tools/list-passports.d.ts.map +1 -0
  36. package/dist/tools/list-passports.js +68 -0
  37. package/dist/tools/list-passports.js.map +1 -0
  38. package/dist/tools/request-access.d.ts +44 -0
  39. package/dist/tools/request-access.d.ts.map +1 -0
  40. package/dist/tools/request-access.js +85 -0
  41. package/dist/tools/request-access.js.map +1 -0
  42. package/dist/tools/revoke.d.ts +35 -0
  43. package/dist/tools/revoke.d.ts.map +1 -0
  44. package/dist/tools/revoke.js +40 -0
  45. package/dist/tools/revoke.js.map +1 -0
  46. package/package.json +65 -0
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # @id-wispera/mcp-server
2
+
3
+ MCP (Model Context Protocol) server for ID Wispera credential governance.
4
+
5
+ ## Overview
6
+
7
+ This package provides an MCP server that allows AI agents (like Claude) to securely access governed credentials through the Model Context Protocol.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @id-wispera/mcp-server
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ### Starting the Server
18
+
19
+ ```bash
20
+ # Start the MCP server
21
+ npx @id-wispera/mcp-server
22
+
23
+ # With custom vault path
24
+ IDW_VAULT_PATH=~/.my-vault/vault.json npx @id-wispera/mcp-server
25
+ ```
26
+
27
+ ### Configuration with Claude Desktop
28
+
29
+ Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
30
+
31
+ ```json
32
+ {
33
+ "mcpServers": {
34
+ "id-wispera": {
35
+ "command": "npx",
36
+ "args": ["@id-wispera/mcp-server"],
37
+ "env": {
38
+ "IDW_VAULT_PATH": "/path/to/vault.json",
39
+ "IDW_SESSION_TOKEN": "idw_st_..."
40
+ }
41
+ }
42
+ }
43
+ }
44
+ ```
45
+
46
+ **Authentication**: Generate a scoped session token with `idw auth token create --name "claude-desktop" --scope read,list --ttl 7d` and set it as `IDW_SESSION_TOKEN`. This avoids storing a plaintext passphrase in your config file.
47
+
48
+ > **Deprecated**: `IDW_PASSPHRASE` is still accepted for backward compatibility but will be removed in a future release. Migrate to `IDW_SESSION_TOKEN`.
49
+
50
+ ## Available Tools
51
+
52
+ ### get_credential
53
+
54
+ Retrieve a credential by passport ID.
55
+
56
+ ```json
57
+ {
58
+ "name": "get_credential",
59
+ "arguments": {
60
+ "passport_id": "uuid-of-passport",
61
+ "purpose": "Making API call to OpenAI"
62
+ }
63
+ }
64
+ ```
65
+
66
+ ### list_passports
67
+
68
+ List available passports with optional filters.
69
+
70
+ ```json
71
+ {
72
+ "name": "list_passports",
73
+ "arguments": {
74
+ "status": "active",
75
+ "platform": "openai"
76
+ }
77
+ }
78
+ ```
79
+
80
+ ### request_access
81
+
82
+ Request access to a credential (creates audit entry, may require approval).
83
+
84
+ ```json
85
+ {
86
+ "name": "request_access",
87
+ "arguments": {
88
+ "passport_id": "uuid-of-passport",
89
+ "purpose": "Executing user-requested API call",
90
+ "scope": ["chat", "completions"]
91
+ }
92
+ }
93
+ ```
94
+
95
+ ### check_policy
96
+
97
+ Check if an action is permitted by policy.
98
+
99
+ ```json
100
+ {
101
+ "name": "check_policy",
102
+ "arguments": {
103
+ "passport_id": "uuid-of-passport",
104
+ "action": "access"
105
+ }
106
+ }
107
+ ```
108
+
109
+ ### revoke_passport
110
+
111
+ Revoke a passport (requires confirmation).
112
+
113
+ ```json
114
+ {
115
+ "name": "revoke_passport",
116
+ "arguments": {
117
+ "passport_id": "uuid-of-passport",
118
+ "reason": "Credential exposed in logs"
119
+ }
120
+ }
121
+ ```
122
+
123
+ ## Available Resources
124
+
125
+ ### passport://{id}
126
+
127
+ Access passport metadata as a resource.
128
+
129
+ ```
130
+ passport://a1b2c3d4-e5f6-7890-abcd-ef1234567890
131
+ ```
132
+
133
+ ### audit://{passport_id}
134
+
135
+ Access audit trail for a passport.
136
+
137
+ ```
138
+ audit://a1b2c3d4-e5f6-7890-abcd-ef1234567890
139
+ ```
140
+
141
+ ## Security
142
+
143
+ - All credential access is logged to the audit trail
144
+ - Policy rules are evaluated before credential retrieval
145
+ - The server runs locally and communicates via stdio
146
+ - Credentials are never sent to external services
147
+
148
+ ## Environment Variables
149
+
150
+ | Variable | Description | Default |
151
+ |----------|-------------|---------|
152
+ | `IDW_SESSION_TOKEN` | Scoped session token (recommended) | |
153
+ | `IDW_VAULT_PATH` | Path to vault file | `~/.id-wispera/vault.json` |
154
+ | `IDW_LOG_LEVEL` | Logging level | `info` |
155
+ | `IDW_PASSPHRASE` | Vault passphrase | **Deprecated** -- use `IDW_SESSION_TOKEN` instead |
156
+
157
+ The server resolves authentication in order: `IDW_SESSION_TOKEN` > OS keychain > `IDW_PASSPHRASE`.
158
+
159
+ ## License
160
+
161
+ MIT
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ID Wispera MCP Server
4
+ * Model Context Protocol server for credential governance
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG"}
package/dist/index.js ADDED
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ID Wispera MCP Server
4
+ * Model Context Protocol server for credential governance
5
+ */
6
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
7
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
8
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
9
+ import { getVault, getActor } from './middleware/auth.js';
10
+ import { getCredentialTool, handleGetCredential, } from './tools/get-credential.js';
11
+ import { listPassportsTool, handleListPassports, } from './tools/list-passports.js';
12
+ import { requestAccessTool, handleRequestAccess, } from './tools/request-access.js';
13
+ import { checkPolicyTool, handleCheckPolicy, } from './tools/check-policy.js';
14
+ import { revokePassportTool, handleRevokePassport, } from './tools/revoke.js';
15
+ import { getPassportResource, listPassportResources, } from './resources/passport-resource.js';
16
+ import { getAuditResource, listAuditResources, } from './resources/audit-resource.js';
17
+ const VERSION = '0.1.0';
18
+ /**
19
+ * Create and configure the MCP server
20
+ */
21
+ async function createServer() {
22
+ const server = new Server({
23
+ name: 'id-wispera',
24
+ version: VERSION,
25
+ }, {
26
+ capabilities: {
27
+ tools: {},
28
+ resources: {},
29
+ },
30
+ });
31
+ // List available tools
32
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
33
+ return {
34
+ tools: [
35
+ getCredentialTool,
36
+ listPassportsTool,
37
+ requestAccessTool,
38
+ checkPolicyTool,
39
+ revokePassportTool,
40
+ ],
41
+ };
42
+ });
43
+ // Handle tool calls
44
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
45
+ const { name, arguments: args } = request.params;
46
+ try {
47
+ const vault = await getVault();
48
+ const actor = getActor();
49
+ let result;
50
+ switch (name) {
51
+ case 'get_credential':
52
+ result = await handleGetCredential(vault, args, actor);
53
+ break;
54
+ case 'list_passports':
55
+ result = await handleListPassports(vault, args);
56
+ break;
57
+ case 'request_access':
58
+ result = await handleRequestAccess(vault, args, actor);
59
+ break;
60
+ case 'check_policy':
61
+ result = await handleCheckPolicy(vault, args);
62
+ break;
63
+ case 'revoke_passport':
64
+ result = await handleRevokePassport(vault, args, actor);
65
+ break;
66
+ default:
67
+ return {
68
+ content: [
69
+ {
70
+ type: 'text',
71
+ text: JSON.stringify({ error: `Unknown tool: ${name}` }),
72
+ },
73
+ ],
74
+ isError: true,
75
+ };
76
+ }
77
+ return {
78
+ content: [
79
+ {
80
+ type: 'text',
81
+ text: JSON.stringify(result, null, 2),
82
+ },
83
+ ],
84
+ };
85
+ }
86
+ catch (err) {
87
+ return {
88
+ content: [
89
+ {
90
+ type: 'text',
91
+ text: JSON.stringify({
92
+ error: err instanceof Error ? err.message : 'Unknown error',
93
+ }),
94
+ },
95
+ ],
96
+ isError: true,
97
+ };
98
+ }
99
+ });
100
+ // List available resources
101
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
102
+ try {
103
+ const vault = await getVault();
104
+ const passportResources = await listPassportResources(vault);
105
+ const auditResources = await listAuditResources(vault);
106
+ return {
107
+ resources: [...passportResources, ...auditResources],
108
+ };
109
+ }
110
+ catch (err) {
111
+ return {
112
+ resources: [],
113
+ };
114
+ }
115
+ });
116
+ // Read resource
117
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
118
+ const { uri } = request.params;
119
+ try {
120
+ const vault = await getVault();
121
+ // Parse URI
122
+ const url = new URL(uri);
123
+ const scheme = url.protocol.replace(':', '');
124
+ const id = url.hostname;
125
+ let content;
126
+ switch (scheme) {
127
+ case 'passport':
128
+ content = await getPassportResource(vault, id);
129
+ break;
130
+ case 'audit':
131
+ content = await getAuditResource(vault, id);
132
+ break;
133
+ default:
134
+ return {
135
+ contents: [
136
+ {
137
+ uri,
138
+ mimeType: 'application/json',
139
+ text: JSON.stringify({ error: `Unknown resource scheme: ${scheme}` }),
140
+ },
141
+ ],
142
+ };
143
+ }
144
+ if (!content) {
145
+ return {
146
+ contents: [
147
+ {
148
+ uri,
149
+ mimeType: 'application/json',
150
+ text: JSON.stringify({ error: 'Resource not found' }),
151
+ },
152
+ ],
153
+ };
154
+ }
155
+ return {
156
+ contents: [
157
+ {
158
+ uri,
159
+ mimeType: 'application/json',
160
+ text: JSON.stringify(content, null, 2),
161
+ },
162
+ ],
163
+ };
164
+ }
165
+ catch (err) {
166
+ return {
167
+ contents: [
168
+ {
169
+ uri,
170
+ mimeType: 'application/json',
171
+ text: JSON.stringify({
172
+ error: err instanceof Error ? err.message : 'Unknown error',
173
+ }),
174
+ },
175
+ ],
176
+ };
177
+ }
178
+ });
179
+ return server;
180
+ }
181
+ /**
182
+ * Main entry point
183
+ */
184
+ async function main() {
185
+ const server = await createServer();
186
+ const transport = new StdioServerTransport();
187
+ await server.connect(transport);
188
+ // Log to stderr (stdout is for MCP communication)
189
+ console.error('ID Wispera MCP Server started');
190
+ console.error(`Version: ${VERSION}`);
191
+ }
192
+ main().catch((err) => {
193
+ console.error('Failed to start MCP server:', err);
194
+ process.exit(1);
195
+ });
196
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,eAAe,EACf,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB;;GAEG;AACH,KAAK,UAAU,YAAY;IACzB,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;QACE,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,OAAO;KACjB,EACD;QACE,YAAY,EAAE;YACZ,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,EAAE;SACd;KACF,CACF,CAAC;IAEF,uBAAuB;IACvB,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QAC1D,OAAO;YACL,KAAK,EAAE;gBACL,iBAAiB;gBACjB,iBAAiB;gBACjB,iBAAiB;gBACjB,eAAe;gBACf,kBAAkB;aACnB;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,oBAAoB;IACpB,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAEjD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;YAEzB,IAAI,MAAe,CAAC;YAEpB,QAAQ,IAAI,EAAE,CAAC;gBACb,KAAK,gBAAgB;oBACnB,MAAM,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,IAAW,EAAE,KAAK,CAAC,CAAC;oBAC9D,MAAM;gBAER,KAAK,gBAAgB;oBACnB,MAAM,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,IAAW,CAAC,CAAC;oBACvD,MAAM;gBAER,KAAK,gBAAgB;oBACnB,MAAM,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,IAAW,EAAE,KAAK,CAAC,CAAC;oBAC9D,MAAM;gBAER,KAAK,cAAc;oBACjB,MAAM,GAAG,MAAM,iBAAiB,CAAC,KAAK,EAAE,IAAW,CAAC,CAAC;oBACrD,MAAM;gBAER,KAAK,iBAAiB;oBACpB,MAAM,GAAG,MAAM,oBAAoB,CAAC,KAAK,EAAE,IAAW,EAAE,KAAK,CAAC,CAAC;oBAC/D,MAAM;gBAER;oBACE,OAAO;wBACL,OAAO,EAAE;4BACP;gCACE,IAAI,EAAE,MAAM;gCACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,iBAAiB,IAAI,EAAE,EAAE,CAAC;6BACzD;yBACF;wBACD,OAAO,EAAE,IAAI;qBACd,CAAC;YACN,CAAC;YAED,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;qBACtC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;yBAC5D,CAAC;qBACH;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,2BAA2B;IAC3B,MAAM,CAAC,iBAAiB,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QAC9D,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;YAE/B,MAAM,iBAAiB,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,CAAC;YAC7D,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAEvD,OAAO;gBACL,SAAS,EAAE,CAAC,GAAG,iBAAiB,EAAE,GAAG,cAAc,CAAC;aACrD,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,SAAS,EAAE,EAAE;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,gBAAgB;IAChB,MAAM,CAAC,iBAAiB,CAAC,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACpE,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAE/B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;YAE/B,YAAY;YACZ,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;YACzB,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC7C,MAAM,EAAE,GAAG,GAAG,CAAC,QAAQ,CAAC;YAExB,IAAI,OAAgB,CAAC;YAErB,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,UAAU;oBACb,OAAO,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;oBAC/C,MAAM;gBAER,KAAK,OAAO;oBACV,OAAO,GAAG,MAAM,gBAAgB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;oBAC5C,MAAM;gBAER;oBACE,OAAO;wBACL,QAAQ,EAAE;4BACR;gCACE,GAAG;gCACH,QAAQ,EAAE,kBAAkB;gCAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,4BAA4B,MAAM,EAAE,EAAE,CAAC;6BACtE;yBACF;qBACF,CAAC;YACN,CAAC;YAED,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO;oBACL,QAAQ,EAAE;wBACR;4BACE,GAAG;4BACH,QAAQ,EAAE,kBAAkB;4BAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;yBACtD;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG;wBACH,QAAQ,EAAE,kBAAkB;wBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;qBACvC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG;wBACH,QAAQ,EAAE,kBAAkB;wBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;yBAC5D,CAAC;qBACH;iBACF;aACF,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;IACpC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,kDAAkD;IAClD,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC/C,OAAO,CAAC,KAAK,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;IAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Authentication middleware for MCP requests
3
+ *
4
+ * Uses PassphraseProvider with allowInteractive: false so the MCP server
5
+ * resolves the passphrase via session token, OS keychain, or IDW_PASSPHRASE
6
+ * env var / .env file — it will never prompt.
7
+ */
8
+ import type { Vault } from '@id-wispera/core';
9
+ /**
10
+ * Get or create an authenticated vault instance
11
+ */
12
+ export declare function getVault(): Promise<Vault>;
13
+ /**
14
+ * Get the actor identifier for audit logging
15
+ */
16
+ export declare function getActor(): string;
17
+ /**
18
+ * Clear cached vault (for testing).
19
+ *
20
+ * NOTE: Currently unused -- intended for test teardown. Wire up in test
21
+ * setup/teardown when vault integration tests are added.
22
+ */
23
+ export declare function clearVaultCache(): void;
24
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAK9C;;GAEG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,CAmB/C;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAKtC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Authentication middleware for MCP requests
3
+ *
4
+ * Uses PassphraseProvider with allowInteractive: false so the MCP server
5
+ * resolves the passphrase via session token, OS keychain, or IDW_PASSPHRASE
6
+ * env var / .env file — it will never prompt.
7
+ */
8
+ import { unlockVault, vaultExists, getDefaultVaultPath, PassphraseProvider } from '@id-wispera/core';
9
+ let cachedVault = null;
10
+ /**
11
+ * Get or create an authenticated vault instance
12
+ */
13
+ export async function getVault() {
14
+ if (cachedVault && cachedVault.isUnlocked) {
15
+ return cachedVault;
16
+ }
17
+ const vaultPath = process.env.IDW_VAULT_PATH ?? getDefaultVaultPath();
18
+ if (!(await vaultExists(vaultPath))) {
19
+ throw new Error(`Vault not found at ${vaultPath}. Initialize with 'idw init' first.`);
20
+ }
21
+ const provider = new PassphraseProvider({
22
+ allowInteractive: false,
23
+ allowEnvVar: true,
24
+ });
25
+ const passphrase = await provider.getPassphrase();
26
+ cachedVault = await unlockVault(passphrase, vaultPath);
27
+ return cachedVault;
28
+ }
29
+ /**
30
+ * Get the actor identifier for audit logging
31
+ */
32
+ export function getActor() {
33
+ return process.env.IDW_ACTOR ?? 'mcp-agent';
34
+ }
35
+ /**
36
+ * Clear cached vault (for testing).
37
+ *
38
+ * NOTE: Currently unused -- intended for test teardown. Wire up in test
39
+ * setup/teardown when vault integration tests are added.
40
+ */
41
+ export function clearVaultCache() {
42
+ if (cachedVault) {
43
+ cachedVault.lock();
44
+ cachedVault = null;
45
+ }
46
+ }
47
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAErG,IAAI,WAAW,GAAiB,IAAI,CAAC;AAErC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,IAAI,WAAW,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;QAC1C,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,mBAAmB,EAAE,CAAC;IAEtE,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,qCAAqC,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,kBAAkB,CAAC;QACtC,gBAAgB,EAAE,KAAK;QACvB,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,CAAC;IAClD,WAAW,GAAG,MAAM,WAAW,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACvD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,WAAW,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,WAAW,EAAE,CAAC;QAChB,WAAW,CAAC,IAAI,EAAE,CAAC;QACnB,WAAW,GAAG,IAAI,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Policy enforcement middleware
3
+ */
4
+ import type { Vault, Passport, PolicyDecision } from '@id-wispera/core';
5
+ export interface EnforcementResult {
6
+ allowed: boolean;
7
+ decision: PolicyDecision;
8
+ }
9
+ /**
10
+ * Enforce policy before credential access.
11
+ *
12
+ * NOTE: Currently unused -- available for future use when tools delegate
13
+ * policy checks to shared middleware instead of calling evaluatePolicy directly.
14
+ */
15
+ export declare function enforcePolicy(vault: Vault, passport: Passport, action: string, actor: string, context?: Record<string, unknown>): Promise<EnforcementResult>;
16
+ /**
17
+ * Check if passport status allows access.
18
+ *
19
+ * NOTE: Currently unused -- available for future use when tools delegate
20
+ * status checks to shared middleware instead of checking passport.status inline.
21
+ */
22
+ export declare function isPassportUsable(passport: Passport): {
23
+ usable: boolean;
24
+ reason?: string;
25
+ };
26
+ //# sourceMappingURL=policy-enforce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-enforce.d.ts","sourceRoot":"","sources":["../../src/middleware/policy-enforce.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGxE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,iBAAiB,CAAC,CAsB5B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAczF"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Policy enforcement middleware
3
+ */
4
+ import { evaluatePolicy, DEFAULT_POLICY_RULES, logAction } from '@id-wispera/core';
5
+ /**
6
+ * Enforce policy before credential access.
7
+ *
8
+ * NOTE: Currently unused -- available for future use when tools delegate
9
+ * policy checks to shared middleware instead of calling evaluatePolicy directly.
10
+ */
11
+ export async function enforcePolicy(vault, passport, action, actor, context) {
12
+ const decision = evaluatePolicy(passport, action, DEFAULT_POLICY_RULES);
13
+ // Log the policy check
14
+ await logAction(vault, {
15
+ passportId: passport.id,
16
+ action: 'policy-checked',
17
+ actor,
18
+ platform: 'mcp',
19
+ details: `Policy ${decision.effect} for action "${action}"`,
20
+ metadata: {
21
+ action,
22
+ effect: decision.effect,
23
+ matchedRules: decision.matchedRules.map(r => r.id),
24
+ context,
25
+ },
26
+ });
27
+ return {
28
+ allowed: decision.allowed,
29
+ decision,
30
+ };
31
+ }
32
+ /**
33
+ * Check if passport status allows access.
34
+ *
35
+ * NOTE: Currently unused -- available for future use when tools delegate
36
+ * status checks to shared middleware instead of checking passport.status inline.
37
+ */
38
+ export function isPassportUsable(passport) {
39
+ switch (passport.status) {
40
+ case 'revoked':
41
+ return { usable: false, reason: 'Passport has been revoked' };
42
+ case 'expired':
43
+ return { usable: false, reason: 'Passport has expired' };
44
+ case 'suspended':
45
+ return { usable: false, reason: 'Passport is suspended' };
46
+ case 'expiring':
47
+ case 'active':
48
+ return { usable: true };
49
+ default:
50
+ return { usable: false, reason: 'Unknown passport status' };
51
+ }
52
+ }
53
+ //# sourceMappingURL=policy-enforce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-enforce.js","sourceRoot":"","sources":["../../src/middleware/policy-enforce.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAOnF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAY,EACZ,QAAkB,EAClB,MAAc,EACd,KAAa,EACb,OAAiC;IAEjC,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAExE,uBAAuB;IACvB,MAAM,SAAS,CAAC,KAAK,EAAE;QACrB,UAAU,EAAE,QAAQ,CAAC,EAAE;QACvB,MAAM,EAAE,gBAAgB;QACxB,KAAK;QACL,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,UAAU,QAAQ,CAAC,MAAM,gBAAgB,MAAM,GAAG;QAC3D,QAAQ,EAAE;YACR,MAAM;YACN,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,OAAO;SACR;KACF,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAkB;IACjD,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;QACxB,KAAK,SAAS;YACZ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAAC;QAChE,KAAK,SAAS;YACZ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;QAC3D,KAAK,WAAW;YACd,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;QAC5D,KAAK,UAAU,CAAC;QAChB,KAAK,QAAQ;YACX,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC1B;YACE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;IAChE,CAAC;AACH,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * MCP Resource: audit://{passport_id}
3
+ * Access audit trail as a resource
4
+ */
5
+ import type { Vault } from '@id-wispera/core';
6
+ export interface AuditResourceContent {
7
+ passport_id: string;
8
+ entries: Array<{
9
+ id: string;
10
+ action: string;
11
+ actor: string;
12
+ timestamp: string;
13
+ platform?: string;
14
+ details?: string;
15
+ }>;
16
+ stats: {
17
+ total_actions: number;
18
+ actions_last_24h: number;
19
+ actions_last_7d: number;
20
+ last_access?: string;
21
+ };
22
+ }
23
+ /**
24
+ * Get audit resource for a passport
25
+ */
26
+ export declare function getAuditResource(vault: Vault, passportId: string): Promise<AuditResourceContent | null>;
27
+ /**
28
+ * List audit resources
29
+ */
30
+ export declare function listAuditResources(vault: Vault): Promise<Array<{
31
+ uri: string;
32
+ name: string;
33
+ description: string;
34
+ }>>;
35
+ //# sourceMappingURL=audit-resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-resource.d.ts","sourceRoot":"","sources":["../../src/resources/audit-resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,KAAK,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,KAAK,EAAE;QACL,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAyBtC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAQpE"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * MCP Resource: audit://{passport_id}
3
+ * Access audit trail as a resource
4
+ */
5
+ import { getAuditLog, getAuditStats } from '@id-wispera/core';
6
+ /**
7
+ * Get audit resource for a passport
8
+ */
9
+ export async function getAuditResource(vault, passportId) {
10
+ try {
11
+ const entries = await getAuditLog(vault, passportId);
12
+ const stats = await getAuditStats(vault, passportId);
13
+ return {
14
+ passport_id: passportId,
15
+ entries: entries.slice(0, 50).map(e => ({
16
+ id: e.id,
17
+ action: e.action,
18
+ actor: e.actor,
19
+ timestamp: e.timestamp,
20
+ platform: e.platform,
21
+ details: e.details,
22
+ })),
23
+ stats: {
24
+ total_actions: stats.totalActions,
25
+ actions_last_24h: stats.actionsLast24h,
26
+ actions_last_7d: stats.actionsLast7d,
27
+ last_access: stats.lastAction?.timestamp,
28
+ },
29
+ };
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ /**
36
+ * List audit resources
37
+ */
38
+ export async function listAuditResources(vault) {
39
+ const passports = await vault.getAllPassports();
40
+ return passports.map(p => ({
41
+ uri: `audit://${p.id}`,
42
+ name: `Audit: ${p.name}`,
43
+ description: `Audit trail for ${p.name}`,
44
+ }));
45
+ }
46
+ //# sourceMappingURL=audit-resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-resource.js","sourceRoot":"","sources":["../../src/resources/audit-resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAoB9D;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAY,EACZ,UAAkB;IAElB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAErD,OAAO;YACL,WAAW,EAAE,UAAU;YACvB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACtC,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,OAAO,EAAE,CAAC,CAAC,OAAO;aACnB,CAAC,CAAC;YACH,KAAK,EAAE;gBACL,aAAa,EAAE,KAAK,CAAC,YAAY;gBACjC,gBAAgB,EAAE,KAAK,CAAC,cAAc;gBACtC,eAAe,EAAE,KAAK,CAAC,aAAa;gBACpC,WAAW,EAAE,KAAK,CAAC,UAAU,EAAE,SAAS;aACzC;SACF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAY;IAEZ,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,eAAe,EAAE,CAAC;IAEhD,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzB,GAAG,EAAE,WAAW,CAAC,CAAC,EAAE,EAAE;QACtB,IAAI,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE;QACxB,WAAW,EAAE,mBAAmB,CAAC,CAAC,IAAI,EAAE;KACzC,CAAC,CAAC,CAAC;AACN,CAAC"}