tru-mcp 0.3.0 → 0.4.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/dist/api-client.d.ts +24 -3
- package/dist/api-client.js +48 -5
- package/dist/api-client.js.map +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.js +63 -0
- package/dist/config.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +12 -0
- package/dist/server.js.map +1 -1
- package/dist/tools/authenticate.d.ts +18 -0
- package/dist/tools/authenticate.js +100 -0
- package/dist/tools/authenticate.js.map +1 -0
- package/dist/tools/create_charge.d.ts +4 -0
- package/dist/tools/create_charge.js +47 -1
- package/dist/tools/create_charge.js.map +1 -1
- package/dist/tools/get_started.js +13 -3
- package/dist/tools/get_started.js.map +1 -1
- package/dist/tools/register_app.d.ts +2 -4
- package/dist/tools/register_app.js +88 -20
- package/dist/tools/register_app.js.map +1 -1
- package/dist/tools/request_virtual_card.d.ts +4 -0
- package/dist/tools/request_virtual_card.js +47 -1
- package/dist/tools/request_virtual_card.js.map +1 -1
- package/package.json +1 -1
package/dist/api-client.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export interface ChargeResponse {
|
|
|
41
41
|
};
|
|
42
42
|
[key: string]: unknown;
|
|
43
43
|
}
|
|
44
|
-
export declare function createCharge(email: string, amountCents: number, description?: string, type?: string, interval?: string, currency?: string, paymentMode?: string, action?: string): Promise<ChargeResponse>;
|
|
44
|
+
export declare function createCharge(email: string, amountCents: number, description?: string, type?: string, interval?: string, currency?: string, paymentMode?: string, action?: string, appId?: string, sourceLabel?: string): Promise<ChargeResponse>;
|
|
45
45
|
export interface AgentCardResponse {
|
|
46
46
|
status: "issued" | "escalated";
|
|
47
47
|
charge_request_id: string;
|
|
@@ -74,7 +74,7 @@ export declare function lookupAppByServiceName(serviceName: string): Promise<App
|
|
|
74
74
|
export interface RegisterAppParams {
|
|
75
75
|
service_name: string;
|
|
76
76
|
display_name: string;
|
|
77
|
-
owner_email
|
|
77
|
+
owner_email?: string;
|
|
78
78
|
description?: string;
|
|
79
79
|
website?: string;
|
|
80
80
|
allowed_fields?: string[];
|
|
@@ -131,5 +131,26 @@ export interface AppCredentialsResponse {
|
|
|
131
131
|
}
|
|
132
132
|
export declare function provisionUser(email: string, serviceName: string): Promise<ProvisionResponse>;
|
|
133
133
|
export declare function getAppCredentials(email: string, serviceName: string): Promise<AppCredentialsResponse>;
|
|
134
|
-
export declare function requestAgentCard(email: string, amountCents: number, description?: string, targetService?: string, currency?: string, action?: string): Promise<AgentCardResponse>;
|
|
134
|
+
export declare function requestAgentCard(email: string, amountCents: number, description?: string, targetService?: string, currency?: string, action?: string, appId?: string, sourceLabel?: string): Promise<AgentCardResponse>;
|
|
135
|
+
export interface McpSessionResponse {
|
|
136
|
+
code: string;
|
|
137
|
+
login_url: string;
|
|
138
|
+
}
|
|
139
|
+
export interface McpSessionStatus {
|
|
140
|
+
status: "pending" | "complete";
|
|
141
|
+
token?: string;
|
|
142
|
+
user?: {
|
|
143
|
+
id: string;
|
|
144
|
+
email: string;
|
|
145
|
+
name: string;
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
export declare function createMcpSession(): Promise<McpSessionResponse>;
|
|
149
|
+
export declare function pollMcpSession(code: string): Promise<McpSessionStatus>;
|
|
150
|
+
export declare function verifyAuth(token: string): Promise<{
|
|
151
|
+
id: string;
|
|
152
|
+
email: string;
|
|
153
|
+
name: string;
|
|
154
|
+
}>;
|
|
155
|
+
export declare function registerAppAuthenticated(params: Omit<RegisterAppParams, "owner_email">, token: string): Promise<RegisterAppResponse>;
|
|
135
156
|
export {};
|
package/dist/api-client.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
const BASE_URL = process.env.TRU_API_URL || "http://localhost:3000";
|
|
2
|
-
|
|
2
|
+
// API key is read dynamically so register_app can set it at runtime
|
|
3
|
+
function getApiKey() {
|
|
4
|
+
return process.env.TRU_API_KEY || "";
|
|
5
|
+
}
|
|
3
6
|
async function request(path, options = {}) {
|
|
4
7
|
const url = `${BASE_URL}${path}`;
|
|
5
8
|
const res = await fetch(url, {
|
|
6
9
|
...options,
|
|
7
10
|
headers: {
|
|
8
11
|
"Content-Type": "application/json",
|
|
9
|
-
"X-API-Key":
|
|
12
|
+
"X-API-Key": getApiKey(),
|
|
10
13
|
...options.headers,
|
|
11
14
|
},
|
|
12
15
|
});
|
|
@@ -32,7 +35,7 @@ export async function requestCredentials(email, service, fields) {
|
|
|
32
35
|
export async function getRequestStatus(id) {
|
|
33
36
|
return (await request(`/api/credentials/${encodeURIComponent(id)}`));
|
|
34
37
|
}
|
|
35
|
-
export async function createCharge(email, amountCents, description, type, interval, currency, paymentMode, action) {
|
|
38
|
+
export async function createCharge(email, amountCents, description, type, interval, currency, paymentMode, action, appId, sourceLabel) {
|
|
36
39
|
return (await request("/api/billing/charges", {
|
|
37
40
|
method: "POST",
|
|
38
41
|
body: JSON.stringify({
|
|
@@ -44,6 +47,8 @@ export async function createCharge(email, amountCents, description, type, interv
|
|
|
44
47
|
interval,
|
|
45
48
|
payment_mode: paymentMode || "direct",
|
|
46
49
|
action,
|
|
50
|
+
app_id: appId,
|
|
51
|
+
source_label: sourceLabel,
|
|
47
52
|
}),
|
|
48
53
|
}));
|
|
49
54
|
}
|
|
@@ -68,7 +73,7 @@ export async function discoverApi(serviceName) {
|
|
|
68
73
|
method: "POST",
|
|
69
74
|
headers: {
|
|
70
75
|
"Content-Type": "application/json",
|
|
71
|
-
"X-API-Key":
|
|
76
|
+
"X-API-Key": getApiKey(),
|
|
72
77
|
},
|
|
73
78
|
});
|
|
74
79
|
if (!res.ok) {
|
|
@@ -109,7 +114,7 @@ export async function provisionUser(email, serviceName) {
|
|
|
109
114
|
export async function getAppCredentials(email, serviceName) {
|
|
110
115
|
return (await request(`/api/apps/by-service/${encodeURIComponent(serviceName)}/credentials/${encodeURIComponent(email)}`));
|
|
111
116
|
}
|
|
112
|
-
export async function requestAgentCard(email, amountCents, description, targetService, currency, action) {
|
|
117
|
+
export async function requestAgentCard(email, amountCents, description, targetService, currency, action, appId, sourceLabel) {
|
|
113
118
|
return (await request("/api/billing/agent-card", {
|
|
114
119
|
method: "POST",
|
|
115
120
|
body: JSON.stringify({
|
|
@@ -119,7 +124,45 @@ export async function requestAgentCard(email, amountCents, description, targetSe
|
|
|
119
124
|
description,
|
|
120
125
|
target_service: targetService,
|
|
121
126
|
action,
|
|
127
|
+
app_id: appId,
|
|
128
|
+
source_label: sourceLabel,
|
|
122
129
|
}),
|
|
123
130
|
}));
|
|
124
131
|
}
|
|
132
|
+
export async function createMcpSession() {
|
|
133
|
+
return (await request("/api/auth/mcp-session", {
|
|
134
|
+
method: "POST",
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
export async function pollMcpSession(code) {
|
|
138
|
+
return (await request(`/api/auth/mcp-session/${encodeURIComponent(code)}`));
|
|
139
|
+
}
|
|
140
|
+
export async function verifyAuth(token) {
|
|
141
|
+
const url = `${BASE_URL}/api/auth/me`;
|
|
142
|
+
const res = await fetch(url, {
|
|
143
|
+
headers: {
|
|
144
|
+
"Authorization": `Bearer ${token}`,
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
if (!res.ok) {
|
|
148
|
+
throw new Error(`Auth verification failed: ${res.status}`);
|
|
149
|
+
}
|
|
150
|
+
return res.json();
|
|
151
|
+
}
|
|
152
|
+
export async function registerAppAuthenticated(params, token) {
|
|
153
|
+
const url = `${BASE_URL}/api/apps`;
|
|
154
|
+
const res = await fetch(url, {
|
|
155
|
+
method: "POST",
|
|
156
|
+
headers: {
|
|
157
|
+
"Content-Type": "application/json",
|
|
158
|
+
"Authorization": `Bearer ${token}`,
|
|
159
|
+
},
|
|
160
|
+
body: JSON.stringify(params),
|
|
161
|
+
});
|
|
162
|
+
if (!res.ok) {
|
|
163
|
+
const body = await res.text();
|
|
164
|
+
throw new Error(`API error ${res.status}: ${body}`);
|
|
165
|
+
}
|
|
166
|
+
return res.json();
|
|
167
|
+
}
|
|
125
168
|
//# sourceMappingURL=api-client.js.map
|
package/dist/api-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,uBAAuB,CAAC;AACpE,
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function readConfig(): Record<string, unknown>;
|
|
2
|
+
export declare function writeConfig(config: Record<string, unknown>): void;
|
|
3
|
+
export declare function getStoredAuth(): {
|
|
4
|
+
token: string;
|
|
5
|
+
email: string;
|
|
6
|
+
} | null;
|
|
7
|
+
export declare function saveAuth(token: string, email: string): void;
|
|
8
|
+
export declare function setClientName(name: string): void;
|
|
9
|
+
export declare function getSourceLabel(): string | null;
|
|
10
|
+
export declare function saveSourceLabel(label: string): void;
|
|
11
|
+
export declare function getSuggestedLabel(): string;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import os from "os";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
const CONFIG_PATH = path.join(os.homedir(), ".tru", "config.json");
|
|
6
|
+
export function readConfig() {
|
|
7
|
+
try {
|
|
8
|
+
return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8"));
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return {};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function writeConfig(config) {
|
|
15
|
+
const dir = path.dirname(CONFIG_PATH);
|
|
16
|
+
if (!fs.existsSync(dir))
|
|
17
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
18
|
+
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
19
|
+
}
|
|
20
|
+
// ─── Auth helpers ────────────────────────────────────────────────
|
|
21
|
+
export function getStoredAuth() {
|
|
22
|
+
const config = readConfig();
|
|
23
|
+
const auth = config.auth;
|
|
24
|
+
if (auth?.token && auth?.email) {
|
|
25
|
+
return { token: auth.token, email: auth.email };
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
export function saveAuth(token, email) {
|
|
30
|
+
const config = readConfig();
|
|
31
|
+
config.auth = { token, email };
|
|
32
|
+
writeConfig(config);
|
|
33
|
+
}
|
|
34
|
+
// ─── Source label helpers ────────────────────────────────────────
|
|
35
|
+
function getComputerName() {
|
|
36
|
+
try {
|
|
37
|
+
return execSync("scutil --get ComputerName", { encoding: "utf-8" }).trim();
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return os.hostname();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
let clientName = "Unknown Client";
|
|
44
|
+
export function setClientName(name) {
|
|
45
|
+
clientName = name;
|
|
46
|
+
}
|
|
47
|
+
export function getSourceLabel() {
|
|
48
|
+
const config = readConfig();
|
|
49
|
+
const labels = (config.source_labels || {});
|
|
50
|
+
return labels[clientName] || null;
|
|
51
|
+
}
|
|
52
|
+
export function saveSourceLabel(label) {
|
|
53
|
+
const config = readConfig();
|
|
54
|
+
const labels = (config.source_labels || {});
|
|
55
|
+
labels[clientName] = label;
|
|
56
|
+
config.source_labels = labels;
|
|
57
|
+
writeConfig(config);
|
|
58
|
+
}
|
|
59
|
+
export function getSuggestedLabel() {
|
|
60
|
+
const computerName = getComputerName();
|
|
61
|
+
return `${clientName} \u2014 ${computerName}`;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
package/dist/server.js
CHANGED
|
@@ -14,11 +14,16 @@ import { connectStripeTool } from "./tools/connect_stripe.js";
|
|
|
14
14
|
import { getStartedTool } from "./tools/get_started.js";
|
|
15
15
|
import { discoverApiTool } from "./tools/discover_api.js";
|
|
16
16
|
import { provisionUserTool } from "./tools/provision_user.js";
|
|
17
|
+
import { authenticateTool } from "./tools/authenticate.js";
|
|
18
|
+
import { setClientName, getSourceLabel, saveSourceLabel, getSuggestedLabel, } from "./config.js";
|
|
19
|
+
// Re-export source label functions so existing tool imports work
|
|
20
|
+
export { getSourceLabel, saveSourceLabel, getSuggestedLabel };
|
|
17
21
|
const server = new McpServer({
|
|
18
22
|
name: "tru-identity",
|
|
19
23
|
version: "0.1.0",
|
|
20
24
|
});
|
|
21
25
|
// Register tools
|
|
26
|
+
server.tool(authenticateTool.name, authenticateTool.description, authenticateTool.inputSchema, authenticateTool.handler);
|
|
22
27
|
server.tool(checkIdentityTool.name, checkIdentityTool.description, checkIdentityTool.inputSchema, checkIdentityTool.handler);
|
|
23
28
|
server.tool(requestUserDataTool.name, requestUserDataTool.description, requestUserDataTool.inputSchema, requestUserDataTool.handler);
|
|
24
29
|
server.tool(checkRequestStatusTool.name, checkRequestStatusTool.description, checkRequestStatusTool.inputSchema, checkRequestStatusTool.handler);
|
|
@@ -36,6 +41,13 @@ server.tool(provisionUserTool.name, provisionUserTool.description, provisionUser
|
|
|
36
41
|
export async function run() {
|
|
37
42
|
const transport = new StdioServerTransport();
|
|
38
43
|
await server.connect(transport);
|
|
44
|
+
// Capture client info (e.g. "Claude Code", "Cursor") for source label
|
|
45
|
+
try {
|
|
46
|
+
const info = server.server?.getClientVersion?.();
|
|
47
|
+
if (info?.name)
|
|
48
|
+
setClientName(info.name);
|
|
49
|
+
}
|
|
50
|
+
catch { }
|
|
39
51
|
console.error("tru-identity MCP server running on stdio");
|
|
40
52
|
}
|
|
41
53
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -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,18 @@
|
|
|
1
|
+
export declare const authenticateTool: {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
inputSchema: {};
|
|
5
|
+
handler: (_args: Record<string, never>) => Promise<{
|
|
6
|
+
content: {
|
|
7
|
+
type: "text";
|
|
8
|
+
text: string;
|
|
9
|
+
}[];
|
|
10
|
+
isError?: undefined;
|
|
11
|
+
} | {
|
|
12
|
+
content: {
|
|
13
|
+
type: "text";
|
|
14
|
+
text: string;
|
|
15
|
+
}[];
|
|
16
|
+
isError: boolean;
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { getStoredAuth, saveAuth } from "../config.js";
|
|
2
|
+
import { createMcpSession, pollMcpSession, verifyAuth } from "../api-client.js";
|
|
3
|
+
function sleep(ms) {
|
|
4
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5
|
+
}
|
|
6
|
+
export const authenticateTool = {
|
|
7
|
+
name: "authenticate",
|
|
8
|
+
description: "[Developer tool] Authenticate with tru via the browser. Required before registering apps. " +
|
|
9
|
+
"Opens a login URL where you verify your identity, then polls until authentication is complete. " +
|
|
10
|
+
"Credentials are stored locally for future sessions.",
|
|
11
|
+
inputSchema: {},
|
|
12
|
+
handler: async (_args) => {
|
|
13
|
+
try {
|
|
14
|
+
// Check if already authenticated
|
|
15
|
+
const stored = getStoredAuth();
|
|
16
|
+
if (stored) {
|
|
17
|
+
try {
|
|
18
|
+
const user = await verifyAuth(stored.token);
|
|
19
|
+
return {
|
|
20
|
+
content: [
|
|
21
|
+
{
|
|
22
|
+
type: "text",
|
|
23
|
+
text: `Already authenticated as ${user.email}.`,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Token expired or invalid, continue to re-authenticate
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Create a new MCP session
|
|
33
|
+
const session = await createMcpSession();
|
|
34
|
+
// Poll for completion (every 2s, up to 5 min)
|
|
35
|
+
const maxAttempts = 150; // 5 minutes at 2s intervals
|
|
36
|
+
let attempts = 0;
|
|
37
|
+
// Return the URL immediately with polling
|
|
38
|
+
const lines = [
|
|
39
|
+
`Open this URL in your browser to authenticate:`,
|
|
40
|
+
``,
|
|
41
|
+
`${session.login_url}`,
|
|
42
|
+
``,
|
|
43
|
+
`Waiting for authentication...`,
|
|
44
|
+
];
|
|
45
|
+
// We need to poll synchronously within the handler
|
|
46
|
+
while (attempts < maxAttempts) {
|
|
47
|
+
await sleep(2000);
|
|
48
|
+
attempts++;
|
|
49
|
+
try {
|
|
50
|
+
const status = await pollMcpSession(session.code);
|
|
51
|
+
if (status.status === "complete" && status.token && status.user) {
|
|
52
|
+
saveAuth(status.token, status.user.email);
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: "text",
|
|
57
|
+
text: [
|
|
58
|
+
...lines,
|
|
59
|
+
``,
|
|
60
|
+
`Authenticated successfully as ${status.user.email}.`,
|
|
61
|
+
`Credentials saved locally. You can now register apps.`,
|
|
62
|
+
].join("\n"),
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Session might have expired, keep trying
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{
|
|
75
|
+
type: "text",
|
|
76
|
+
text: [
|
|
77
|
+
...lines,
|
|
78
|
+
``,
|
|
79
|
+
`Authentication timed out after 5 minutes. Please try again.`,
|
|
80
|
+
].join("\n"),
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
isError: true,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
88
|
+
return {
|
|
89
|
+
content: [
|
|
90
|
+
{
|
|
91
|
+
type: "text",
|
|
92
|
+
text: `Error during authentication: ${message}`,
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
isError: true,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=authenticate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authenticate.js","sourceRoot":"","sources":["../../src/tools/authenticate.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,8 @@ export declare const createChargeTool: {
|
|
|
20
20
|
virtual_card: "virtual_card";
|
|
21
21
|
}>>;
|
|
22
22
|
action: z.ZodOptional<z.ZodString>;
|
|
23
|
+
app_id: z.ZodOptional<z.ZodString>;
|
|
24
|
+
source_label: z.ZodOptional<z.ZodString>;
|
|
23
25
|
};
|
|
24
26
|
handler: (args: {
|
|
25
27
|
email: string;
|
|
@@ -30,6 +32,8 @@ export declare const createChargeTool: {
|
|
|
30
32
|
currency?: string;
|
|
31
33
|
payment_mode?: "direct" | "virtual_card";
|
|
32
34
|
action?: string;
|
|
35
|
+
app_id?: string;
|
|
36
|
+
source_label?: string;
|
|
33
37
|
}) => Promise<{
|
|
34
38
|
content: {
|
|
35
39
|
type: "text";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { createCharge } from "../api-client.js";
|
|
3
|
+
import { getSourceLabel, saveSourceLabel, getSuggestedLabel } from "../server.js";
|
|
3
4
|
export const createChargeTool = {
|
|
4
5
|
name: "create_charge",
|
|
5
6
|
description: "Create a direct charge or subscription on behalf of a user. " +
|
|
@@ -39,10 +40,55 @@ export const createChargeTool = {
|
|
|
39
40
|
.string()
|
|
40
41
|
.optional()
|
|
41
42
|
.describe("The action being performed (e.g. 'purchase products', 'create subscription'). Used to evaluate action permission rules."),
|
|
43
|
+
app_id: z
|
|
44
|
+
.string()
|
|
45
|
+
.optional()
|
|
46
|
+
.describe("The tru app ID to charge as (required when using shared API key)"),
|
|
47
|
+
source_label: z
|
|
48
|
+
.string()
|
|
49
|
+
.optional()
|
|
50
|
+
.describe("Label identifying the source of this personal charge (e.g. 'Claude Code — David's MacBook Pro'). Required for personal charges without an app_id. On first use, omit this to get a suggested label."),
|
|
42
51
|
},
|
|
43
52
|
handler: async (args) => {
|
|
44
53
|
try {
|
|
45
|
-
|
|
54
|
+
// Resolve source_label for personal charges (no app_id)
|
|
55
|
+
let sourceLabel = args.source_label;
|
|
56
|
+
if (!args.app_id) {
|
|
57
|
+
if (sourceLabel) {
|
|
58
|
+
// User confirmed a label — save it for future use
|
|
59
|
+
saveSourceLabel(sourceLabel);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// Check for stored label
|
|
63
|
+
const stored = getSourceLabel();
|
|
64
|
+
if (stored) {
|
|
65
|
+
sourceLabel = stored;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// First use — return confirmation prompt
|
|
69
|
+
const suggested = getSuggestedLabel();
|
|
70
|
+
return {
|
|
71
|
+
content: [
|
|
72
|
+
{
|
|
73
|
+
type: "text",
|
|
74
|
+
text: [
|
|
75
|
+
`Before processing, I need a label for charges from this device and tool.`,
|
|
76
|
+
`Suggested: **${suggested}**`,
|
|
77
|
+
``,
|
|
78
|
+
`This label appears in your tru wallet so you can tell where each charge came from.`,
|
|
79
|
+
`Confirm this name, or type a custom one.`,
|
|
80
|
+
``,
|
|
81
|
+
`_If you're building a service for others, consider registering a tru app instead — it gives you a dedicated identity with custom branding._`,
|
|
82
|
+
``,
|
|
83
|
+
`To proceed, call this tool again with source_label set to your chosen label.`,
|
|
84
|
+
].join("\n"),
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const result = await createCharge(args.email, args.amount_cents, args.description, args.type, args.interval, args.currency, args.payment_mode, args.action, args.app_id, sourceLabel);
|
|
46
92
|
const amount = (args.amount_cents / 100).toFixed(2);
|
|
47
93
|
const currencyLabel = (args.currency || "usd").toUpperCase();
|
|
48
94
|
const chargeType = args.type === "recurring"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create_charge.js","sourceRoot":"","sources":["../../src/tools/create_charge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"create_charge.js","sourceRoot":"","sources":["../../src/tools/create_charge.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,7 +37,15 @@ Users set their own spending rules ("auto-approve charges under $10 from this ap
|
|
|
37
37
|
|
|
38
38
|
## Setup (5 minutes)
|
|
39
39
|
|
|
40
|
-
You'll use
|
|
40
|
+
You'll use a few MCP tools, in order. Each one takes about a minute.
|
|
41
|
+
|
|
42
|
+
### Step 0: Authenticate
|
|
43
|
+
|
|
44
|
+
\`\`\`
|
|
45
|
+
authenticate()
|
|
46
|
+
\`\`\`
|
|
47
|
+
|
|
48
|
+
This opens a browser window where you verify your identity with tru. Your credentials are stored locally so you only need to do this once (they last 7 days).
|
|
41
49
|
|
|
42
50
|
### Step 1: Register your app
|
|
43
51
|
|
|
@@ -45,13 +53,14 @@ You'll use three MCP tools, in order. Each one takes about a minute.
|
|
|
45
53
|
register_app(
|
|
46
54
|
service_name: "my-app",
|
|
47
55
|
display_name: "My App",
|
|
48
|
-
owner_email: "you@example.com",
|
|
49
56
|
description: "What your app does",
|
|
50
57
|
website: "https://myapp.com"
|
|
51
58
|
)
|
|
52
59
|
\`\`\`
|
|
53
60
|
|
|
54
|
-
This creates your app on tru and returns an **API key** (starts with \`tru_ak_\`).
|
|
61
|
+
This creates your app on tru and returns an **API key** (starts with \`tru_ak_\`). The key is automatically:
|
|
62
|
+
- **Set for this session** — all subsequent tru tools work immediately
|
|
63
|
+
- **Saved to your MCP config** — future sessions pick it up without manual steps
|
|
55
64
|
|
|
56
65
|
The \`service_name\` is your app's unique identifier on tru (lowercase, letters/numbers/hyphens).
|
|
57
66
|
|
|
@@ -228,6 +237,7 @@ provision_user(email: "user@example.com", service_name: "my-app")
|
|
|
228
237
|
| Tool | Purpose |
|
|
229
238
|
|------|---------|
|
|
230
239
|
| \`get_started\` | This guide |
|
|
240
|
+
| \`authenticate\` | Verify your identity (required before registering apps) |
|
|
231
241
|
| \`register_app\` | Create your app, get API key |
|
|
232
242
|
| \`connect_stripe\` | Link your Stripe account |
|
|
233
243
|
| \`discover_api\` | Crawl your site, generate agent skill |
|
|
@@ -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,wGAAwG;QACxG,uEAAuE;QACvE,0DAA0D;IAC5D,WAAW,EAAE,EAAE;IACf,OAAO,EAAE,KAAK,EAAE,KAA4B,EAAE,EAAE;QAC9C,MAAM,KAAK,GAAG
|
|
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoPjB,CAAC;QAEE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;SAClD,CAAC;IACJ,CAAC;CACF,CAAC"}
|
|
@@ -5,7 +5,6 @@ export declare const registerAppTool: {
|
|
|
5
5
|
inputSchema: {
|
|
6
6
|
service_name: z.ZodString;
|
|
7
7
|
display_name: z.ZodString;
|
|
8
|
-
owner_email: z.ZodString;
|
|
9
8
|
description: z.ZodOptional<z.ZodString>;
|
|
10
9
|
website: z.ZodOptional<z.ZodString>;
|
|
11
10
|
allowed_fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -15,7 +14,6 @@ export declare const registerAppTool: {
|
|
|
15
14
|
handler: (args: {
|
|
16
15
|
service_name: string;
|
|
17
16
|
display_name: string;
|
|
18
|
-
owner_email: string;
|
|
19
17
|
description?: string;
|
|
20
18
|
website?: string;
|
|
21
19
|
allowed_fields?: string[];
|
|
@@ -26,12 +24,12 @@ export declare const registerAppTool: {
|
|
|
26
24
|
type: "text";
|
|
27
25
|
text: string;
|
|
28
26
|
}[];
|
|
29
|
-
isError
|
|
27
|
+
isError: boolean;
|
|
30
28
|
} | {
|
|
31
29
|
content: {
|
|
32
30
|
type: "text";
|
|
33
31
|
text: string;
|
|
34
32
|
}[];
|
|
35
|
-
isError
|
|
33
|
+
isError?: undefined;
|
|
36
34
|
}>;
|
|
37
35
|
};
|
|
@@ -1,9 +1,47 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
2
|
+
import { readFile, writeFile, access } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { registerAppAuthenticated } from "../api-client.js";
|
|
6
|
+
import { getStoredAuth } from "../config.js";
|
|
7
|
+
/** Find and update tru API key in MCP config files */
|
|
8
|
+
async function persistApiKey(apiKey) {
|
|
9
|
+
const cwd = process.cwd();
|
|
10
|
+
const home = homedir();
|
|
11
|
+
const platform = process.platform;
|
|
12
|
+
const paths = [
|
|
13
|
+
join(cwd, ".mcp.json"),
|
|
14
|
+
join(cwd, ".cursor", "mcp.json"),
|
|
15
|
+
platform === "darwin"
|
|
16
|
+
? join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json")
|
|
17
|
+
: platform === "win32"
|
|
18
|
+
? join(home, "AppData", "Roaming", "Claude", "claude_desktop_config.json")
|
|
19
|
+
: join(home, ".config", "Claude", "claude_desktop_config.json"),
|
|
20
|
+
];
|
|
21
|
+
const updated = [];
|
|
22
|
+
for (const p of paths) {
|
|
23
|
+
try {
|
|
24
|
+
await access(p);
|
|
25
|
+
const raw = await readFile(p, "utf-8");
|
|
26
|
+
const config = JSON.parse(raw);
|
|
27
|
+
if (config.mcpServers?.tru) {
|
|
28
|
+
if (!config.mcpServers.tru.env)
|
|
29
|
+
config.mcpServers.tru.env = {};
|
|
30
|
+
config.mcpServers.tru.env.TRU_API_KEY = apiKey;
|
|
31
|
+
await writeFile(p, JSON.stringify(config, null, 2) + "\n");
|
|
32
|
+
updated.push(p);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// File doesn't exist or isn't valid JSON — skip
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return updated;
|
|
40
|
+
}
|
|
3
41
|
export const registerAppTool = {
|
|
4
42
|
name: "register_app",
|
|
5
|
-
description: "[Developer tool] Register a new app on the tru platform.
|
|
6
|
-
"Returns an API key
|
|
43
|
+
description: "[Developer tool] Register a new app on the tru platform. Requires authentication (run `authenticate` first). " +
|
|
44
|
+
"Returns an API key and automatically configures it for this session and in MCP config files.",
|
|
7
45
|
inputSchema: {
|
|
8
46
|
service_name: z
|
|
9
47
|
.string()
|
|
@@ -11,9 +49,6 @@ export const registerAppTool = {
|
|
|
11
49
|
display_name: z
|
|
12
50
|
.string()
|
|
13
51
|
.describe("Human-friendly display name for the app"),
|
|
14
|
-
owner_email: z
|
|
15
|
-
.string()
|
|
16
|
-
.describe("Email of the tru user who will own this app"),
|
|
17
52
|
description: z
|
|
18
53
|
.string()
|
|
19
54
|
.optional()
|
|
@@ -36,25 +71,47 @@ export const registerAppTool = {
|
|
|
36
71
|
.describe("URL of your provision endpoint. tru POSTs { email, name, tru_user_id } here to auto-create accounts for tru users."),
|
|
37
72
|
},
|
|
38
73
|
handler: async (args) => {
|
|
74
|
+
// Check for stored auth
|
|
75
|
+
const auth = getStoredAuth();
|
|
76
|
+
if (!auth) {
|
|
77
|
+
return {
|
|
78
|
+
content: [
|
|
79
|
+
{
|
|
80
|
+
type: "text",
|
|
81
|
+
text: "You need to authenticate before registering an app. Run the `authenticate` tool first — it will open a browser window where you can verify your identity with tru.",
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
isError: true,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
39
87
|
try {
|
|
40
|
-
const result = await
|
|
88
|
+
const result = await registerAppAuthenticated(args, auth.token);
|
|
89
|
+
// Set key in-memory so subsequent tools work without restart
|
|
90
|
+
process.env.TRU_API_KEY = result.api_key;
|
|
91
|
+
// Persist key to MCP config files for future sessions
|
|
92
|
+
const configsUpdated = await persistApiKey(result.api_key);
|
|
93
|
+
const lines = [
|
|
94
|
+
`App registered successfully.`,
|
|
95
|
+
``,
|
|
96
|
+
`App ID: ${result.app.id}`,
|
|
97
|
+
`Service name: ${result.app.service_name}`,
|
|
98
|
+
`Display name: ${result.app.display_name}`,
|
|
99
|
+
`Owner: ${auth.email}`,
|
|
100
|
+
`Status: ${result.app.status}`,
|
|
101
|
+
``,
|
|
102
|
+
`API Key: ${result.api_key}`,
|
|
103
|
+
];
|
|
104
|
+
if (configsUpdated.length > 0) {
|
|
105
|
+
lines.push(``, `API key auto-saved to:`, ...configsUpdated.map((p) => ` ${p}`), ``, `This session is already configured. Future sessions will pick up the key automatically.`);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
lines.push(``, `This session is configured. To persist the key for future sessions, add TRU_API_KEY to your MCP config.`);
|
|
109
|
+
}
|
|
41
110
|
return {
|
|
42
111
|
content: [
|
|
43
112
|
{
|
|
44
113
|
type: "text",
|
|
45
|
-
text:
|
|
46
|
-
`App registered successfully.`,
|
|
47
|
-
``,
|
|
48
|
-
`App ID: ${result.app.id}`,
|
|
49
|
-
`Service name: ${result.app.service_name}`,
|
|
50
|
-
`Display name: ${result.app.display_name}`,
|
|
51
|
-
`Status: ${result.app.status}`,
|
|
52
|
-
``,
|
|
53
|
-
`API Key: ${result.api_key}`,
|
|
54
|
-
``,
|
|
55
|
-
`WARNING: Save this API key now — it cannot be retrieved later.`,
|
|
56
|
-
`Use it as TRU_API_KEY when configuring the tru MCP server or REST API.`,
|
|
57
|
-
].join("\n"),
|
|
114
|
+
text: lines.join("\n"),
|
|
58
115
|
},
|
|
59
116
|
],
|
|
60
117
|
};
|
|
@@ -72,6 +129,17 @@ export const registerAppTool = {
|
|
|
72
129
|
isError: true,
|
|
73
130
|
};
|
|
74
131
|
}
|
|
132
|
+
if (message.includes("401") || message.includes("403")) {
|
|
133
|
+
return {
|
|
134
|
+
content: [
|
|
135
|
+
{
|
|
136
|
+
type: "text",
|
|
137
|
+
text: `Authentication expired or invalid. Run \`authenticate\` again to re-verify your identity.`,
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
isError: true,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
75
143
|
return {
|
|
76
144
|
content: [
|
|
77
145
|
{
|
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"register_app.js","sourceRoot":"","sources":["../../src/tools/register_app.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,8 @@ export declare const requestVirtualCardTool: {
|
|
|
9
9
|
target_service: z.ZodOptional<z.ZodString>;
|
|
10
10
|
currency: z.ZodOptional<z.ZodString>;
|
|
11
11
|
action: z.ZodOptional<z.ZodString>;
|
|
12
|
+
app_id: z.ZodOptional<z.ZodString>;
|
|
13
|
+
source_label: z.ZodOptional<z.ZodString>;
|
|
12
14
|
};
|
|
13
15
|
handler: (args: {
|
|
14
16
|
email: string;
|
|
@@ -17,6 +19,8 @@ export declare const requestVirtualCardTool: {
|
|
|
17
19
|
target_service?: string;
|
|
18
20
|
currency?: string;
|
|
19
21
|
action?: string;
|
|
22
|
+
app_id?: string;
|
|
23
|
+
source_label?: string;
|
|
20
24
|
}) => Promise<{
|
|
21
25
|
content: {
|
|
22
26
|
type: "text";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { requestAgentCard } from "../api-client.js";
|
|
3
|
+
import { getSourceLabel, saveSourceLabel, getSuggestedLabel } from "../server.js";
|
|
3
4
|
export const requestVirtualCardTool = {
|
|
4
5
|
name: "request_virtual_card",
|
|
5
6
|
description: "Request a one-time virtual card to make a purchase on behalf of a user. " +
|
|
@@ -30,10 +31,55 @@ export const requestVirtualCardTool = {
|
|
|
30
31
|
.string()
|
|
31
32
|
.optional()
|
|
32
33
|
.describe("The action being performed (e.g. 'purchase products', 'book flight'). Used to evaluate action permission rules."),
|
|
34
|
+
app_id: z
|
|
35
|
+
.string()
|
|
36
|
+
.optional()
|
|
37
|
+
.describe("The tru app ID to charge as (required when using shared API key)"),
|
|
38
|
+
source_label: z
|
|
39
|
+
.string()
|
|
40
|
+
.optional()
|
|
41
|
+
.describe("Label identifying the source of this personal charge (e.g. 'Claude Code — David's MacBook Pro'). Required for personal charges without an app_id. On first use, omit this to get a suggested label."),
|
|
33
42
|
},
|
|
34
43
|
handler: async (args) => {
|
|
35
44
|
try {
|
|
36
|
-
|
|
45
|
+
// Resolve source_label for personal charges (no app_id)
|
|
46
|
+
let sourceLabel = args.source_label;
|
|
47
|
+
if (!args.app_id) {
|
|
48
|
+
if (sourceLabel) {
|
|
49
|
+
// User confirmed a label — save it for future use
|
|
50
|
+
saveSourceLabel(sourceLabel);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// Check for stored label
|
|
54
|
+
const stored = getSourceLabel();
|
|
55
|
+
if (stored) {
|
|
56
|
+
sourceLabel = stored;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// First use — return confirmation prompt
|
|
60
|
+
const suggested = getSuggestedLabel();
|
|
61
|
+
return {
|
|
62
|
+
content: [
|
|
63
|
+
{
|
|
64
|
+
type: "text",
|
|
65
|
+
text: [
|
|
66
|
+
`Before processing, I need a label for charges from this device and tool.`,
|
|
67
|
+
`Suggested: **${suggested}**`,
|
|
68
|
+
``,
|
|
69
|
+
`This label appears in your tru wallet so you can tell where each charge came from.`,
|
|
70
|
+
`Confirm this name, or type a custom one.`,
|
|
71
|
+
``,
|
|
72
|
+
`_If you're building a service for others, consider registering a tru app instead — it gives you a dedicated identity with custom branding._`,
|
|
73
|
+
``,
|
|
74
|
+
`To proceed, call this tool again with source_label set to your chosen label.`,
|
|
75
|
+
].join("\n"),
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const result = await requestAgentCard(args.email, args.amount_cents, args.description, args.target_service, args.currency, args.action, args.app_id, sourceLabel);
|
|
37
83
|
if (result.status === "escalated") {
|
|
38
84
|
return {
|
|
39
85
|
content: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request_virtual_card.js","sourceRoot":"","sources":["../../src/tools/request_virtual_card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"request_virtual_card.js","sourceRoot":"","sources":["../../src/tools/request_virtual_card.ts"],"names":[],"mappings":"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"}
|