tru-mcp 0.2.0 → 0.3.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 CHANGED
@@ -8,9 +8,17 @@ MCP server for [tru](https://tru-by29.onrender.com) — auth and billing API in
8
8
  npx tru-mcp init
9
9
  ```
10
10
 
11
- This detects your MCP client (Claude Code, Claude Desktop, Cursor) and writes the config automatically.
11
+ No API key needed. This detects your MCP client (Claude Code, Claude Desktop, Cursor) and writes the config automatically. Then tell your agent:
12
12
 
13
- Don't have an API key yet? That's fine — add the MCP server first, then ask your agent to run `get_started`. It walks you through the entire setup.
13
+ > "Run get_started to set up tru"
14
+
15
+ Your agent will register your app, get you an API key, connect Stripe, and discover your API — all in one conversation.
16
+
17
+ If you already have an API key:
18
+
19
+ ```bash
20
+ npx tru-mcp init --key tru_ak_your_key_here
21
+ ```
14
22
 
15
23
  ### Manual Config
16
24
 
@@ -23,8 +31,7 @@ Add to your `.mcp.json` (Claude Code) or equivalent:
23
31
  "command": "npx",
24
32
  "args": ["-y", "tru-mcp"],
25
33
  "env": {
26
- "TRU_API_URL": "https://tru-by29.onrender.com",
27
- "TRU_API_KEY": "your_api_key_here"
34
+ "TRU_API_URL": "https://tru-by29.onrender.com"
28
35
  }
29
36
  }
30
37
  }
@@ -35,7 +42,7 @@ Add to your `.mcp.json` (Claude Code) or equivalent:
35
42
 
36
43
  | Variable | Required | Description |
37
44
  |----------|----------|-------------|
38
- | `TRU_API_KEY` | Yes | Your tru API key (starts with `tru_ak_`) |
45
+ | `TRU_API_KEY` | No | Your tru API key (starts with `tru_ak_`). Not needed for initial setup — `register_app` will create one. |
39
46
  | `TRU_API_URL` | No | tru server URL (default: `https://tru-by29.onrender.com`) |
40
47
 
41
48
  ## Getting Started
@@ -56,14 +63,17 @@ After that, you're live. All the tools below work immediately.
56
63
  | `get_started` | Full setup guide — what tru is, how to integrate, risk signals explained |
57
64
  | `register_app` | Register a new app on tru and get an API key |
58
65
  | `connect_stripe` | Link your existing Stripe account to receive payments |
59
- | **Identity & Credentials** | |
66
+ | `discover_api` | Crawl your site and generate an agent skill (SKILL.md) |
67
+ | **Identity & Data** | |
60
68
  | `check_identity` | Verify a user + get risk signals (level, score, card funding, country) |
61
- | `request_credentials` | Request verified data from a user's vault (name, email, phone, address) |
69
+ | `request_user_data` | Request verified data from a user's vault (name, email, phone, address) |
62
70
  | `check_request_status` | Poll the status of a credential request |
63
71
  | **Billing** | |
64
72
  | `create_charge` | Create a direct charge or subscription |
65
73
  | `check_charge_status` | Check the status of a charge request |
66
74
  | `request_virtual_card` | Issue a single-use virtual card for agent purchases |
75
+ | **Provisioning** | |
76
+ | `provision_user` | Auto-create a user account on a third-party app |
67
77
  | **Discovery** | |
68
78
  | `discover_apps` | Browse registered apps on the tru platform |
69
79
  | `read_skill` | Read an app's agent skill guide |
@@ -95,6 +105,20 @@ Agent: Now let's connect your Stripe account.
95
105
  Agent: You're live. Charges approved by tru users will flow to your Stripe account.
96
106
  ```
97
107
 
108
+ ## Example: Auto-Provisioning
109
+
110
+ ```
111
+ User: Sign me up for clayking
112
+
113
+ Agent: → check_identity(email: "user@example.com")
114
+ ✓ Verified — risk: low
115
+
116
+ Agent: → provision_user(email: "user@example.com", service_name: "clayking")
117
+ ✓ Provisioned — got API key and account ID
118
+
119
+ Agent: Now using clayking API on behalf of user...
120
+ ```
121
+
98
122
  ## Example: End User Flow
99
123
 
100
124
  ```
@@ -103,7 +127,7 @@ User: Sign me up for that new service
103
127
  Agent: → check_identity(email: "user@example.com")
104
128
  ✓ Verified — risk: low, score: 12, debit card, US
105
129
 
106
- Agent: → request_credentials(email: "user@example.com", fields: ["name", "email"])
130
+ Agent: → request_user_data(email: "user@example.com", fields: ["name", "email"])
107
131
  ⏳ Pending — approve on your tru dashboard
108
132
 
109
133
  Agent: → check_request_status(request_id: "req_abc123")
@@ -79,6 +79,7 @@ export interface RegisterAppParams {
79
79
  website?: string;
80
80
  allowed_fields?: string[];
81
81
  redirect_uris?: string[];
82
+ provision_url?: string;
82
83
  }
83
84
  export interface RegisterAppResponse {
84
85
  app: {
@@ -113,5 +114,22 @@ export interface ConnectOAuthResponse {
113
114
  payouts_enabled?: boolean;
114
115
  }
115
116
  export declare function getConnectOAuthUrl(serviceName: string): Promise<ConnectOAuthResponse>;
117
+ export interface DiscoverApiResponse {
118
+ endpoints_found: number;
119
+ pages_crawled: number;
120
+ skill_url: string;
121
+ skill_preview: string;
122
+ }
123
+ export declare function discoverApi(serviceName: string): Promise<DiscoverApiResponse>;
124
+ export interface ProvisionResponse {
125
+ credentials: Record<string, unknown>;
126
+ provisioned: boolean;
127
+ }
128
+ export interface AppCredentialsResponse {
129
+ status: "active" | "not_provisioned";
130
+ credentials?: Record<string, unknown>;
131
+ }
132
+ export declare function provisionUser(email: string, serviceName: string): Promise<ProvisionResponse>;
133
+ export declare function getAppCredentials(email: string, serviceName: string): Promise<AppCredentialsResponse>;
116
134
  export declare function requestAgentCard(email: string, amountCents: number, description?: string, targetService?: string, currency?: string, action?: string): Promise<AgentCardResponse>;
117
135
  export {};
@@ -62,6 +62,53 @@ export async function getChargeStatus(id) {
62
62
  export async function getConnectOAuthUrl(serviceName) {
63
63
  return (await request(`/api/connect/by-service/${encodeURIComponent(serviceName)}/oauth-url`));
64
64
  }
65
+ export async function discoverApi(serviceName) {
66
+ const url = `${BASE_URL}/apps/${encodeURIComponent(serviceName)}/discover`;
67
+ const res = await fetch(url, {
68
+ method: "POST",
69
+ headers: {
70
+ "Content-Type": "application/json",
71
+ "X-API-Key": API_KEY,
72
+ },
73
+ });
74
+ if (!res.ok) {
75
+ const body = await res.text();
76
+ throw new Error(`API error ${res.status}: ${body}`);
77
+ }
78
+ // The response is NDJSON — read all lines and extract the final results
79
+ const text = await res.text();
80
+ const lines = text.trim().split("\n");
81
+ let endpointsFound = 0;
82
+ let pagesCrawled = 0;
83
+ let skillContent = "";
84
+ for (const line of lines) {
85
+ try {
86
+ const event = JSON.parse(line);
87
+ if (event.type === "endpoints")
88
+ endpointsFound = event.count;
89
+ if (event.type === "pages")
90
+ pagesCrawled = event.count;
91
+ if (event.type === "skill")
92
+ skillContent = event.content;
93
+ }
94
+ catch { }
95
+ }
96
+ return {
97
+ endpoints_found: endpointsFound,
98
+ pages_crawled: pagesCrawled,
99
+ skill_url: `${BASE_URL}/apps/${encodeURIComponent(serviceName)}/SKILL.md`,
100
+ skill_preview: skillContent.slice(0, 2000),
101
+ };
102
+ }
103
+ export async function provisionUser(email, serviceName) {
104
+ return (await request(`/api/apps/by-service/${encodeURIComponent(serviceName)}/provision`, {
105
+ method: "POST",
106
+ body: JSON.stringify({ email }),
107
+ }));
108
+ }
109
+ export async function getAppCredentials(email, serviceName) {
110
+ return (await request(`/api/apps/by-service/${encodeURIComponent(serviceName)}/credentials/${encodeURIComponent(email)}`));
111
+ }
65
112
  export async function requestAgentCard(email, amountCents, description, targetService, currency, action) {
66
113
  return (await request("/api/billing/agent-card", {
67
114
  method: "POST",
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
package/dist/init.js CHANGED
@@ -1,21 +1,14 @@
1
1
  #!/usr/bin/env node
2
- import { createInterface } from "node:readline/promises";
3
- import { stdin, stdout } from "node:process";
4
- import { readFile, writeFile, access } from "node:fs/promises";
5
- import { join } from "node:path";
2
+ import { readFile, writeFile, access, mkdir } from "node:fs/promises";
3
+ import { join, dirname } from "node:path";
6
4
  import { homedir } from "node:os";
7
5
  const DEFAULT_URL = "https://tru-by29.onrender.com";
8
6
  function detectTargets() {
9
7
  const targets = [];
10
8
  const cwd = process.cwd();
11
- // Claude Code — .mcp.json in current directory
12
- targets.push({
13
- name: "Claude Code",
14
- path: join(cwd, ".mcp.json"),
15
- });
16
- // Claude Desktop
17
9
  const home = homedir();
18
10
  const platform = process.platform;
11
+ targets.push({ name: "Claude Code", path: join(cwd, ".mcp.json") });
19
12
  if (platform === "darwin") {
20
13
  targets.push({
21
14
  name: "Claude Desktop",
@@ -34,119 +27,81 @@ function detectTargets() {
34
27
  path: join(home, ".config", "Claude", "claude_desktop_config.json"),
35
28
  });
36
29
  }
37
- // Cursor .cursor/mcp.json in current directory
38
- targets.push({
39
- name: "Cursor",
40
- path: join(cwd, ".cursor", "mcp.json"),
41
- });
30
+ targets.push({ name: "Cursor", path: join(cwd, ".cursor", "mcp.json") });
42
31
  return targets;
43
32
  }
44
- async function fileExists(path) {
33
+ async function fileExists(p) {
45
34
  try {
46
- await access(path);
35
+ await access(p);
47
36
  return true;
48
37
  }
49
38
  catch {
50
39
  return false;
51
40
  }
52
41
  }
53
- async function readJsonFile(path) {
42
+ async function readJsonFile(p) {
54
43
  try {
55
- const raw = await readFile(path, "utf-8");
44
+ const raw = await readFile(p, "utf-8");
56
45
  return JSON.parse(raw);
57
46
  }
58
47
  catch {
59
48
  return {};
60
49
  }
61
50
  }
62
- function buildTruEntry(apiUrl, apiKey) {
63
- return {
51
+ function buildEntry(apiKey) {
52
+ const entry = {
64
53
  command: "npx",
65
54
  args: ["-y", "tru-mcp"],
66
- env: {
67
- TRU_API_URL: apiUrl,
68
- TRU_API_KEY: apiKey,
69
- },
70
55
  };
56
+ if (apiKey) {
57
+ entry.env = { TRU_API_URL: DEFAULT_URL, TRU_API_KEY: apiKey };
58
+ }
59
+ else {
60
+ entry.env = { TRU_API_URL: DEFAULT_URL };
61
+ }
62
+ return entry;
71
63
  }
72
- async function main() {
73
- const rl = createInterface({ input: stdin, output: stdout });
74
- console.log("\n tru MCP Server Setup\n");
75
- // Prompt for config values
76
- const apiUrl = (await rl.question(` tru API URL [${DEFAULT_URL}]: `)).trim() || DEFAULT_URL;
77
- const apiKey = (await rl.question(" tru API Key: ")).trim();
78
- if (!apiKey) {
79
- console.log("\n Error: API key is required.\n");
80
- rl.close();
81
- process.exit(1);
64
+ function parseArgs() {
65
+ const args = process.argv.slice(2).filter((a) => a !== "init");
66
+ let key;
67
+ for (let i = 0; i < args.length; i++) {
68
+ if (args[i] === "--key" && args[i + 1]) {
69
+ key = args[i + 1];
70
+ i++;
71
+ }
82
72
  }
83
- // Detect available targets
73
+ return { key };
74
+ }
75
+ async function main() {
76
+ const { key } = parseArgs();
77
+ console.log("\n tru MCP — setting up...\n");
84
78
  const targets = detectTargets();
85
- const existing = [];
86
- const creatable = [];
79
+ const written = [];
80
+ const entry = buildEntry(key);
87
81
  for (const t of targets) {
88
- if (await fileExists(t.path)) {
89
- existing.push(t);
90
- }
91
- else {
92
- // For Claude Code, always offer to create .mcp.json
93
- // For others, only offer if the parent dir exists
94
- if (t.name === "Claude Code") {
95
- creatable.push(t);
96
- }
97
- }
82
+ // Write to existing config files, or create .mcp.json for Claude Code
83
+ const exists = await fileExists(t.path);
84
+ if (!exists && t.name !== "Claude Code")
85
+ continue;
86
+ // Ensure parent dir exists
87
+ await mkdir(dirname(t.path), { recursive: true });
88
+ const config = exists ? await readJsonFile(t.path) : {};
89
+ if (!config.mcpServers)
90
+ config.mcpServers = {};
91
+ config.mcpServers.tru = entry;
92
+ await writeFile(t.path, JSON.stringify(config, null, 2) + "\n");
93
+ written.push(t.name);
98
94
  }
99
- const available = [...existing, ...creatable];
100
- if (available.length === 0) {
101
- // No config files found print manual snippet
102
- console.log("\n No MCP client config files detected. Add this to your config:\n");
103
- printManualConfig(apiUrl, apiKey);
104
- rl.close();
95
+ if (written.length === 0) {
96
+ console.log(" No MCP client detected. Add this to your config:\n");
97
+ console.log(JSON.stringify({ mcpServers: { tru: entry } }, null, 2) + "\n");
105
98
  return;
106
99
  }
107
- // Show detected targets
108
- console.log("\n Detected MCP clients:");
109
- available.forEach((t, i) => {
110
- const tag = existing.includes(t) ? "(existing)" : "(will create)";
111
- console.log(` ${i + 1}. ${t.name} ${tag} — ${t.path}`);
112
- });
113
- const choice = (await rl.question(`\n Configure which? [1-${available.length}, or "all"]: `)).trim();
114
- let selected;
115
- if (choice.toLowerCase() === "all") {
116
- selected = available;
117
- }
118
- else {
119
- const idx = parseInt(choice, 10) - 1;
120
- if (isNaN(idx) || idx < 0 || idx >= available.length) {
121
- console.log("\n Invalid choice. Here's the manual config instead:\n");
122
- printManualConfig(apiUrl, apiKey);
123
- rl.close();
124
- return;
125
- }
126
- selected = [available[idx]];
127
- }
128
- // Write configs
129
- const entry = buildTruEntry(apiUrl, apiKey);
130
- for (const target of selected) {
131
- const config = await readJsonFile(target.path);
132
- if (!config.mcpServers) {
133
- config.mcpServers = {};
134
- }
135
- config.mcpServers.tru = entry;
136
- await writeFile(target.path, JSON.stringify(config, null, 2) + "\n");
137
- console.log(` ✓ Updated ${target.name} — ${target.path}`);
100
+ for (const name of written) {
101
+ console.log(` ${name}`);
138
102
  }
139
- console.log("\n Done! Restart your MCP client to connect.\n");
140
- rl.close();
141
- }
142
- function printManualConfig(apiUrl, apiKey) {
143
- const snippet = {
144
- mcpServers: {
145
- tru: buildTruEntry(apiUrl, apiKey),
146
- },
147
- };
148
- console.log(JSON.stringify(snippet, null, 2));
149
- console.log();
103
+ console.log("\n Done. Restart your MCP client, then tell your agent:\n");
104
+ console.log(' "Run get_started to set up tru"\n');
150
105
  }
151
106
  main().catch((err) => {
152
107
  console.error("Error:", err);
package/dist/init.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
3
  import { checkIdentityTool } from "./tools/check_identity.js";
4
- import { requestCredentialsTool } from "./tools/request_credentials.js";
4
+ import { requestUserDataTool } from "./tools/request_user_data.js";
5
5
  import { checkRequestStatusTool } from "./tools/check_request_status.js";
6
6
  import { requestVirtualCardTool } from "./tools/request_virtual_card.js";
7
7
  import { discoverAppsTool } from "./tools/discover_apps.js";
@@ -12,13 +12,15 @@ import { registerAppTool } from "./tools/register_app.js";
12
12
  import { initiateOAuthTool } from "./tools/initiate_oauth.js";
13
13
  import { connectStripeTool } from "./tools/connect_stripe.js";
14
14
  import { getStartedTool } from "./tools/get_started.js";
15
+ import { discoverApiTool } from "./tools/discover_api.js";
16
+ import { provisionUserTool } from "./tools/provision_user.js";
15
17
  const server = new McpServer({
16
18
  name: "tru-identity",
17
19
  version: "0.1.0",
18
20
  });
19
21
  // Register tools
20
22
  server.tool(checkIdentityTool.name, checkIdentityTool.description, checkIdentityTool.inputSchema, checkIdentityTool.handler);
21
- server.tool(requestCredentialsTool.name, requestCredentialsTool.description, requestCredentialsTool.inputSchema, requestCredentialsTool.handler);
23
+ server.tool(requestUserDataTool.name, requestUserDataTool.description, requestUserDataTool.inputSchema, requestUserDataTool.handler);
22
24
  server.tool(checkRequestStatusTool.name, checkRequestStatusTool.description, checkRequestStatusTool.inputSchema, checkRequestStatusTool.handler);
23
25
  server.tool(requestVirtualCardTool.name, requestVirtualCardTool.description, requestVirtualCardTool.inputSchema, requestVirtualCardTool.handler);
24
26
  server.tool(discoverAppsTool.name, discoverAppsTool.description, discoverAppsTool.inputSchema, discoverAppsTool.handler);
@@ -29,6 +31,8 @@ server.tool(registerAppTool.name, registerAppTool.description, registerAppTool.i
29
31
  server.tool(initiateOAuthTool.name, initiateOAuthTool.description, initiateOAuthTool.inputSchema, initiateOAuthTool.handler);
30
32
  server.tool(connectStripeTool.name, connectStripeTool.description, connectStripeTool.inputSchema, connectStripeTool.handler);
31
33
  server.tool(getStartedTool.name, getStartedTool.description, getStartedTool.inputSchema, getStartedTool.handler);
34
+ server.tool(discoverApiTool.name, discoverApiTool.description, discoverApiTool.inputSchema, discoverApiTool.handler);
35
+ server.tool(provisionUserTool.name, provisionUserTool.description, provisionUserTool.inputSchema, provisionUserTool.handler);
32
36
  export async function run() {
33
37
  const transport = new StdioServerTransport();
34
38
  await server.connect(transport);
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ export declare const discoverApiTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ service_name: z.ZodString;
7
+ };
8
+ handler: (args: {
9
+ service_name: string;
10
+ }) => Promise<{
11
+ content: {
12
+ type: "text";
13
+ text: string;
14
+ }[];
15
+ isError?: undefined;
16
+ } | {
17
+ content: {
18
+ type: "text";
19
+ text: string;
20
+ }[];
21
+ isError: boolean;
22
+ }>;
23
+ };
@@ -0,0 +1,73 @@
1
+ import { z } from "zod";
2
+ import { discoverApi, lookupAppByServiceName } from "../api-client.js";
3
+ export const discoverApiTool = {
4
+ name: "discover_api",
5
+ description: "Crawl a registered app's website to discover its API endpoints, documentation, and developer guides. " +
6
+ "Generates an agent skill (SKILL.md) that teaches AI agents how to use the app. " +
7
+ "The app must have a website URL set. Call this after register_app to make your app agent-friendly.",
8
+ inputSchema: {
9
+ service_name: z
10
+ .string()
11
+ .describe("The service_name of the app to discover (e.g. 'my-app')"),
12
+ },
13
+ handler: async (args) => {
14
+ try {
15
+ // Verify the app exists first
16
+ const lookup = await lookupAppByServiceName(args.service_name);
17
+ if (lookup.status === "not_found") {
18
+ return {
19
+ content: [
20
+ {
21
+ type: "text",
22
+ text: `App "${args.service_name}" not found. Use register_app to create it first.`,
23
+ },
24
+ ],
25
+ };
26
+ }
27
+ const result = await discoverApi(args.service_name);
28
+ const lines = [
29
+ `API discovery complete for "${args.service_name}".`,
30
+ ``,
31
+ `Pages crawled: ${result.pages_crawled}`,
32
+ `API endpoints found: ${result.endpoints_found}`,
33
+ ``,
34
+ `Generated agent skill available at:`,
35
+ `${result.skill_url}`,
36
+ ``,
37
+ `Any AI agent can now fetch this skill to learn how to sign up, authenticate, and use your app's API.`,
38
+ ``,
39
+ `To view the full skill: use the read_skill tool with service_name "${args.service_name}".`,
40
+ ];
41
+ if (result.endpoints_found === 0) {
42
+ lines.push(``, `No API endpoints were auto-detected. To improve discovery:`, `- Add an /openapi.json or /swagger.json file to your app`, `- Add an /agent.md file with your API documentation`, `- Make sure your /docs or /api/docs pages are publicly accessible`, `- Or edit the skill manually in the tru dashboard`);
43
+ }
44
+ return {
45
+ content: [{ type: "text", text: lines.join("\n") }],
46
+ };
47
+ }
48
+ catch (err) {
49
+ const message = err instanceof Error ? err.message : String(err);
50
+ if (message.includes("website URL")) {
51
+ return {
52
+ content: [
53
+ {
54
+ type: "text",
55
+ text: `App "${args.service_name}" doesn't have a website URL set. Ask the developer for their domain and update the app:\n\nPUT /api/apps/:id with { "website": "https://their-domain.com" }\n\nOr re-register with the website field included.`,
56
+ },
57
+ ],
58
+ isError: true,
59
+ };
60
+ }
61
+ return {
62
+ content: [
63
+ {
64
+ type: "text",
65
+ text: `Error discovering API: ${message}`,
66
+ },
67
+ ],
68
+ isError: true,
69
+ };
70
+ }
71
+ },
72
+ };
73
+ //# sourceMappingURL=discover_api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover_api.js","sourceRoot":"","sources":["../../src/tools/discover_api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAEvE,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,uGAAuG;QACvG,iFAAiF;QACjF,oGAAoG;IACtG,WAAW,EAAE;QACX,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,CAAC,yDAAyD,CAAC;KACvE;IACD,OAAO,EAAE,KAAK,EAAE,IAA8B,EAAE,EAAE;QAChD,IAAI,CAAC;YACH,8BAA8B;YAC9B,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC/D,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAClC,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,QAAQ,IAAI,CAAC,YAAY,mDAAmD;yBACnF;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAEpD,MAAM,KAAK,GAAG;gBACZ,+BAA+B,IAAI,CAAC,YAAY,IAAI;gBACpD,EAAE;gBACF,kBAAkB,MAAM,CAAC,aAAa,EAAE;gBACxC,wBAAwB,MAAM,CAAC,eAAe,EAAE;gBAChD,EAAE;gBACF,qCAAqC;gBACrC,GAAG,MAAM,CAAC,SAAS,EAAE;gBACrB,EAAE;gBACF,sGAAsG;gBACtG,EAAE;gBACF,sEAAsE,IAAI,CAAC,YAAY,IAAI;aAC5F,CAAC;YAEF,IAAI,MAAM,CAAC,eAAe,KAAK,CAAC,EAAE,CAAC;gBACjC,KAAK,CAAC,IAAI,CACR,EAAE,EACF,4DAA4D,EAC5D,0DAA0D,EAC1D,qDAAqD,EACrD,mEAAmE,EACnE,mDAAmD,CACpD,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;aAC7D,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAEjE,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;gBACpC,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,QAAQ,IAAI,CAAC,YAAY,iNAAiN;yBACjP;qBACF;oBACD,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,0BAA0B,OAAO,EAAE;qBAC1C;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -2,8 +2,8 @@ export const getStartedTool = {
2
2
  name: "get_started",
3
3
  description: "Returns a complete guide for developers integrating tru into their app. " +
4
4
  "Covers what tru is (auth + billing API with risk signals), why it matters, " +
5
- "and walks through setup step-by-step using the MCP tools: register_app, connect_stripe, " +
6
- "and then using create_charge, request_credentials, and check_identity. " +
5
+ "and walks through setup step-by-step using the MCP tools: register_app, connect_stripe, discover_api, " +
6
+ "and then using create_charge, request_user_data, and check_identity. " +
7
7
  "Call this first when a developer wants to integrate tru.",
8
8
  inputSchema: {},
9
9
  handler: async (_args) => {
@@ -55,6 +55,8 @@ This creates your app on tru and returns an **API key** (starts with \`tru_ak_\`
55
55
 
56
56
  The \`service_name\` is your app's unique identifier on tru (lowercase, letters/numbers/hyphens).
57
57
 
58
+ **Important:** Always ask the developer for their \`website\` URL. tru uses it to crawl their docs and generate an agent skill (Step 3), and it's needed for the agent widget (Step 4). Without it, agents won't be able to discover the app.
59
+
58
60
  ### Step 2: Connect your Stripe account
59
61
 
60
62
  \`\`\`
@@ -72,12 +74,40 @@ This generates a URL. Open it in your browser, log into your existing Stripe acc
72
74
 
73
75
  **If you don't have a Stripe account yet**, the OAuth flow will let you create one. But most developers already have one, and the whole point is that nothing about it changes.
74
76
 
75
- ### Step 3: You're live
77
+ ### Step 3: Discover your API
78
+
79
+ \`\`\`
80
+ discover_api(service_name: "my-app")
81
+ \`\`\`
82
+
83
+ tru will crawl your website — homepage, docs pages, API references, OpenAPI specs — and generate a **SKILL.md** that teaches AI agents how to use your app. The more docs you have publicly accessible, the better the generated skill.
84
+
85
+ **Tips for better discovery:**
86
+ - Serve an \`/openapi.json\` or \`/swagger.json\` for structured endpoint detection
87
+ - Add an \`/agent.md\` with custom agent instructions
88
+ - Make your \`/docs\` pages publicly accessible (no auth wall on docs)
89
+ - You can also edit the generated skill in the tru dashboard
90
+
91
+ ### Step 4: Add the agent widget
92
+
93
+ Add this script tag to your app's HTML (in \`<head>\` or before \`</body>\`):
94
+
95
+ \`\`\`html
96
+ <script src="https://tru-by29.onrender.com/widget/agent.js" data-app="my-app" defer></script>
97
+ \`\`\`
98
+
99
+ Replace \`my-app\` with your \`service_name\`. This does two things:
100
+ - **For AI agents** visiting your site: shows them a link to your SKILL.md so they know how to use your app (sign up, authenticate, call your API)
101
+ - **For humans**: shows a subtle "agent guide" link
102
+
103
+ This is how agents discover your app's capabilities when they land on your site. Without it, they have to be told about your app explicitly.
104
+
105
+ ### Step 5: You're live
76
106
 
77
107
  That's it. Your app can now:
78
108
 
79
109
  - **Verify users** — \`check_identity(email)\` returns whether they're verified, plus risk signals
80
- - **Request credentials** — \`request_credentials(email, service, fields)\` asks the user to share verified data
110
+ - **Request credentials** — \`request_user_data(email, service, fields)\` asks the user to share verified data
81
111
  - **Charge users** — \`create_charge(email, amount_cents, description)\` creates a charge that the user approves
82
112
  - **Issue virtual cards** — \`request_virtual_card(email, amount_cents)\` for agent purchases on other sites
83
113
  - **Check risk** — every identity check includes risk level, score, card funding type, country, and fingerprint reuse
@@ -121,10 +151,75 @@ These signals come from Stripe's Radar and Identity — the same fraud detection
121
151
 
122
152
  ---
123
153
 
154
+ ## Auto-provisioning: Let tru users fly through signup
155
+
156
+ The biggest conversion killer is making users create yet another account on your app. tru solves this with **provisioning** — you add a single endpoint, and tru automatically creates accounts for verified users.
157
+
158
+ ### How it works
159
+
160
+ 1. Register a \`provision_url\` on your app (via \`register_app\` or the dashboard)
161
+ 2. When an agent calls \`provision_user(email, service_name)\`, tru:
162
+ - Verifies the user's identity
163
+ - POSTs their verified info to your \`provision_url\`
164
+ - Stores the credentials you return
165
+ 3. The agent gets back API keys / account IDs and can use your service immediately
166
+
167
+ The user never fills out a signup form, never verifies their email (tru already did that), and never hunts for an API key page.
168
+
169
+ ### Your provision endpoint
170
+
171
+ tru sends a signed POST request:
172
+
173
+ \`\`\`
174
+ POST {your_provision_url}
175
+ Headers:
176
+ Content-Type: application/json
177
+ X-Tru-Signature: {HMAC-SHA256 of body using your webhook_secret}
178
+ X-Tru-Event: user.provision
179
+
180
+ Body:
181
+ { "email": "user@example.com", "name": "Jane Doe", "tru_user_id": "user@example.com" }
182
+ \`\`\`
183
+
184
+ Your endpoint should:
185
+ 1. Create an account for the user (or find existing)
186
+ 2. Generate an API key or credentials
187
+ 3. Return them as JSON (any shape — tru stores the whole response)
188
+
189
+ \`\`\`json
190
+ { "api_key": "sk_live_abc123", "account_id": "acct_xyz" }
191
+ \`\`\`
192
+
193
+ ### Verify the signature
194
+
195
+ Use your app's \`webhook_secret\` to verify the \`X-Tru-Signature\` header:
196
+
197
+ \`\`\`javascript
198
+ const crypto = require('crypto');
199
+ const expected = crypto.createHmac('sha256', WEBHOOK_SECRET).update(rawBody).digest('hex');
200
+ if (signature !== expected) return res.status(401).json({ error: 'Invalid signature' });
201
+ \`\`\`
202
+
203
+ ### Example: register with provisioning
204
+
205
+ \`\`\`
206
+ register_app(
207
+ service_name: "my-app",
208
+ display_name: "My App",
209
+ owner_email: "dev@example.com",
210
+ provision_url: "https://myapp.com/api/tru/provision"
211
+ )
212
+ \`\`\`
213
+
214
+ Then any tru agent can:
215
+ \`\`\`
216
+ provision_user(email: "user@example.com", service_name: "my-app")
217
+ → { api_key: "sk_live_abc123", account_id: "acct_xyz" }
218
+ \`\`\`
219
+
124
220
  ## What's next
125
221
 
126
222
  - **Set up webhooks** — get notified when charges are approved/rejected, credentials shared, etc.
127
- - **Write an Agent Skill** — a SKILL.md that teaches AI agents how to use your app (tru hosts it for you)
128
223
  - **Configure App Rules** — users can set per-app spending rules; you can set default limits on your side
129
224
  - **Add "Login with tru"** — OAuth 2.0 flow for browser-based auth (see integration docs)
130
225
 
@@ -135,12 +230,14 @@ These signals come from Stripe's Radar and Identity — the same fraud detection
135
230
  | \`get_started\` | This guide |
136
231
  | \`register_app\` | Create your app, get API key |
137
232
  | \`connect_stripe\` | Link your Stripe account |
233
+ | \`discover_api\` | Crawl your site, generate agent skill |
138
234
  | \`check_identity\` | Verify a user + get risk signals |
139
- | \`request_credentials\` | Ask user to share verified data |
235
+ | \`request_user_data\` | Ask user to share verified data |
140
236
  | \`check_request_status\` | Poll credential request status |
141
237
  | \`create_charge\` | Charge a user (one-time or subscription) |
142
238
  | \`check_charge_status\` | Poll charge status |
143
239
  | \`request_virtual_card\` | Issue single-use card for agent purchases |
240
+ | \`provision_user\` | Auto-create account on a third-party app |
144
241
  | \`discover_apps\` | Browse tru app directory |
145
242
  | \`read_skill\` | Read an app's agent guide |
146
243
  | \`initiate_oauth\` | Start OAuth login flow |
@@ -1 +1 @@
1
- {"version":3,"file":"get_started.js","sourceRoot":"","sources":["../../src/tools/get_started.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,0EAA0E;QAC1E,6EAA6E;QAC7E,0FAA0F;QAC1F,yEAAyE;QACzE,0DAA0D;IAC5D,WAAW,EAAE,EAAE;IACf,OAAO,EAAE,KAAK,EAAE,KAA4B,EAAE,EAAE;QAC9C,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyIjB,CAAC;QAEE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;SAClD,CAAC;IACJ,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"get_started.js","sourceRoot":"","sources":["../../src/tools/get_started.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,0EAA0E;QAC1E,6EAA6E;QAC7E,wGAAwG;QACxG,uEAAuE;QACvE,0DAA0D;IAC5D,WAAW,EAAE,EAAE;IACf,OAAO,EAAE,KAAK,EAAE,KAA4B,EAAE,EAAE;QAC9C,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0OjB,CAAC;QAEE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;SAClD,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { z } from "zod";
2
+ export declare const provisionUserTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ email: z.ZodString;
7
+ service_name: z.ZodString;
8
+ };
9
+ handler: (args: {
10
+ email: string;
11
+ service_name: string;
12
+ }) => Promise<{
13
+ content: {
14
+ type: "text";
15
+ text: string;
16
+ }[];
17
+ isError: boolean;
18
+ } | {
19
+ content: {
20
+ type: "text";
21
+ text: string;
22
+ }[];
23
+ isError?: undefined;
24
+ }>;
25
+ };
@@ -0,0 +1,84 @@
1
+ import { z } from "zod";
2
+ import { checkIdentity, provisionUser } from "../api-client.js";
3
+ export const provisionUserTool = {
4
+ name: "provision_user",
5
+ description: "Provision a tru user on a third-party app. The app must have a provision_url configured. " +
6
+ "tru sends the user's verified identity to the app's provision endpoint, the app creates an account " +
7
+ "and returns credentials (API key, account ID, etc.), and tru stores them. " +
8
+ "Returns the credentials so the agent can use the service immediately. " +
9
+ "If the user was already provisioned, returns the stored credentials without hitting the app again.",
10
+ inputSchema: {
11
+ email: z
12
+ .string()
13
+ .describe("Email address of the tru user to provision"),
14
+ service_name: z
15
+ .string()
16
+ .describe("The service_name of the app to provision the user on"),
17
+ },
18
+ handler: async (args) => {
19
+ try {
20
+ // First verify the user exists on tru
21
+ const identity = await checkIdentity(args.email);
22
+ if (!identity.verified) {
23
+ return {
24
+ content: [
25
+ {
26
+ type: "text",
27
+ text: `User ${args.email} is not verified on tru (reason: ${identity.reason || "unknown"}). They need to sign up at tru first.`,
28
+ },
29
+ ],
30
+ isError: true,
31
+ };
32
+ }
33
+ // Call the provision API
34
+ const result = await provisionUser(args.email, args.service_name);
35
+ const lines = [
36
+ result.provisioned
37
+ ? `Successfully provisioned ${args.email} on ${args.service_name}.`
38
+ : `${args.email} was already provisioned on ${args.service_name}. Returning stored credentials.`,
39
+ ``,
40
+ `Credentials:`,
41
+ `\`\`\`json`,
42
+ JSON.stringify(result.credentials, null, 2),
43
+ `\`\`\``,
44
+ ``,
45
+ `Use these credentials to make API calls to ${args.service_name} on behalf of the user.`,
46
+ ];
47
+ return {
48
+ content: [{ type: "text", text: lines.join("\n") }],
49
+ };
50
+ }
51
+ catch (err) {
52
+ const message = err instanceof Error ? err.message : String(err);
53
+ if (message.includes("no provision_url")) {
54
+ return {
55
+ content: [
56
+ {
57
+ type: "text",
58
+ text: [
59
+ `The app "${args.service_name}" doesn't have a provision_url configured.`,
60
+ ``,
61
+ `The app developer needs to:`,
62
+ `1. Add a POST endpoint that accepts { email, name, tru_user_id } and returns credentials (e.g. { api_key, account_id })`,
63
+ `2. Register the endpoint URL as provision_url on their tru app settings`,
64
+ ``,
65
+ `See the tru developer docs for the full provisioning spec.`,
66
+ ].join("\n"),
67
+ },
68
+ ],
69
+ isError: true,
70
+ };
71
+ }
72
+ return {
73
+ content: [
74
+ {
75
+ type: "text",
76
+ text: `Error provisioning user: ${message}`,
77
+ },
78
+ ],
79
+ isError: true,
80
+ };
81
+ }
82
+ },
83
+ };
84
+ //# sourceMappingURL=provision_user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provision_user.js","sourceRoot":"","sources":["../../src/tools/provision_user.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEhE,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,gBAAgB;IACtB,WAAW,EACT,2FAA2F;QAC3F,qGAAqG;QACrG,4EAA4E;QAC5E,wEAAwE;QACxE,oGAAoG;IACtG,WAAW,EAAE;QACX,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,QAAQ,CAAC,4CAA4C,CAAC;QACzD,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,CAAC,sDAAsD,CAAC;KACpE;IACD,OAAO,EAAE,KAAK,EAAE,IAA6C,EAAE,EAAE;QAC/D,IAAI,CAAC;YACH,sCAAsC;YACtC,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjD,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACvB,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,QAAQ,IAAI,CAAC,KAAK,oCAAoC,QAAQ,CAAC,MAAM,IAAI,SAAS,uCAAuC;yBAChI;qBACF;oBACD,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YAED,yBAAyB;YACzB,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YAElE,MAAM,KAAK,GAAG;gBACZ,MAAM,CAAC,WAAW;oBAChB,CAAC,CAAC,4BAA4B,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,YAAY,GAAG;oBACnE,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,+BAA+B,IAAI,CAAC,YAAY,iCAAiC;gBAClG,EAAE;gBACF,cAAc;gBACd,YAAY;gBACZ,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3C,QAAQ;gBACR,EAAE;gBACF,8CAA8C,IAAI,CAAC,YAAY,yBAAyB;aACzF,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;aAC7D,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAEjE,IAAI,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBACzC,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE;gCACJ,YAAY,IAAI,CAAC,YAAY,4CAA4C;gCACzE,EAAE;gCACF,6BAA6B;gCAC7B,yHAAyH;gCACzH,yEAAyE;gCACzE,EAAE;gCACF,4DAA4D;6BAC7D,CAAC,IAAI,CAAC,IAAI,CAAC;yBACb;qBACF;oBACD,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,4BAA4B,OAAO,EAAE;qBAC5C;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -10,6 +10,7 @@ export declare const registerAppTool: {
10
10
  website: z.ZodOptional<z.ZodString>;
11
11
  allowed_fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
12
12
  redirect_uris: z.ZodOptional<z.ZodArray<z.ZodString>>;
13
+ provision_url: z.ZodOptional<z.ZodString>;
13
14
  };
14
15
  handler: (args: {
15
16
  service_name: string;
@@ -19,6 +20,7 @@ export declare const registerAppTool: {
19
20
  website?: string;
20
21
  allowed_fields?: string[];
21
22
  redirect_uris?: string[];
23
+ provision_url?: string;
22
24
  }) => Promise<{
23
25
  content: {
24
26
  type: "text";
@@ -21,7 +21,7 @@ export const registerAppTool = {
21
21
  website: z
22
22
  .string()
23
23
  .optional()
24
- .describe("The app's public URL"),
24
+ .describe("The app's public URL. Required for API discovery (discover_api) and the agent widget. Always ask the developer for this."),
25
25
  allowed_fields: z
26
26
  .array(z.string())
27
27
  .optional()
@@ -30,6 +30,10 @@ export const registerAppTool = {
30
30
  .array(z.string())
31
31
  .optional()
32
32
  .describe("OAuth redirect URIs for the app"),
33
+ provision_url: z
34
+ .string()
35
+ .optional()
36
+ .describe("URL of your provision endpoint. tru POSTs { email, name, tru_user_id } here to auto-create accounts for tru users."),
33
37
  },
34
38
  handler: async (args) => {
35
39
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"register_app.js","sourceRoot":"","sources":["../../src/tools/register_app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,0IAA0I;QAC1I,8DAA8D;IAChE,WAAW,EAAE;QACX,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,CAAC,yEAAyE,CAAC;QACtF,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,CAAC,yCAAyC,CAAC;QACtD,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,CAAC,6CAA6C,CAAC;QAC1D,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,2CAA2C,CAAC;QACxD,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,sBAAsB,CAAC;QACnC,cAAc,EAAE,CAAC;aACd,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,QAAQ,EAAE;aACV,QAAQ,CAAC,0EAA0E,CAAC;QACvF,aAAa,EAAE,CAAC;aACb,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,QAAQ,EAAE;aACV,QAAQ,CAAC,iCAAiC,CAAC;KAC/C;IACD,OAAO,EAAE,KAAK,EAAE,IAQf,EAAE,EAAE;QACH,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;YAEvC,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE;4BACJ,8BAA8B;4BAC9B,EAAE;4BACF,WAAW,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE;4BAC1B,iBAAiB,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE;4BAC1C,iBAAiB,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE;4BAC1C,WAAW,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE;4BAC9B,EAAE;4BACF,YAAY,MAAM,CAAC,OAAO,EAAE;4BAC5B,EAAE;4BACF,gEAAgE;4BAChE,wEAAwE;yBACzE,CAAC,IAAI,CAAC,IAAI,CAAC;qBACb;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAEjE,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5B,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,6BAA6B,IAAI,CAAC,YAAY,4CAA4C;yBACjG;qBACF;oBACD,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,0BAA0B,OAAO,EAAE;qBAC1C;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"register_app.js","sourceRoot":"","sources":["../../src/tools/register_app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,0IAA0I;QAC1I,8DAA8D;IAChE,WAAW,EAAE;QACX,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,CAAC,yEAAyE,CAAC;QACtF,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,CAAC,yCAAyC,CAAC;QACtD,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,CAAC,6CAA6C,CAAC;QAC1D,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,2CAA2C,CAAC;QACxD,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,0HAA0H,CAAC;QACvI,cAAc,EAAE,CAAC;aACd,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,QAAQ,EAAE;aACV,QAAQ,CAAC,0EAA0E,CAAC;QACvF,aAAa,EAAE,CAAC;aACb,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,QAAQ,EAAE;aACV,QAAQ,CAAC,iCAAiC,CAAC;QAC9C,aAAa,EAAE,CAAC;aACb,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,oHAAoH,CAAC;KAClI;IACD,OAAO,EAAE,KAAK,EAAE,IASf,EAAE,EAAE;QACH,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;YAEvC,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE;4BACJ,8BAA8B;4BAC9B,EAAE;4BACF,WAAW,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE;4BAC1B,iBAAiB,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE;4BAC1C,iBAAiB,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE;4BAC1C,WAAW,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE;4BAC9B,EAAE;4BACF,YAAY,MAAM,CAAC,OAAO,EAAE;4BAC5B,EAAE;4BACF,gEAAgE;4BAChE,wEAAwE;yBACzE,CAAC,IAAI,CAAC,IAAI,CAAC;qBACb;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAEjE,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5B,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,6BAA6B,IAAI,CAAC,YAAY,4CAA4C;yBACjG;qBACF;oBACD,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,0BAA0B,OAAO,EAAE;qBAC1C;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { z } from "zod";
2
+ export declare const requestUserDataTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ email: z.ZodString;
7
+ service: z.ZodString;
8
+ fields: z.ZodArray<z.ZodString>;
9
+ };
10
+ handler: (args: {
11
+ email: string;
12
+ service: string;
13
+ fields: string[];
14
+ }) => Promise<{
15
+ content: {
16
+ type: "text";
17
+ text: string;
18
+ }[];
19
+ isError?: undefined;
20
+ } | {
21
+ content: {
22
+ type: "text";
23
+ text: string;
24
+ }[];
25
+ isError: boolean;
26
+ }>;
27
+ };
@@ -0,0 +1,63 @@
1
+ import { z } from "zod";
2
+ import { checkIdentity, requestCredentials } from "../api-client.js";
3
+ export const requestUserDataTool = {
4
+ name: "request_user_data",
5
+ description: "Request verified data from a tru user (name, email, phone, address, banking). The user will be notified and must approve the request on their dashboard.",
6
+ inputSchema: {
7
+ email: z.string().describe("Email address of the tru user"),
8
+ service: z.string().describe("Name of the service requesting data"),
9
+ fields: z
10
+ .array(z.string())
11
+ .describe("List of fields to request, e.g. ['name', 'email', 'phone', 'address', 'banking']"),
12
+ },
13
+ handler: async (args) => {
14
+ try {
15
+ // First check if the user exists and is verified
16
+ const identity = await checkIdentity(args.email);
17
+ if (!identity.verified) {
18
+ const reason = identity.reason === "user_not_found"
19
+ ? "No tru account found for this email."
20
+ : identity.reason === "not_verified"
21
+ ? "This user has not completed tru identity verification."
22
+ : identity.reason === "no_vault"
23
+ ? "This user's credential vault is not populated."
24
+ : `User is not verified (${identity.reason}).`;
25
+ return {
26
+ content: [
27
+ {
28
+ type: "text",
29
+ text: `Cannot request user data: ${reason}`,
30
+ },
31
+ ],
32
+ };
33
+ }
34
+ // User is verified — create the data request
35
+ const request = await requestCredentials(args.email, args.service, args.fields);
36
+ const lines = [
37
+ `User data request created successfully.`,
38
+ ``,
39
+ `Request ID: ${request.id}`,
40
+ `User: ${args.email}`,
41
+ `Service: ${args.service}`,
42
+ `Fields requested: ${args.fields.join(", ")}`,
43
+ `Status: pending`,
44
+ ``,
45
+ `The user has been notified and must approve this request on their tru dashboard.`,
46
+ `Use the check_request_status tool with request ID "${request.id}" to check if the user has responded.`,
47
+ ];
48
+ return {
49
+ content: [{ type: "text", text: lines.join("\n") }],
50
+ };
51
+ }
52
+ catch (err) {
53
+ const message = err instanceof Error ? err.message : String(err);
54
+ return {
55
+ content: [
56
+ { type: "text", text: `Error requesting user data: ${message}` },
57
+ ],
58
+ isError: true,
59
+ };
60
+ }
61
+ },
62
+ };
63
+ //# sourceMappingURL=request_user_data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request_user_data.js","sourceRoot":"","sources":["../../src/tools/request_user_data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAErE,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,mBAAmB;IACzB,WAAW,EACT,0JAA0J;IAC5J,WAAW,EAAE;QACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;QAC3D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;QACnE,MAAM,EAAE,CAAC;aACN,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,QAAQ,CACP,kFAAkF,CACnF;KACJ;IACD,OAAO,EAAE,KAAK,EAAE,IAA0D,EAAE,EAAE;QAC5E,IAAI,CAAC;YACH,iDAAiD;YACjD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAEjD,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACvB,MAAM,MAAM,GACV,QAAQ,CAAC,MAAM,KAAK,gBAAgB;oBAClC,CAAC,CAAC,sCAAsC;oBACxC,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,cAAc;wBAClC,CAAC,CAAC,wDAAwD;wBAC1D,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,UAAU;4BAC9B,CAAC,CAAC,gDAAgD;4BAClD,CAAC,CAAC,yBAAyB,QAAQ,CAAC,MAAM,IAAI,CAAC;gBAEvD,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,6BAA6B,MAAM,EAAE;yBAC5C;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,6CAA6C;YAC7C,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAEhF,MAAM,KAAK,GAAG;gBACZ,yCAAyC;gBACzC,EAAE;gBACF,eAAe,OAAO,CAAC,EAAE,EAAE;gBAC3B,SAAS,IAAI,CAAC,KAAK,EAAE;gBACrB,YAAY,IAAI,CAAC,OAAO,EAAE;gBAC1B,qBAAqB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBAC7C,iBAAiB;gBACjB,EAAE;gBACF,kFAAkF;gBAClF,sDAAsD,OAAO,CAAC,EAAE,uCAAuC;aACxG,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;aAC7D,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,+BAA+B,OAAO,EAAE,EAAE;iBAC1E;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tru-mcp",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "MCP server for tru — auth, billing, and risk signals in one API",
5
5
  "type": "module",
6
6
  "bin": {