build
This commit is contained in:
@@ -19,7 +19,6 @@ const toolsCache = new Map<string, any[]>();
|
|||||||
async function loadTools(openapiUrl: string, filterTag: string, forceRefresh = false): Promise<any[]> {
|
async function loadTools(openapiUrl: string, filterTag: string, forceRefresh = false): Promise<any[]> {
|
||||||
const cacheKey = `${openapiUrl}::${filterTag}`;
|
const cacheKey = `${openapiUrl}::${filterTag}`;
|
||||||
|
|
||||||
// Jika tidak forceRefresh, gunakan cache
|
|
||||||
if (!forceRefresh && toolsCache.has(cacheKey)) {
|
if (!forceRefresh && toolsCache.has(cacheKey)) {
|
||||||
return toolsCache.get(cacheKey)!;
|
return toolsCache.get(cacheKey)!;
|
||||||
}
|
}
|
||||||
@@ -27,12 +26,9 @@ async function loadTools(openapiUrl: string, filterTag: string, forceRefresh = f
|
|||||||
console.log(`[MCP] 🔄 Refreshing tools from ${openapiUrl} ...`);
|
console.log(`[MCP] 🔄 Refreshing tools from ${openapiUrl} ...`);
|
||||||
const fetched = await getMcpTools(openapiUrl, filterTag);
|
const fetched = await getMcpTools(openapiUrl, filterTag);
|
||||||
|
|
||||||
// 🟢 Log jumlah & daftar tools
|
|
||||||
console.log(`[MCP] ✅ Loaded ${fetched.length} tools`);
|
console.log(`[MCP] ✅ Loaded ${fetched.length} tools`);
|
||||||
if (fetched.length > 0) {
|
if (fetched.length > 0) {
|
||||||
console.log(
|
console.log(`[MCP] Tools: ${fetched.map((t: any) => t.name).join(", ")}`);
|
||||||
`[MCP] Tools: ${fetched.map((t: any) => t.name).join(", ")}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toolsCache.set(cacheKey, fetched);
|
toolsCache.set(cacheKey, fetched);
|
||||||
@@ -104,7 +100,7 @@ async function executeTool(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
// JSON-RPC Handler (per node, per request)
|
// JSON-RPC Handler
|
||||||
// ======================================================
|
// ======================================================
|
||||||
async function handleMCPRequest(
|
async function handleMCPRequest(
|
||||||
request: JSONRPCRequest,
|
request: JSONRPCRequest,
|
||||||
@@ -181,7 +177,7 @@ async function handleMCPRequest(
|
|||||||
result: {
|
result: {
|
||||||
content: [
|
content: [
|
||||||
isObject
|
isObject
|
||||||
? { type: "json", data: data }
|
? { type: "json", data }
|
||||||
: { type: "text", text: JSON.stringify(data || result.data || result) },
|
: { type: "text", text: JSON.stringify(data || result.data || result) },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -208,7 +204,7 @@ async function handleMCPRequest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
// NODE MCP TRIGGER
|
// MCP TRIGGER NODE
|
||||||
// ======================================================
|
// ======================================================
|
||||||
export class OpenapiMcpServer implements INodeType {
|
export class OpenapiMcpServer implements INodeType {
|
||||||
description: INodeTypeDescription = {
|
description: INodeTypeDescription = {
|
||||||
@@ -255,27 +251,25 @@ export class OpenapiMcpServer implements INodeType {
|
|||||||
default: "",
|
default: "",
|
||||||
placeholder: "mcp | tag",
|
placeholder: "mcp | tag",
|
||||||
},
|
},
|
||||||
// 🟢 Tambahan agar terlihat jumlah tools di UI
|
|
||||||
{
|
{
|
||||||
displayName: 'Available Tools (auto-refresh)',
|
displayName: 'Available Tools (auto-refresh)',
|
||||||
name: 'toolList',
|
name: 'toolList',
|
||||||
type: 'options',
|
type: 'options',
|
||||||
typeOptions: {
|
typeOptions: {
|
||||||
loadOptionsMethod: 'refreshToolList',
|
loadOptionsMethod: 'refreshToolList',
|
||||||
refreshOnOpen: true, // setiap node dibuka auto refresh
|
refreshOnOpen: true,
|
||||||
},
|
},
|
||||||
default: '',
|
default: 'all',
|
||||||
description: 'Daftar tools yang berhasil dimuat dari OpenAPI',
|
description: 'Daftar tools yang berhasil dimuat dari OpenAPI',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==================================================
|
// ==================================================
|
||||||
// LoadOptions untuk tampil di dropdown
|
// LoadOptions
|
||||||
// ==================================================
|
// ==================================================
|
||||||
methods = {
|
methods = {
|
||||||
loadOptions: {
|
loadOptions: {
|
||||||
// 🟢 otomatis refetch setiap kali node dibuka
|
|
||||||
async refreshToolList(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
async refreshToolList(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
const openapiUrl = this.getNodeParameter("openapiUrl", 0) as string;
|
const openapiUrl = this.getNodeParameter("openapiUrl", 0) as string;
|
||||||
const filterTag = this.getNodeParameter("defaultFilter", 0) as string;
|
const filterTag = this.getNodeParameter("defaultFilter", 0) as string;
|
||||||
@@ -284,25 +278,27 @@ export class OpenapiMcpServer implements INodeType {
|
|||||||
return [{ name: "❌ No OpenAPI URL provided", value: "" }];
|
return [{ name: "❌ No OpenAPI URL provided", value: "" }];
|
||||||
}
|
}
|
||||||
|
|
||||||
const tools = await loadTools(openapiUrl, filterTag, true); // force refresh
|
const tools = await loadTools(openapiUrl, filterTag, true);
|
||||||
|
|
||||||
return tools.map((t) => ({
|
return [
|
||||||
name: t.name,
|
{ name: "All Tools", value: "all" },
|
||||||
value: t.name,
|
...tools.map((t) => ({
|
||||||
description: t.description,
|
name: t.name,
|
||||||
}));
|
value: t.name,
|
||||||
|
description: t.description,
|
||||||
|
})),
|
||||||
|
];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==================================================
|
// ==================================================
|
||||||
// WEBHOOK HANDLER
|
// Webhook Handler
|
||||||
// ==================================================
|
// ==================================================
|
||||||
async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
|
async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
|
||||||
const openapiUrl = this.getNodeParameter("openapiUrl", 0) as string;
|
const openapiUrl = this.getNodeParameter("openapiUrl", 0) as string;
|
||||||
const filterTag = this.getNodeParameter("defaultFilter", 0) as string;
|
const filterTag = this.getNodeParameter("defaultFilter", 0) as string;
|
||||||
|
|
||||||
// 🟢 selalu refresh (agar node terbaru)
|
|
||||||
const tools = await loadTools(openapiUrl, filterTag, true);
|
const tools = await loadTools(openapiUrl, filterTag, true);
|
||||||
|
|
||||||
const creds = await this.getCredentials("openapiMcpServerCredentials") as {
|
const creds = await this.getCredentials("openapiMcpServerCredentials") as {
|
||||||
|
|||||||
18
x.json
Normal file
18
x.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"model": "gpt-4.1",
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"type": "web_search_preview"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"input": [
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": "Kamu adalah AI agent yang hanya menjawab berdasarkan tools websearch preview berdasarkan tag [indonesia, bali, badung, abiansemal, darmasaba, 2025], jika tidak menggunakan , jangan menjawab selain hasil dari tools , dilarang percakapan basabasi , jika tidak ada hasil dari tool cukup jawab dengan \"\" jika ada hasil dari tool gunakan format berikut # LAPORAN WEB PREVIEW AGENT\n\n<content>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "{{ $('map_data').item.json.message_text }}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user