decoy-mcp-server 1.0.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.
- package/README.md +54 -0
- package/dist/cxf-structured.d.ts +12 -0
- package/dist/cxf-structured.js +33 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +1409 -0
- package/dist/tools/alerts.d.ts +9 -0
- package/dist/tools/alerts.js +111 -0
- package/dist/tools/auth.d.ts +9 -0
- package/dist/tools/auth.js +90 -0
- package/dist/tools/decoys.d.ts +9 -0
- package/dist/tools/decoys.js +293 -0
- package/dist/tools/forwarding-emails.d.ts +9 -0
- package/dist/tools/forwarding-emails.js +179 -0
- package/dist/tools/messages.d.ts +9 -0
- package/dist/tools/messages.js +113 -0
- package/dist/tools/stats.d.ts +9 -0
- package/dist/tools/stats.js +61 -0
- package/dist/tools/subdomain.d.ts +9 -0
- package/dist/tools/subdomain.js +302 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# decoy-mcp-server
|
|
2
|
+
|
|
3
|
+
A local [MCP](https://modelcontextprotocol.io) bridge for [Decoy](https://decoys.me).
|
|
4
|
+
It lets an AI agent (Claude Desktop, Claude Code, or any MCP client) manage your
|
|
5
|
+
Decoy identities — create decoy email aliases, list and create accounts, and fill
|
|
6
|
+
credentials — on your behalf.
|
|
7
|
+
|
|
8
|
+
**End-to-end encrypted.** The bridge unwraps your vault-key grant and decrypts
|
|
9
|
+
account data **on your machine**. Decoy's servers only ever see sealed blobs — they
|
|
10
|
+
stay blind to your service↔identity graph.
|
|
11
|
+
|
|
12
|
+
## Quick start
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npx decoy-mcp-server
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
On first run it prints a pairing code and a link to **https://decoys.me/connect** —
|
|
19
|
+
approve it in the Decoy iOS app. The approved agent token is saved to
|
|
20
|
+
`~/.decoy/mcp-token` and reused on subsequent runs.
|
|
21
|
+
|
|
22
|
+
The bridge serves MCP over HTTP at `http://localhost:3001/mcp`.
|
|
23
|
+
|
|
24
|
+
### Connect your MCP client
|
|
25
|
+
|
|
26
|
+
Point your client at the local bridge. For example, Claude Desktop
|
|
27
|
+
(`claude_desktop_config.json`):
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"mcpServers": {
|
|
32
|
+
"decoy": { "url": "http://localhost:3001/mcp" }
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Configuration
|
|
38
|
+
|
|
39
|
+
| Env var | Default | Purpose |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| `DECOY_AGENT_TOKEN` | — | Explicit agent token (skips interactive pairing) |
|
|
42
|
+
| `PORT` | `3001` | Local HTTP port for the MCP endpoint |
|
|
43
|
+
| `DECOY_AGENT_API_URL` | `https://api.decoys.me/api/agent` | Decoy agent API base |
|
|
44
|
+
| `DECOY_AGENT_NAME` | `MCP Server` | Name shown in the Decoy approval prompt |
|
|
45
|
+
|
|
46
|
+
Token and agent key live under `~/.decoy/`.
|
|
47
|
+
|
|
48
|
+
## Docs
|
|
49
|
+
|
|
50
|
+
Full tool catalog and guides: **https://decoys.me/documentation**
|
|
51
|
+
|
|
52
|
+
## License
|
|
53
|
+
|
|
54
|
+
MIT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const STRUCTURED_CXF_TYPES: Set<string>;
|
|
2
|
+
export interface StructuredFieldBlob {
|
|
3
|
+
id: string;
|
|
4
|
+
kind: string;
|
|
5
|
+
label: string | null;
|
|
6
|
+
values: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Reconstruct StructuredFieldBlob[] from a CXF Item's address/credit-card
|
|
10
|
+
* credentials. Returns [] when there are none. `genId` is injectable for tests.
|
|
11
|
+
*/
|
|
12
|
+
export declare function cxfItemToStructured(item: any, genId?: () => string): StructuredFieldBlob[];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
// Multi-part typed fields (address, credit-card) ⇄ StructuredFieldBlob[].
|
|
3
|
+
//
|
|
4
|
+
// This is the MCP-server inverse of the iOS AccountMetadataBlob.toCXFItem mapping
|
|
5
|
+
// (CryptoService.swift). Each such CXF credential carries its members as
|
|
6
|
+
// EditableFields whose `designation` IS the CXF member name (= the
|
|
7
|
+
// StructuredFieldBlob `values` key), e.g. address → streetAddress/city/postalCode/…,
|
|
8
|
+
// credit-card → number/fullName/expiryDate/verificationNumber.
|
|
9
|
+
//
|
|
10
|
+
// CRITICAL: every emitted entry MUST have a string `id`. iOS StructuredFieldBlob.id
|
|
11
|
+
// is a required Codable key with no custom decoder, so a missing id makes the entire
|
|
12
|
+
// `structured` array silently decode to nil on the device → the user's address/card
|
|
13
|
+
// vanishes. The id is ephemeral (iOS regenerates it on its own CXF reads), so a fresh
|
|
14
|
+
// uuid per reconstruction is correct.
|
|
15
|
+
export const STRUCTURED_CXF_TYPES = new Set(['address', 'credit-card']);
|
|
16
|
+
/**
|
|
17
|
+
* Reconstruct StructuredFieldBlob[] from a CXF Item's address/credit-card
|
|
18
|
+
* credentials. Returns [] when there are none. `genId` is injectable for tests.
|
|
19
|
+
*/
|
|
20
|
+
export function cxfItemToStructured(item, genId = randomUUID) {
|
|
21
|
+
const creds = (item && item.credentials) || [];
|
|
22
|
+
return creds
|
|
23
|
+
.filter((c) => STRUCTURED_CXF_TYPES.has(c?.type))
|
|
24
|
+
.map((c) => {
|
|
25
|
+
const values = {};
|
|
26
|
+
for (const f of (c.fields || [])) {
|
|
27
|
+
if (f?.designation)
|
|
28
|
+
values[f.designation] = f.value;
|
|
29
|
+
}
|
|
30
|
+
return { id: genId(), kind: c.type, label: c.label ?? null, values };
|
|
31
|
+
})
|
|
32
|
+
.filter((s) => Object.keys(s.values).length > 0);
|
|
33
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Decoy MCP Server v2.2 — Streamable HTTP transport
|
|
4
|
+
*
|
|
5
|
+
* Setup: first run opens decoys.me/connect?code=... in the user's browser → scan QR
|
|
6
|
+
* with the Decoy iOS app → approved token saved to ~/.decoy/mcp-token and reused
|
|
7
|
+
* on subsequent runs. No localhost setup page — the public website is the kiosk.
|
|
8
|
+
*
|
|
9
|
+
* Auth priority:
|
|
10
|
+
* 1. DECOY_AGENT_TOKEN env var (explicit override)
|
|
11
|
+
* 2. ~/.decoy/mcp-token config file (saved after first pairing)
|
|
12
|
+
* 3. Interactive pairing via decoys.me/connect (first-time setup)
|
|
13
|
+
*
|
|
14
|
+
* ENV:
|
|
15
|
+
* DECOY_AGENT_TOKEN Explicit agent token (skips pairing)
|
|
16
|
+
* DECOY_AGENT_API_URL Base URL for agent API (default: https://api.decoys.me/api/agent)
|
|
17
|
+
* DECOY_CONNECT_URL Frontend pairing page (default: https://decoys.me/connect)
|
|
18
|
+
* DECOY_AGENT_FOR Slug for ?for= param so the website shows the right agent
|
|
19
|
+
* name (e.g. claude-code, cursor, gemini, codex). Default: mcp
|
|
20
|
+
* PORT HTTP port (default: 3001)
|
|
21
|
+
* DEV_MODE "true" → use dev-api.decoys.me
|
|
22
|
+
*/
|
|
23
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
24
|
+
export declare function openVault(blobBase64: string, vaultKey: Buffer): Record<string, unknown>;
|
|
25
|
+
export declare function sealVault(value: unknown, vaultKey: Buffer): string;
|
|
26
|
+
/** Injectable dependencies — production uses the real HTTP client + grant-based
|
|
27
|
+
* vault key; tests inject an in-memory API and a fixed test key to exercise the
|
|
28
|
+
* real tool handlers (schema validation → crypto → re-seal) without a network. */
|
|
29
|
+
export interface ServerDeps {
|
|
30
|
+
call?: <T = unknown>(path: string, method?: string, body?: Record<string, unknown>) => Promise<T>;
|
|
31
|
+
getVaultKey?: () => Promise<Buffer | null>;
|
|
32
|
+
}
|
|
33
|
+
export declare function buildMcpServer(agentToken: string, privateKeyPem?: string, deps?: ServerDeps): McpServer;
|