This commit is contained in:
bipproduction
2025-11-18 10:11:09 +08:00
parent ea210b0ed9
commit c3863d845f
2 changed files with 35 additions and 21 deletions

View File

@@ -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
View 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 }}"
}
]
}