tru-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +76 -0
- package/dist/api-client.d.ts +107 -0
- package/dist/api-client.js +75 -0
- package/dist/api-client.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +2 -0
- package/dist/init.js +155 -0
- package/dist/init.js.map +1 -0
- package/dist/tools/check_charge_status.d.ts +23 -0
- package/dist/tools/check_charge_status.js +60 -0
- package/dist/tools/check_charge_status.js.map +1 -0
- package/dist/tools/check_identity.d.ts +23 -0
- package/dist/tools/check_identity.js +56 -0
- package/dist/tools/check_identity.js.map +1 -0
- package/dist/tools/check_request_status.d.ts +23 -0
- package/dist/tools/check_request_status.js +87 -0
- package/dist/tools/check_request_status.js.map +1 -0
- package/dist/tools/create_charge.d.ts +46 -0
- package/dist/tools/create_charge.js +135 -0
- package/dist/tools/create_charge.js.map +1 -0
- package/dist/tools/discover_apps.d.ts +18 -0
- package/dist/tools/discover_apps.js +56 -0
- package/dist/tools/discover_apps.js.map +1 -0
- package/dist/tools/initiate_oauth.d.ts +23 -0
- package/dist/tools/initiate_oauth.js +75 -0
- package/dist/tools/initiate_oauth.js.map +1 -0
- package/dist/tools/read_skill.d.ts +23 -0
- package/dist/tools/read_skill.js +50 -0
- package/dist/tools/read_skill.js.map +1 -0
- package/dist/tools/register_app.d.ts +35 -0
- package/dist/tools/register_app.js +83 -0
- package/dist/tools/register_app.js.map +1 -0
- package/dist/tools/request_credentials.d.ts +27 -0
- package/dist/tools/request_credentials.js +63 -0
- package/dist/tools/request_credentials.js.map +1 -0
- package/dist/tools/request_virtual_card.d.ts +33 -0
- package/dist/tools/request_virtual_card.js +124 -0
- package/dist/tools/request_virtual_card.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { checkIdentity } from "../api-client.js";
|
|
3
|
+
export const checkIdentityTool = {
|
|
4
|
+
name: "check_identity",
|
|
5
|
+
description: "Check if a user has a verified tru identity. Returns verification status without requiring user approval.",
|
|
6
|
+
inputSchema: {
|
|
7
|
+
email: z.string().describe("Email address of the user to check"),
|
|
8
|
+
},
|
|
9
|
+
handler: async (args) => {
|
|
10
|
+
try {
|
|
11
|
+
const result = await checkIdentity(args.email);
|
|
12
|
+
if (!result.verified) {
|
|
13
|
+
const reason = result.reason === "user_not_found"
|
|
14
|
+
? "No tru account found for this email. The user needs to sign up at tru first."
|
|
15
|
+
: result.reason === "not_verified"
|
|
16
|
+
? "This user has a tru account but has not completed identity verification."
|
|
17
|
+
: result.reason === "no_vault"
|
|
18
|
+
? "This user is verified but their credential vault is not yet populated."
|
|
19
|
+
: `Identity not verified (reason: ${result.reason}).`;
|
|
20
|
+
return {
|
|
21
|
+
content: [{ type: "text", text: `Not verified: ${reason}` }],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const lines = [
|
|
25
|
+
`Verified: Yes`,
|
|
26
|
+
`Name: ${result.name}`,
|
|
27
|
+
`Email: ${result.email}`,
|
|
28
|
+
`Identity verified: ${result.identity_verified ? "Yes" : "No"}`,
|
|
29
|
+
`Bank account linked: ${result.bank_linked ? "Yes" : "No"}`,
|
|
30
|
+
`Vault status: ${result.vault_status}`,
|
|
31
|
+
];
|
|
32
|
+
if (result.risk) {
|
|
33
|
+
lines.push(`Risk level: ${result.risk.level}`);
|
|
34
|
+
if (result.risk.score !== null)
|
|
35
|
+
lines.push(`Risk score: ${result.risk.score}/99`);
|
|
36
|
+
if (result.risk.card_funding)
|
|
37
|
+
lines.push(`Card type: ${result.risk.card_funding}`);
|
|
38
|
+
if (result.risk.card_country)
|
|
39
|
+
lines.push(`Card country: ${result.risk.card_country}`);
|
|
40
|
+
if (result.risk.fingerprint_reuse)
|
|
41
|
+
lines.push(`Warning: Card fingerprint seen on another account`);
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
49
|
+
return {
|
|
50
|
+
content: [{ type: "text", text: `Error checking identity: ${message}` }],
|
|
51
|
+
isError: true,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=check_identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check_identity.js","sourceRoot":"","sources":["../../src/tools/check_identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const checkRequestStatusTool: {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: {
|
|
6
|
+
request_id: z.ZodString;
|
|
7
|
+
};
|
|
8
|
+
handler: (args: {
|
|
9
|
+
request_id: 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,87 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getRequestStatus } from "../api-client.js";
|
|
3
|
+
export const checkRequestStatusTool = {
|
|
4
|
+
name: "check_request_status",
|
|
5
|
+
description: "Check the status of a credential sharing request. Returns 'pending', 'approved', or 'rejected'. If approved, returns the requested credential data.",
|
|
6
|
+
inputSchema: {
|
|
7
|
+
request_id: z.string().describe("The credential request ID to check"),
|
|
8
|
+
},
|
|
9
|
+
handler: async (args) => {
|
|
10
|
+
try {
|
|
11
|
+
const request = await getRequestStatus(args.request_id);
|
|
12
|
+
if (request.status === "pending") {
|
|
13
|
+
return {
|
|
14
|
+
content: [
|
|
15
|
+
{
|
|
16
|
+
type: "text",
|
|
17
|
+
text: [
|
|
18
|
+
`Status: pending`,
|
|
19
|
+
``,
|
|
20
|
+
`Request ID: ${request.id}`,
|
|
21
|
+
`User: ${request.user_email}`,
|
|
22
|
+
`Service: ${request.requesting_service}`,
|
|
23
|
+
`Fields: ${request.requested_fields.join(", ")}`,
|
|
24
|
+
``,
|
|
25
|
+
`The user has not yet responded. Check again later.`,
|
|
26
|
+
].join("\n"),
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (request.status === "rejected") {
|
|
32
|
+
return {
|
|
33
|
+
content: [
|
|
34
|
+
{
|
|
35
|
+
type: "text",
|
|
36
|
+
text: [
|
|
37
|
+
`Status: rejected`,
|
|
38
|
+
``,
|
|
39
|
+
`Request ID: ${request.id}`,
|
|
40
|
+
`User: ${request.user_email}`,
|
|
41
|
+
`Service: ${request.requesting_service}`,
|
|
42
|
+
``,
|
|
43
|
+
`The user declined to share their credentials with ${request.requesting_service}.`,
|
|
44
|
+
].join("\n"),
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// Approved — include vault data
|
|
50
|
+
const lines = [
|
|
51
|
+
`Status: approved`,
|
|
52
|
+
``,
|
|
53
|
+
`Request ID: ${request.id}`,
|
|
54
|
+
`User: ${request.user_email}`,
|
|
55
|
+
`Service: ${request.requesting_service}`,
|
|
56
|
+
``,
|
|
57
|
+
`Shared credential data:`,
|
|
58
|
+
];
|
|
59
|
+
if (request.vault_data) {
|
|
60
|
+
for (const [key, value] of Object.entries(request.vault_data)) {
|
|
61
|
+
if (typeof value === "object" && value !== null) {
|
|
62
|
+
lines.push(` ${key}: ${JSON.stringify(value)}`);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
lines.push(` ${key}: ${value}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
lines.push(" (No vault data returned)");
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
78
|
+
return {
|
|
79
|
+
content: [
|
|
80
|
+
{ type: "text", text: `Error checking request status: ${message}` },
|
|
81
|
+
],
|
|
82
|
+
isError: true,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=check_request_status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check_request_status.js","sourceRoot":"","sources":["../../src/tools/check_request_status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const createChargeTool: {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: {
|
|
6
|
+
email: z.ZodString;
|
|
7
|
+
amount_cents: z.ZodNumber;
|
|
8
|
+
description: z.ZodOptional<z.ZodString>;
|
|
9
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
10
|
+
one_time: "one_time";
|
|
11
|
+
recurring: "recurring";
|
|
12
|
+
}>>;
|
|
13
|
+
interval: z.ZodOptional<z.ZodEnum<{
|
|
14
|
+
month: "month";
|
|
15
|
+
year: "year";
|
|
16
|
+
}>>;
|
|
17
|
+
currency: z.ZodOptional<z.ZodString>;
|
|
18
|
+
payment_mode: z.ZodOptional<z.ZodEnum<{
|
|
19
|
+
direct: "direct";
|
|
20
|
+
virtual_card: "virtual_card";
|
|
21
|
+
}>>;
|
|
22
|
+
action: z.ZodOptional<z.ZodString>;
|
|
23
|
+
};
|
|
24
|
+
handler: (args: {
|
|
25
|
+
email: string;
|
|
26
|
+
amount_cents: number;
|
|
27
|
+
description?: string;
|
|
28
|
+
type?: "one_time" | "recurring";
|
|
29
|
+
interval?: "month" | "year";
|
|
30
|
+
currency?: string;
|
|
31
|
+
payment_mode?: "direct" | "virtual_card";
|
|
32
|
+
action?: string;
|
|
33
|
+
}) => Promise<{
|
|
34
|
+
content: {
|
|
35
|
+
type: "text";
|
|
36
|
+
text: string;
|
|
37
|
+
}[];
|
|
38
|
+
isError?: undefined;
|
|
39
|
+
} | {
|
|
40
|
+
content: {
|
|
41
|
+
type: "text";
|
|
42
|
+
text: string;
|
|
43
|
+
}[];
|
|
44
|
+
isError: boolean;
|
|
45
|
+
}>;
|
|
46
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { createCharge } from "../api-client.js";
|
|
3
|
+
export const createChargeTool = {
|
|
4
|
+
name: "create_charge",
|
|
5
|
+
description: "Create a direct charge or subscription on behalf of a user. " +
|
|
6
|
+
"Unlike request_virtual_card, this charges the user's payment method directly " +
|
|
7
|
+
"or creates a recurring subscription. " +
|
|
8
|
+
"The charge goes through the user's agent rules: auto-approved if within limits, " +
|
|
9
|
+
"left pending for manual approval if escalated, or auto-rejected if denied. " +
|
|
10
|
+
"For recurring subscriptions, set type to 'recurring' and specify the interval.",
|
|
11
|
+
inputSchema: {
|
|
12
|
+
email: z.string().describe("Email address of the tru user who will be charged"),
|
|
13
|
+
amount_cents: z
|
|
14
|
+
.number()
|
|
15
|
+
.int()
|
|
16
|
+
.positive()
|
|
17
|
+
.describe("Amount in cents (e.g. 4999 for $49.99)"),
|
|
18
|
+
description: z
|
|
19
|
+
.string()
|
|
20
|
+
.optional()
|
|
21
|
+
.describe("What this charge is for (shown to the user)"),
|
|
22
|
+
type: z
|
|
23
|
+
.enum(["one_time", "recurring"])
|
|
24
|
+
.optional()
|
|
25
|
+
.describe("Charge type: 'one_time' (default) or 'recurring' for subscriptions"),
|
|
26
|
+
interval: z
|
|
27
|
+
.enum(["month", "year"])
|
|
28
|
+
.optional()
|
|
29
|
+
.describe("Billing interval for recurring charges: 'month' or 'year'"),
|
|
30
|
+
currency: z
|
|
31
|
+
.string()
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("Currency code (default: 'usd')"),
|
|
34
|
+
payment_mode: z
|
|
35
|
+
.enum(["direct", "virtual_card"])
|
|
36
|
+
.optional()
|
|
37
|
+
.describe("Payment mode: 'direct' (default) charges the user's card directly, 'virtual_card' issues a virtual card"),
|
|
38
|
+
action: z
|
|
39
|
+
.string()
|
|
40
|
+
.optional()
|
|
41
|
+
.describe("The action being performed (e.g. 'purchase products', 'create subscription'). Used to evaluate action permission rules."),
|
|
42
|
+
},
|
|
43
|
+
handler: async (args) => {
|
|
44
|
+
try {
|
|
45
|
+
const result = await createCharge(args.email, args.amount_cents, args.description, args.type, args.interval, args.currency, args.payment_mode, args.action);
|
|
46
|
+
const amount = (args.amount_cents / 100).toFixed(2);
|
|
47
|
+
const currencyLabel = (args.currency || "usd").toUpperCase();
|
|
48
|
+
const chargeType = args.type === "recurring"
|
|
49
|
+
? `recurring (${args.interval || "month"})`
|
|
50
|
+
: "one-time";
|
|
51
|
+
// Charge was auto-rejected by agent rules
|
|
52
|
+
if (result.status === "rejected") {
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: "text",
|
|
57
|
+
text: [
|
|
58
|
+
`Denied: The user's agent rules do not allow this charge.`,
|
|
59
|
+
`Amount: $${amount} ${currencyLabel} (${chargeType})`,
|
|
60
|
+
`Reason: ${result.rule_evaluation?.reason || "Blocked by spending rules"}`,
|
|
61
|
+
`Charge request ID: ${result.id}`,
|
|
62
|
+
].join("\n"),
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// Charge is pending (escalated or no auto-approve rule matched)
|
|
68
|
+
if (result.status === "pending") {
|
|
69
|
+
const escalated = result.rule_evaluation?.action === "escalate";
|
|
70
|
+
return {
|
|
71
|
+
content: [
|
|
72
|
+
{
|
|
73
|
+
type: "text",
|
|
74
|
+
text: [
|
|
75
|
+
escalated
|
|
76
|
+
? `Escalated: This charge requires user approval.`
|
|
77
|
+
: `Pending: The charge has been created and is awaiting user approval.`,
|
|
78
|
+
`Amount: $${amount} ${currencyLabel} (${chargeType})`,
|
|
79
|
+
escalated
|
|
80
|
+
? `Reason: ${result.rule_evaluation?.reason || "Exceeds spending limits"}`
|
|
81
|
+
: null,
|
|
82
|
+
`Charge request ID: ${result.id}`,
|
|
83
|
+
``,
|
|
84
|
+
`The user needs to approve this in their tru dashboard.`,
|
|
85
|
+
`You can poll the status using the check_charge_status tool with this ID.`,
|
|
86
|
+
]
|
|
87
|
+
.filter(Boolean)
|
|
88
|
+
.join("\n"),
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// Charge was auto-approved
|
|
94
|
+
return {
|
|
95
|
+
content: [
|
|
96
|
+
{
|
|
97
|
+
type: "text",
|
|
98
|
+
text: [
|
|
99
|
+
`Charge created successfully.`,
|
|
100
|
+
`Amount: $${amount} ${currencyLabel} (${chargeType})`,
|
|
101
|
+
`Status: ${result.status}`,
|
|
102
|
+
`Charge request ID: ${result.id}`,
|
|
103
|
+
result.description ? `Description: ${result.description}` : null,
|
|
104
|
+
]
|
|
105
|
+
.filter(Boolean)
|
|
106
|
+
.join("\n"),
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
113
|
+
if (message.includes("no_payment_method")) {
|
|
114
|
+
return {
|
|
115
|
+
content: [
|
|
116
|
+
{
|
|
117
|
+
type: "text",
|
|
118
|
+
text: `The user has no payment method on file. They need to add a card in their tru dashboard first.`,
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
content: [
|
|
125
|
+
{
|
|
126
|
+
type: "text",
|
|
127
|
+
text: `Error creating charge: ${message}`,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
isError: true,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
//# sourceMappingURL=create_charge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_charge.js","sourceRoot":"","sources":["../../src/tools/create_charge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const discoverAppsTool: {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
inputSchema: {};
|
|
5
|
+
handler: () => 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,56 @@
|
|
|
1
|
+
const BASE_URL = process.env.TRU_API_URL || "http://localhost:3000";
|
|
2
|
+
export const discoverAppsTool = {
|
|
3
|
+
name: "discover_apps",
|
|
4
|
+
description: "List all apps in the tru directory. Returns active apps with their service names, " +
|
|
5
|
+
"descriptions, and SKILL.md URLs. Use this to find services an agent can interact with.",
|
|
6
|
+
inputSchema: {},
|
|
7
|
+
handler: async () => {
|
|
8
|
+
try {
|
|
9
|
+
const res = await fetch(`${BASE_URL}/api/apps/directory`);
|
|
10
|
+
if (!res.ok) {
|
|
11
|
+
const body = await res.text();
|
|
12
|
+
throw new Error(`API error ${res.status}: ${body}`);
|
|
13
|
+
}
|
|
14
|
+
const data = (await res.json());
|
|
15
|
+
if (data.apps.length === 0) {
|
|
16
|
+
return {
|
|
17
|
+
content: [
|
|
18
|
+
{
|
|
19
|
+
type: "text",
|
|
20
|
+
text: "No apps are currently registered in the tru directory.",
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const lines = [
|
|
26
|
+
`Found ${data.apps.length} app(s) in the tru directory:\n`,
|
|
27
|
+
];
|
|
28
|
+
for (const app of data.apps) {
|
|
29
|
+
lines.push(`## ${app.display_name} (${app.service_name})`);
|
|
30
|
+
if (app.description)
|
|
31
|
+
lines.push(app.description);
|
|
32
|
+
if (app.website)
|
|
33
|
+
lines.push(`Website: ${app.website}`);
|
|
34
|
+
lines.push(`SKILL.md: ${app.skill_url}`);
|
|
35
|
+
lines.push("");
|
|
36
|
+
}
|
|
37
|
+
lines.push("Use the read_skill tool with a service_name to learn how to interact with an app.");
|
|
38
|
+
return {
|
|
39
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
44
|
+
return {
|
|
45
|
+
content: [
|
|
46
|
+
{
|
|
47
|
+
type: "text",
|
|
48
|
+
text: `Error discovering apps: ${message}`,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
isError: true,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=discover_apps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover_apps.js","sourceRoot":"","sources":["../../src/tools/discover_apps.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,uBAAuB,CAAC;AAWpE,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,IAAI,EAAE,eAAe;IACrB,WAAW,EACT,oFAAoF;QACpF,wFAAwF;IAC1F,WAAW,EAAE,EAAE;IACf,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,qBAAqB,CAAC,CAAC;YAE1D,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,aAAa,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;YACtD,CAAC;YAED,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA6B,CAAC;YAE5D,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,wDAAwD;yBAC/D;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAG;gBACZ,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,iCAAiC;aAC3D,CAAC;YAEF,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,YAAY,KAAK,GAAG,CAAC,YAAY,GAAG,CAAC,CAAC;gBAC3D,IAAI,GAAG,CAAC,WAAW;oBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBACjD,IAAI,GAAG,CAAC,OAAO;oBAAE,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBACvD,KAAK,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;gBACzC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjB,CAAC;YAED,KAAK,CAAC,IAAI,CACR,mFAAmF,CACpF,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;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,2BAA2B,OAAO,EAAE;qBAC3C;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const initiateOAuthTool: {
|
|
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,75 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import crypto from "crypto";
|
|
3
|
+
import { lookupAppByServiceName } from "../api-client.js";
|
|
4
|
+
const BASE_URL = process.env.TRU_API_URL || "http://localhost:3000";
|
|
5
|
+
export const initiateOAuthTool = {
|
|
6
|
+
name: "initiate_oauth",
|
|
7
|
+
description: "Generate an OAuth authorization URL for a tru-integrated app. " +
|
|
8
|
+
"Given a service_name, looks up the app and returns the URL the user should open in their browser to authenticate via tru.",
|
|
9
|
+
inputSchema: {
|
|
10
|
+
service_name: z
|
|
11
|
+
.string()
|
|
12
|
+
.describe("The service_name of the app to initiate OAuth for"),
|
|
13
|
+
},
|
|
14
|
+
handler: async (args) => {
|
|
15
|
+
try {
|
|
16
|
+
const lookup = await lookupAppByServiceName(args.service_name);
|
|
17
|
+
if (lookup.status === "not_found" || !lookup.app) {
|
|
18
|
+
return {
|
|
19
|
+
content: [
|
|
20
|
+
{
|
|
21
|
+
type: "text",
|
|
22
|
+
text: `No active app found with service_name "${args.service_name}". Use the discover_apps tool to see available apps.`,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const app = lookup.app;
|
|
28
|
+
const redirectUri = app.redirect_uris[0];
|
|
29
|
+
if (!redirectUri) {
|
|
30
|
+
return {
|
|
31
|
+
content: [
|
|
32
|
+
{
|
|
33
|
+
type: "text",
|
|
34
|
+
text: `The app "${app.display_name}" does not have any redirect URIs configured. The app developer needs to set up a redirect URI before OAuth can be used.`,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const state = crypto.randomUUID();
|
|
40
|
+
const params = new URLSearchParams({
|
|
41
|
+
client_id: app.id,
|
|
42
|
+
redirect_uri: redirectUri,
|
|
43
|
+
scope: "openid",
|
|
44
|
+
state,
|
|
45
|
+
});
|
|
46
|
+
const authUrl = `${BASE_URL}/oauth/authorize?${params.toString()}`;
|
|
47
|
+
const lines = [
|
|
48
|
+
`## OAuth Authorization for ${app.display_name}`,
|
|
49
|
+
"",
|
|
50
|
+
`Open this URL in the user's browser:`,
|
|
51
|
+
"",
|
|
52
|
+
authUrl,
|
|
53
|
+
"",
|
|
54
|
+
"The user will authenticate via tru and be redirected back to the app.",
|
|
55
|
+
`State parameter: ${state}`,
|
|
56
|
+
];
|
|
57
|
+
return {
|
|
58
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
63
|
+
return {
|
|
64
|
+
content: [
|
|
65
|
+
{
|
|
66
|
+
type: "text",
|
|
67
|
+
text: `Error initiating OAuth: ${message}`,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
isError: true,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=initiate_oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initiate_oauth.js","sourceRoot":"","sources":["../../src/tools/initiate_oauth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,uBAAuB,CAAC;AAEpE,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,gBAAgB;IACtB,WAAW,EACT,gEAAgE;QAChE,2HAA2H;IAC7H,WAAW,EAAE;QACX,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,CAAC,mDAAmD,CAAC;KACjE;IACD,OAAO,EAAE,KAAK,EAAE,IAA8B,EAAE,EAAE;QAChD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAE/D,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;gBACjD,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,0CAA0C,IAAI,CAAC,YAAY,sDAAsD;yBACxH;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;YACvB,MAAM,WAAW,GAAG,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YAEzC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,YAAY,GAAG,CAAC,YAAY,0HAA0H;yBAC7J;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;gBACjC,SAAS,EAAE,GAAG,CAAC,EAAE;gBACjB,YAAY,EAAE,WAAW;gBACzB,KAAK,EAAE,QAAQ;gBACf,KAAK;aACN,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,GAAG,QAAQ,oBAAoB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;YAEnE,MAAM,KAAK,GAAG;gBACZ,8BAA8B,GAAG,CAAC,YAAY,EAAE;gBAChD,EAAE;gBACF,sCAAsC;gBACtC,EAAE;gBACF,OAAO;gBACP,EAAE;gBACF,uEAAuE;gBACvE,oBAAoB,KAAK,EAAE;aAC5B,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;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,2BAA2B,OAAO,EAAE;qBAC3C;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const readSkillTool: {
|
|
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,50 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const BASE_URL = process.env.TRU_API_URL || "http://localhost:3000";
|
|
3
|
+
export const readSkillTool = {
|
|
4
|
+
name: "read_skill",
|
|
5
|
+
description: "Fetch and return the SKILL.md for a specific app. " +
|
|
6
|
+
"The SKILL.md describes how an agent should interact with the app's API, " +
|
|
7
|
+
"including available endpoints, authentication, and usage examples.",
|
|
8
|
+
inputSchema: {
|
|
9
|
+
service_name: z
|
|
10
|
+
.string()
|
|
11
|
+
.describe("The service_name of the app (e.g. 'clayking')"),
|
|
12
|
+
},
|
|
13
|
+
handler: async (args) => {
|
|
14
|
+
try {
|
|
15
|
+
const url = `${BASE_URL}/apps/${encodeURIComponent(args.service_name)}/SKILL.md`;
|
|
16
|
+
const res = await fetch(url);
|
|
17
|
+
if (res.status === 404) {
|
|
18
|
+
return {
|
|
19
|
+
content: [
|
|
20
|
+
{
|
|
21
|
+
type: "text",
|
|
22
|
+
text: `No app found with service_name "${args.service_name}". Use discover_apps to list available apps.`,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (!res.ok) {
|
|
28
|
+
const body = await res.text();
|
|
29
|
+
throw new Error(`API error ${res.status}: ${body}`);
|
|
30
|
+
}
|
|
31
|
+
const markdown = await res.text();
|
|
32
|
+
return {
|
|
33
|
+
content: [{ type: "text", text: markdown }],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
38
|
+
return {
|
|
39
|
+
content: [
|
|
40
|
+
{
|
|
41
|
+
type: "text",
|
|
42
|
+
text: `Error reading SKILL.md: ${message}`,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
isError: true,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=read_skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read_skill.js","sourceRoot":"","sources":["../../src/tools/read_skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,uBAAuB,CAAC;AAEpE,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,YAAY;IAClB,WAAW,EACT,oDAAoD;QACpD,0EAA0E;QAC1E,oEAAoE;IACtE,WAAW,EAAE;QACX,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,CAAC,+CAA+C,CAAC;KAC7D;IACD,OAAO,EAAE,KAAK,EAAE,IAA8B,EAAE,EAAE;QAChD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,GAAG,QAAQ,SAAS,kBAAkB,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC;YACjF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YAE7B,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACvB,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,mCAAmC,IAAI,CAAC,YAAY,8CAA8C;yBACzG;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,aAAa,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;YACtD,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAElC,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;aACrD,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;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,2BAA2B,OAAO,EAAE;qBAC3C;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
|