n8n-nodes-agnicwallet 1.0.5 → 1.0.7
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/credentials/AgnicWalletApi.credentials.d.ts +1 -1
- package/dist/credentials/AgnicWalletApi.credentials.js +17 -17
- package/dist/credentials/AgnicWalletOAuth2Api.credentials.d.ts +1 -1
- package/dist/credentials/AgnicWalletOAuth2Api.credentials.js +51 -51
- package/dist/nodes/AgnicAI/AgnicAI.node.d.ts +5 -0
- package/dist/nodes/AgnicAI/AgnicAI.node.js +422 -0
- package/dist/nodes/AgnicAI/AgnicAI.png +0 -0
- package/dist/nodes/AgnicAILanguageModel/AgnicAILanguageModel.node.d.ts +12 -0
- package/dist/nodes/AgnicAILanguageModel/AgnicAILanguageModel.node.js +365 -0
- package/dist/nodes/AgnicAILanguageModel/AgnicAILanguageModel.png +0 -0
- package/dist/nodes/AgnicAILanguageModel/AgnicAILanguageModel.svg +6 -0
- package/dist/nodes/AgnicMCPTool/AgnicMCPTool.node.d.ts +22 -0
- package/dist/nodes/AgnicMCPTool/AgnicMCPTool.node.js +368 -0
- package/dist/nodes/AgnicMCPTool/AgnicMCPTool.png +0 -0
- package/dist/nodes/X402HttpRequest/X402HttpRequest.node.d.ts +1 -1
- package/dist/nodes/X402HttpRequest/X402HttpRequest.node.js +91 -89
- package/dist/nodes/X402HttpRequest/X402HttpRequest.png +0 -0
- package/dist/nodes/X402HttpRequest/X402HttpRequest.svg +19 -0
- package/package.json +21 -8
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AgnicMCPTool = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
|
|
6
|
+
const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
7
|
+
const tools_1 = require("@langchain/core/tools");
|
|
8
|
+
const agents_1 = require("langchain/agents");
|
|
9
|
+
const zod_1 = require("zod");
|
|
10
|
+
const json_schema_to_zod_1 = require("@n8n/json-schema-to-zod");
|
|
11
|
+
/**
|
|
12
|
+
* Toolkit class that wraps MCP tools for n8n AI Agent
|
|
13
|
+
* Extends Toolkit from langchain/agents for proper serialization
|
|
14
|
+
*/
|
|
15
|
+
class AgnicMcpToolkit extends agents_1.Toolkit {
|
|
16
|
+
constructor(tools) {
|
|
17
|
+
super();
|
|
18
|
+
this.tools = tools;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// Pre-configured AgnicPay MCP endpoint (uses HTTP Streamable transport)
|
|
22
|
+
const AGNIC_MCP_ENDPOINT = "https://mcp.agnicpay.xyz/sse";
|
|
23
|
+
/**
|
|
24
|
+
* Convert JSON Schema to Zod schema using n8n's library
|
|
25
|
+
* Returns actual Zod schema objects (not strings)
|
|
26
|
+
*/
|
|
27
|
+
function convertJsonSchemaToZod(schema) {
|
|
28
|
+
if (!schema || typeof schema !== "object") {
|
|
29
|
+
return zod_1.z.object({});
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
// @n8n/json-schema-to-zod returns actual Zod objects, not strings
|
|
33
|
+
const zodSchema = (0, json_schema_to_zod_1.jsonSchemaToZod)(schema);
|
|
34
|
+
// Ensure we return an object schema for structured tools
|
|
35
|
+
if (zodSchema instanceof zod_1.z.ZodObject) {
|
|
36
|
+
return zodSchema;
|
|
37
|
+
}
|
|
38
|
+
// Wrap non-object schemas in an object
|
|
39
|
+
return zod_1.z.object({ value: zodSchema });
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Fallback to empty object schema if conversion fails
|
|
43
|
+
return zod_1.z.object({});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Convert an MCP tool to a LangChain DynamicStructuredTool
|
|
48
|
+
*/
|
|
49
|
+
function mcpToolToDynamicTool(tool, callTool) {
|
|
50
|
+
// Convert JSON Schema to Zod schema using proper library
|
|
51
|
+
const zodSchema = convertJsonSchemaToZod(tool.inputSchema);
|
|
52
|
+
// Use type assertion to avoid deep type instantiation issues with DynamicStructuredTool
|
|
53
|
+
const toolConfig = {
|
|
54
|
+
name: tool.name,
|
|
55
|
+
description: tool.description || `MCP tool: ${tool.name}`,
|
|
56
|
+
schema: zodSchema,
|
|
57
|
+
func: async (input) => {
|
|
58
|
+
try {
|
|
59
|
+
const result = await callTool(tool.name, input);
|
|
60
|
+
if (typeof result === "string") {
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
return JSON.stringify(result);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
67
|
+
return `Error calling ${tool.name}: ${errorMessage}`;
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
// Required metadata for proper tool serialization in n8n
|
|
71
|
+
metadata: { isFromToolkit: true },
|
|
72
|
+
};
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
74
|
+
return new tools_1.DynamicStructuredTool(toolConfig);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* AgnicMCPTool - MCP Client for AgnicPay
|
|
78
|
+
*
|
|
79
|
+
* This is a supply-only AI tool node that connects to the AgnicPay MCP server
|
|
80
|
+
* and provides X402 payment tools to AI Agents via the MCP protocol.
|
|
81
|
+
*
|
|
82
|
+
* This node cannot be executed directly - it only supplies tools to AI Agents.
|
|
83
|
+
*/
|
|
84
|
+
class AgnicMCPTool {
|
|
85
|
+
constructor() {
|
|
86
|
+
this.description = {
|
|
87
|
+
displayName: "Agnic MCP Tool",
|
|
88
|
+
name: "agnicMcpTool",
|
|
89
|
+
icon: "file:AgnicMCPTool.png",
|
|
90
|
+
group: ["output"],
|
|
91
|
+
version: 1,
|
|
92
|
+
description: "MCP client for AgnicPay - X402 payment tools for AI Agents",
|
|
93
|
+
defaults: {
|
|
94
|
+
name: "Agnic MCP Tool",
|
|
95
|
+
},
|
|
96
|
+
// Supply-only AI tool configuration
|
|
97
|
+
inputs: [],
|
|
98
|
+
outputs: [{ type: n8n_workflow_1.NodeConnectionTypes.AiTool, displayName: "Tools" }],
|
|
99
|
+
codex: {
|
|
100
|
+
categories: ["AI"],
|
|
101
|
+
subcategories: {
|
|
102
|
+
AI: ["Tools"],
|
|
103
|
+
},
|
|
104
|
+
resources: {
|
|
105
|
+
primaryDocumentation: [
|
|
106
|
+
{
|
|
107
|
+
url: "https://www.agnicpay.xyz/mcp",
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
credentials: [
|
|
113
|
+
{
|
|
114
|
+
name: "agnicWalletOAuth2Api",
|
|
115
|
+
required: false,
|
|
116
|
+
displayOptions: {
|
|
117
|
+
show: {
|
|
118
|
+
authentication: ["oAuth2"],
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: "agnicWalletApi",
|
|
124
|
+
required: false,
|
|
125
|
+
displayOptions: {
|
|
126
|
+
show: {
|
|
127
|
+
authentication: ["apiKey"],
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
properties: [
|
|
133
|
+
{
|
|
134
|
+
displayName: "Authentication",
|
|
135
|
+
name: "authentication",
|
|
136
|
+
type: "options",
|
|
137
|
+
default: "apiKey",
|
|
138
|
+
options: [
|
|
139
|
+
{
|
|
140
|
+
name: "OAuth2",
|
|
141
|
+
value: "oAuth2",
|
|
142
|
+
description: "Recommended: Connect your account",
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
name: "API Key",
|
|
146
|
+
value: "apiKey",
|
|
147
|
+
description: "For CI/CD or programmatic access",
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
description: "How to authenticate with AgnicWallet",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
displayName: "Connects to AgnicPay MCP server. Tools are discovered automatically and include: make X402 API requests, check balance, view payment history, and discover APIs.",
|
|
154
|
+
name: "notice",
|
|
155
|
+
type: "notice",
|
|
156
|
+
default: "",
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Execute method for direct tool invocation.
|
|
163
|
+
* This is called when input data is passed directly to this node.
|
|
164
|
+
*/
|
|
165
|
+
async execute() {
|
|
166
|
+
var _a;
|
|
167
|
+
const node = this.getNode();
|
|
168
|
+
const items = this.getInputData();
|
|
169
|
+
const returnData = [];
|
|
170
|
+
// Get authentication
|
|
171
|
+
const authentication = this.getNodeParameter("authentication", 0);
|
|
172
|
+
let accessToken;
|
|
173
|
+
try {
|
|
174
|
+
if (authentication === "oAuth2") {
|
|
175
|
+
const creds = (await this.getCredentials("agnicWalletOAuth2Api"));
|
|
176
|
+
accessToken = (_a = creds === null || creds === void 0 ? void 0 : creds.oauthTokenData) === null || _a === void 0 ? void 0 : _a.access_token;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
const creds = (await this.getCredentials("agnicWalletApi"));
|
|
180
|
+
accessToken = creds === null || creds === void 0 ? void 0 : creds.apiToken;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
throw new n8n_workflow_1.NodeOperationError(node, "Failed to load AgnicWallet credentials.");
|
|
185
|
+
}
|
|
186
|
+
if (!accessToken) {
|
|
187
|
+
throw new n8n_workflow_1.NodeOperationError(node, "Missing AgnicWallet authentication token.");
|
|
188
|
+
}
|
|
189
|
+
// Connect to MCP server
|
|
190
|
+
const transport = new streamableHttp_js_1.StreamableHTTPClientTransport(new URL(AGNIC_MCP_ENDPOINT), {
|
|
191
|
+
requestInit: { headers: { Authorization: `Bearer ${accessToken}` } },
|
|
192
|
+
});
|
|
193
|
+
const client = new index_js_1.Client({ name: "agnic-mcp-client", version: "1.0.0" }, { capabilities: {} });
|
|
194
|
+
try {
|
|
195
|
+
await client.connect(transport);
|
|
196
|
+
const toolsResult = await client.listTools();
|
|
197
|
+
const mcpTools = toolsResult.tools || [];
|
|
198
|
+
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
199
|
+
const item = items[itemIndex];
|
|
200
|
+
// Expect input to have a 'tool' property with the tool name
|
|
201
|
+
if (!item.json.tool || typeof item.json.tool !== "string") {
|
|
202
|
+
throw new n8n_workflow_1.NodeOperationError(node, "Tool name not found in item.json.tool", { itemIndex });
|
|
203
|
+
}
|
|
204
|
+
const toolName = item.json.tool;
|
|
205
|
+
const matchingTool = mcpTools.find((t) => t.name === toolName);
|
|
206
|
+
if (!matchingTool) {
|
|
207
|
+
throw new n8n_workflow_1.NodeOperationError(node, `Tool "${toolName}" not found`, {
|
|
208
|
+
itemIndex,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
// Extract tool arguments (everything except 'tool' property)
|
|
212
|
+
const { tool: _, ...toolArguments } = item.json;
|
|
213
|
+
const result = await client.callTool({
|
|
214
|
+
name: toolName,
|
|
215
|
+
arguments: toolArguments,
|
|
216
|
+
});
|
|
217
|
+
// Extract text content from result
|
|
218
|
+
let responseContent = result;
|
|
219
|
+
if (result.content && Array.isArray(result.content)) {
|
|
220
|
+
const textContent = result.content.find((c) => c.type === "text");
|
|
221
|
+
if (textContent && "text" in textContent) {
|
|
222
|
+
responseContent = textContent.text;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
returnData.push({
|
|
226
|
+
json: { response: responseContent },
|
|
227
|
+
pairedItem: { item: itemIndex },
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
finally {
|
|
232
|
+
try {
|
|
233
|
+
await client.close();
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
// Ignore cleanup errors
|
|
237
|
+
}
|
|
238
|
+
try {
|
|
239
|
+
await transport.close();
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
// Ignore cleanup errors
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return [returnData];
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Supply MCP tools to AI Agent.
|
|
249
|
+
* This is the main method that provides tools to the AI Agent.
|
|
250
|
+
*/
|
|
251
|
+
async supplyData(itemIndex) {
|
|
252
|
+
var _a;
|
|
253
|
+
// ─────────────────────────────────────────────
|
|
254
|
+
// Authentication
|
|
255
|
+
// ─────────────────────────────────────────────
|
|
256
|
+
const authentication = this.getNodeParameter("authentication", itemIndex);
|
|
257
|
+
let accessToken;
|
|
258
|
+
try {
|
|
259
|
+
if (authentication === "oAuth2") {
|
|
260
|
+
const creds = (await this.getCredentials("agnicWalletOAuth2Api", itemIndex));
|
|
261
|
+
accessToken = (_a = creds === null || creds === void 0 ? void 0 : creds.oauthTokenData) === null || _a === void 0 ? void 0 : _a.access_token;
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
const creds = (await this.getCredentials("agnicWalletApi", itemIndex));
|
|
265
|
+
accessToken = creds === null || creds === void 0 ? void 0 : creds.apiToken;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), "Failed to load AgnicWallet credentials. Please configure your credentials.", { itemIndex });
|
|
270
|
+
}
|
|
271
|
+
if (!accessToken) {
|
|
272
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), "Missing AgnicWallet authentication token. Please check your credentials configuration.", { itemIndex });
|
|
273
|
+
}
|
|
274
|
+
// ─────────────────────────────────────────────
|
|
275
|
+
// MCP Client Setup
|
|
276
|
+
// ─────────────────────────────────────────────
|
|
277
|
+
let client;
|
|
278
|
+
let transport;
|
|
279
|
+
try {
|
|
280
|
+
// Create HTTP Streamable transport with authentication
|
|
281
|
+
// This transport uses POST requests and accepts both JSON and SSE responses
|
|
282
|
+
transport = new streamableHttp_js_1.StreamableHTTPClientTransport(new URL(AGNIC_MCP_ENDPOINT), {
|
|
283
|
+
requestInit: {
|
|
284
|
+
headers: {
|
|
285
|
+
Authorization: `Bearer ${accessToken}`,
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
// Create MCP client
|
|
290
|
+
client = new index_js_1.Client({ name: "agnic-mcp-client", version: "1.0.0" }, { capabilities: {} });
|
|
291
|
+
// Connect to MCP server
|
|
292
|
+
await client.connect(transport);
|
|
293
|
+
// ─────────────────────────────────────────────
|
|
294
|
+
// Discover and wrap MCP tools
|
|
295
|
+
// ─────────────────────────────────────────────
|
|
296
|
+
const toolsResult = await client.listTools();
|
|
297
|
+
const mcpTools = toolsResult.tools || [];
|
|
298
|
+
if (mcpTools.length === 0) {
|
|
299
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), "No tools available from AgnicPay MCP server. Please check your authentication and try again.", { itemIndex });
|
|
300
|
+
}
|
|
301
|
+
// Create a tool caller function
|
|
302
|
+
const callTool = async (name, args) => {
|
|
303
|
+
if (!client) {
|
|
304
|
+
throw new Error("MCP client is not connected");
|
|
305
|
+
}
|
|
306
|
+
const result = await client.callTool({
|
|
307
|
+
name,
|
|
308
|
+
arguments: args,
|
|
309
|
+
});
|
|
310
|
+
// Extract content from the result
|
|
311
|
+
if (result.content && Array.isArray(result.content)) {
|
|
312
|
+
const textContent = result.content.find((c) => c.type === "text");
|
|
313
|
+
if (textContent && "text" in textContent) {
|
|
314
|
+
return textContent.text;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return result;
|
|
318
|
+
};
|
|
319
|
+
// Convert MCP tools to LangChain DynamicStructuredTools
|
|
320
|
+
const langchainTools = mcpTools.map((tool) => mcpToolToDynamicTool(tool, callTool));
|
|
321
|
+
// Wrap tools in a Toolkit for n8n AI Agent compatibility
|
|
322
|
+
const toolkit = new AgnicMcpToolkit(langchainTools);
|
|
323
|
+
// Store references for cleanup
|
|
324
|
+
const clientRef = client;
|
|
325
|
+
const transportRef = transport;
|
|
326
|
+
// Return toolkit with cleanup function
|
|
327
|
+
return {
|
|
328
|
+
response: toolkit,
|
|
329
|
+
closeFunction: async () => {
|
|
330
|
+
try {
|
|
331
|
+
await clientRef.close();
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
// Ignore cleanup errors
|
|
335
|
+
}
|
|
336
|
+
try {
|
|
337
|
+
await transportRef.close();
|
|
338
|
+
}
|
|
339
|
+
catch {
|
|
340
|
+
// Ignore cleanup errors
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
// Clean up on error
|
|
347
|
+
if (client) {
|
|
348
|
+
try {
|
|
349
|
+
await client.close();
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
// Ignore cleanup errors
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (transport) {
|
|
356
|
+
try {
|
|
357
|
+
await transport.close();
|
|
358
|
+
}
|
|
359
|
+
catch {
|
|
360
|
+
// Ignore cleanup errors
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
364
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to connect to AgnicPay MCP server: ${errorMessage}`, { itemIndex });
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
exports.AgnicMCPTool = AgnicMCPTool;
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from
|
|
1
|
+
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from "n8n-workflow";
|
|
2
2
|
export declare class X402HttpRequest implements INodeType {
|
|
3
3
|
description: INodeTypeDescription;
|
|
4
4
|
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|