Skip to main content
Glama
ycyun

ABLESTACK MOLD MCP Server

by ycyun

mold_autoRegisterApis

Automatically registers multiple MCP tools by scanning available APIs with regex-based filtering. This tool simplifies API integration by batch-processing API endpoints for cloud infrastructure management.

Instructions

listApis를 기반으로 MCP 도구를 일괄 등록합니다. include/exclude는 정규식.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
includeNo
excludeNo
limitNo
namespaceNo

Implementation Reference

  • Registers the 'mold_autoRegisterApis' MCP tool with input schema and a thin handler that delegates to autoRegisterApis from discovery.js.
    server.registerTool( "mold_autoRegisterApis", { title: "MOLD 모든 API 동적 등록", description: "listApis를 기반으로 MCP 도구를 일괄 등록합니다. include/exclude는 정규식.", inputSchema: { include: z.string().optional(), exclude: z.string().optional(), limit: z.number().int().optional(), namespace: z.string().optional(), }, }, async ({ include, exclude, limit, namespace }) => { const result = await autoRegisterApis(server, { include, exclude, limit, namespace }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; } );
  • Core handler logic: fetches API metadata, filters by include/exclude/limit, and registers individual tools for each matching API using registerToolForApi.
    export async function autoRegisterApis(server, { include, exclude, limit, namespace } = {}) { const all = await fetchApisMeta(); const inc = include ? new RegExp(include, "i") : null; const exc = exclude ? new RegExp(exclude, "i") : null; const filtered = all.filter((a) => { if (inc && !inc.test(a.name)) return false; if (exc && exc.test(a.name)) return false; return true; }); const slice = typeof limit === "number" ? filtered.slice(0, limit) : filtered; let count = 0; for (const meta of slice) { if (registerToolForApi(server, meta, { namespace })) count++; } return { total: slice.length, registered: count, namespace: namespace || "mold_" }; }
  • Helper that dynamically registers a single MCP tool for a given MOLD API, including schema generation and async job handling.
    export function registerToolForApi(server, apiMeta, { namespace = "mold_" } = {}) { const rawName = `${namespace}${apiMeta.name}`; const toolName = sanitizeToolName(rawName); if (server.hasTool && server.hasTool(toolName)) return false; const inputSchema = buildInputSchemaFromParams(apiMeta.params, { isasync: apiMeta.isasync }); const title = `${apiMeta.name}${apiMeta.isasync ? " (async)" : ""}`; const description = (apiMeta.description || "").trim() || `Invoke ${apiMeta.name}`; server.registerTool( toolName, { title, description, inputSchema }, async (args = {}) => { const { _wait, _timeoutMs, _intervalMs, ...apiArgs } = args || {}; const params = {}; Object.keys(apiArgs).forEach((k) => { const v = apiArgs[k]; if (v !== undefined) params[k] = normalizeParamValue(v); }); const flat = flattenParamsForMold(apiArgs); const data = await callApi(apiMeta.name, flat); if (apiMeta.isasync && (_wait === true || _wait === "true")) { const resp = data[`${apiMeta.name.toLowerCase()}response`] || data; const jobid = resp.jobid || resp.jobId || data.jobid || data.jobId; if (!jobid) return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; const timeoutMs = Number(_timeoutMs || 60000); const intervalMs = Number(_intervalMs || 2000); const start = Date.now(); while (true) { const jr = await callApi("queryAsyncJobResult", { jobid }); const jresp = jr.queryasyncjobresultresponse || jr.queryAsyncJobResultResponse || jr; const status = jresp.jobstatus; if (status === 1 || status === 2) { return { content: [{ type: "text", text: JSON.stringify(jr, null, 2) }] }; } if (Date.now() - start > timeoutMs) { throw new Error(`timeout waiting job ${jobid} after ${timeoutMs}ms`); } await new Promise((r) => setTimeout(r, intervalMs)); } } return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } ); return true; }
  • Helper to fetch and parse listApis metadata from MOLD server.
    export async function fetchApisMeta({ name } = {}) { const data = await callApi("listApis", name ? { name } : {}); const resp = data.listapisresponse || data.listApisResponse || data.listapis || data; const apis = resp.api || resp.apis || resp; if (!apis || !Array.isArray(apis)) { throw new Error("listApis 응답을 파싱할 수 없습니다. (api 배열 없음)"); } return apis.map((a) => ({ name: a.name, description: a.description, isasync: !!a.isasync, since: a.since, related: a.related, params: Array.isArray(a.params) ? a.params.map((p) => ({ name: p.name, type: p.type, required: !!p.required, description: p.description, length: p.length, })) : [], })); }
  • Helper to build Zod input schema for a tool based on API param metadata.
    export function buildInputSchemaFromParams(paramsMeta, { isasync }) { const schema = {}; for (const p of paramsMeta) { const key = p.name; const ztype = mapTypeToZod(p.type); schema[key] = ztype; } if (isasync) { schema["_wait"] = z.union([z.boolean(), z.string()]).optional(); schema["_timeoutMs"] = z.union([z.number(), z.string()]).optional(); schema["_intervalMs"] = z.union([z.number(), z.string()]).optional(); } return schema; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ycyun/ablestack-MCP-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server