Skip to main content
Glama

Alibaba Cloud FC MCP Server

Official
by aliyun
index.ts39.1 kB
#!/usr/bin/env node import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { createFcClient, getAccountId } from "./utils/alibaba_cloud_sdk.js"; import * as path from 'path'; import * as fs from 'fs'; import { z } from "zod"; import os from 'os'; import { fileURLToPath } from 'url'; import { dirname, resolve } from 'path'; import yaml from 'js-yaml'; import { logger } from "./logger.js"; import loadComponent from "@serverless-devs/load-component"; import { regionSchema, domainSchema, codeUriSchema, logConfigSchema, vpcConfigSchema, updateCustomDomainConfigSchema, createCustomDomainConfigSchema, cpuSchema, memorySizeSchema, functionNameSchema, locationSchema, customRuntimeConfigSchema, functionDescriptionSchema, functionVersionDescriptionSchema, diskSizeSchema, instanceConcurrencySchema, environmentVariablesSchema, internetAccessSchema, functionRoleSchema, customRuntimeSchema, functionTimeoutSchema, customRuntimeLayersSchema, functionTagSchema, listFunctionsPrefixSchema, listFunctionsNextTokenSchema, listFunctionVersionsNextTokenSchema, listFunctionVersionsDirectionSchema, listFunctionVersionsLimitSchema, versionIdSchema } from "./schema.js"; import { GetFunctionRequest, ListFunctionsRequest, CreateCustomDomainRequest, UpdateCustomDomainRequest, PublishFunctionVersionRequest, ListFunctionVersionsRequest, } from "@alicloud/fc20230330"; import axios from "axios"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const server = new McpServer({ name: "alibabacloud-fc-mcp-server", version: "1.0.8", }); const remoteMode = process.env.REMOTE_MODE === 'true'; // Helper: Prepare layers function prepareLayers(layers: string[], regionID: string): string[] { layers.push(`acs:fc:${regionID}:official:layers/Python310/versions/3`); layers.push(`acs:fc:${regionID}:official:layers/Nodejs20/versions/3`); layers.push(`acs:fc:${regionID}:official:layers/Java21/versions/2`); return [...new Set(layers)]; } // Helper: Prepare environment variables function prepareEnvVars(env: Record<string, string> | undefined): Record<string, string> { env = env || {}; if (!env.PATH) { env.PATH = "/opt/python3.10/bin:/opt/nodejs20/bin:/opt/java21/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin"; } if (!env.PYTHONPATH) { env.PYTHONPATH = "/code/python"; } if (!env.JAVA_HOME) { env.JAVA_HOME = "/opt/java21"; } return env; } // Helper: Prepare fc3Props function buildFc3Props(params: any, accountId: string, layers: string[], environmentVariables: Record<string, string>) { const { location, functionName, region, cpu, memorySize, customRuntimeConfig, description, diskSize, instanceConcurrency, internetAccess, logConfig, vpcConfig, role, runtime, timeout, tags } = params; if (customRuntimeConfig && customRuntimeConfig.args && customRuntimeConfig.args.length === 0) { // unset empty args to avoid fc 400 error delete customRuntimeConfig.args; } return { functionName, region, cpu, memorySize, customRuntimeConfig, description, diskSize, instanceConcurrency, environmentVariables, internetAccess, logConfig, vpcConfig, role: role || `acs:ram::${accountId}:role/aliyunfcdefaultrole`, runtime, timeout, layers, tags, code: location, customDomain: { domainName: "auto", protocol: "HTTP", route: { path: "/*", qualifier: "LATEST", } } }; } // Helper: Write s.yaml function writeSYaml(workspacePath: string, fc3Props: any) { const alias = 'default_serverless_devs_key'; const yamlObject: any = { edition: "3.0.0", access: alias, name: "my-app", resources: { [fc3Props.functionName]: { component: "fc3", props: fc3Props, } } }; const yamlContent = yaml.dump(yamlObject); const yamlPath = path.join(workspacePath, "s.yaml"); console.error('writing yaml to: ', yamlPath, 'content: \n', yamlContent); fs.writeFileSync(yamlPath, yamlContent); return yamlPath; } async function syncYaml(tmpYamlDir: string, functionName: string, region: string, sconfig: any) { const component = await loadComponent.default("fc3", { logger }); const result = await component.sync({ //args: ['--silent', '--region', region, '-y', '--functionName', functionName, '--access', 'default_serverless_devs_key', '--name', 'my-app'], props: { functionName, region, }, name: "my-app", args: ['--silent', '--access', 'default_serverless_devs_key', '--target-dir', tmpYamlDir], resource: { name: functionName, component: "fc3", access: 'default_serverless_devs_key', }, getCredential: async () => ({ AccountID: sconfig.AccountID, AccessKeyID: sconfig.AccessKeyID, AccessKeySecret: sconfig.AccessKeySecret, SecurityToken: sconfig.SecurityToken, }), }); console.error('sync result: ', JSON.stringify(result)); const yamlFileName = `${region}_${functionName}.yaml`.replace('$', '_') const codePath = `${region}_${functionName}`.replace('$', '_') return { yamlPath: path.join(tmpYamlDir, yamlFileName), codePath: path.join(tmpYamlDir, codePath) }; } function updateYamlByInputs(yamlPath: string, originCodePath: string, args: any) { const yamlContent = fs.readFileSync(yamlPath, 'utf-8'); const yamlObject: any = yaml.load(yamlContent); const { location, functionName, region, cpu, memorySize, customRuntimeConfig, description, diskSize, instanceConcurrency, environmentVariables, layers, internetAccess, logConfig, vpcConfig, role, runtime, timeout, tags } = args; if (location) { yamlObject.resources[functionName].props.code = location; } else { yamlObject.resources[functionName].props.code = originCodePath; } if (cpu) { yamlObject.resources[functionName].props.cpu = cpu; } if (memorySize) { yamlObject.resources[functionName].props.memorySize = memorySize; } if (customRuntimeConfig) { yamlObject.resources[functionName].props.customRuntimeConfig = customRuntimeConfig; } if (description) { yamlObject.resources[functionName].props.description = description; } if (diskSize) { yamlObject.resources[functionName].props.diskSize = diskSize; } if (instanceConcurrency) { yamlObject.resources[functionName].props.instanceConcurrency = instanceConcurrency; } if (environmentVariables) { const finalEnv = prepareEnvVars(environmentVariables); yamlObject.resources[functionName].props.environmentVariables = finalEnv; } if (layers) { const finalLayers = prepareLayers(layers, region); yamlObject.resources[functionName].props.layers = finalLayers; } if (internetAccess) { yamlObject.resources[functionName].props.internetAccess = internetAccess; } if (logConfig) { yamlObject.resources[functionName].props.logConfig = logConfig; } if (vpcConfig) { yamlObject.resources[functionName].props.vpcConfig = vpcConfig; } if (role) { yamlObject.resources[functionName].props.role = role; } if (runtime) { yamlObject.resources[functionName].props.runtime = runtime; } if (timeout) { yamlObject.resources[functionName].props.timeout = timeout; } if (tags) { yamlObject.resources[functionName].props.tags = tags; } fs.writeFileSync(yamlPath, yaml.dump(yamlObject)); return yamlObject.resources[functionName].props; } // Helper: Deploy function async function deployFunction(functionName: string, yamlPath: string, sconfig: any, fc3Props: any) { const component = await loadComponent.default("fc3", { logger }); const result = await component.deploy({ props: fc3Props, name: "my-app", args: ['--silent', '-t', yamlPath, '-y'], yaml: { path: yamlPath }, resource: { name: functionName, component: "fc3", access: 'default_serverless_devs_key', }, getCredential: async () => ({ AccountID: sconfig.AccountID, AccessKeyID: sconfig.AccessKeyID, AccessKeySecret: sconfig.AccessKeySecret, SecurityToken: sconfig.SecurityToken, }), }) console.error('deploy result: ', result); console.error('deploy output: ', JSON.stringify(result)); return JSON.stringify(result); } function prepareTmpDir() { const tmpYamlDir = path.join(os.tmpdir(), `${Date.now()}`); fs.mkdirSync(tmpYamlDir, { recursive: true }); return tmpYamlDir; } function getAutoCustomDomainName(uid: string, functionName: string, regionID: string) { const normalizedFunctionName = functionName.replace(/_/g, '-').toLowerCase(); return `${normalizedFunctionName}.fcv3.${uid}.${regionID}.fc.devsapp.net`; } // Helper: Download file async function downloadFile(url: string, dest: string): Promise<void> { const response = await axios.get(url, { responseType: 'stream' }); const writer = fs.createWriteStream(dest); response.data.pipe(writer); return new Promise((resolve, reject) => { writer.on('finish', resolve); writer.on('error', reject); }); } async function createCustomRuntimeFunction(params: any): Promise<CallToolResult> { const { location, functionName, region, layers, environmentVariables } = params; if (!functionName) { return { isError: true, content: [{ type: "text", text: `执行失败,请设置functionName参数` }] }; } const accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID; const accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET; const stsToken = process.env.ALIBABA_CLOUD_SECURITY_TOKEN || ''; if (!accessKeyId || !accessKeySecret) { return { isError: true, content: [{ type: "text", text: `执行失败,请设置ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, ALIBABA_CLOUD_SECURITY_TOKEN环境变量` }] }; } const accountId = await getAccountId(); if (!accountId) { return { isError: true, content: [{ type: "text", text: `执行失败,获取accountId异常` }] }; } // Prepare layers and env const finalLayers = prepareLayers(layers, region); const finalEnv = prepareEnvVars(environmentVariables); // Build props const fc3Props = buildFc3Props(params, accountId, finalLayers, finalEnv); // Write yaml const tmpYamlDir = prepareTmpDir(); const yamlPath = writeSYaml(tmpYamlDir, fc3Props); // Deploy const sconfig: any = { AccountID: accountId, AccessKeyID: accessKeyId, AccessKeySecret: accessKeySecret, SecurityToken: stsToken, }; if (stsToken && stsToken.length > 0) { sconfig.SecurityToken = stsToken; } try { const result = await deployFunction(functionName, yamlPath, sconfig, fc3Props); return { content: [{ type: "text", text: `部署完成。output: ${result}` }] }; } catch (error: any) { return { isError: true, content: [{ type: "text", text: `部署失败:${JSON.stringify(error)}` }] }; } } async function updateCustomRuntimeFunction(params: any): Promise<CallToolResult> { const { functionName, region } = params; const accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID; const accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET; const stsToken = process.env.ALIBABA_CLOUD_SECURITY_TOKEN || ''; if (!accessKeyId || !accessKeySecret) { return { isError: true, content: [{ type: "text", text: `执行失败,请设置ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, ALIBABA_CLOUD_SECURITY_TOKEN环境变量` }] }; } const fcClient = createFcClient(region); const accountId = await getAccountId(); if (!accountId) { return { isError: true, content: [{ type: "text", text: `执行失败,获取accountId异常` }] }; } try { await fcClient.getFunction(functionName, new GetFunctionRequest({})); } catch (error: any) { if (error.statusCode !== 404) { return { isError: true, content: [{ type: "text", text: `获取函数信息失败:${JSON.stringify(error as any)}` }] }; } return { isError: true, content: [{ type: "text", text: `函数不存在` }] }; } const sconfig: any = { AccountID: accountId, AccessKeyID: accessKeyId, AccessKeySecret: accessKeySecret, SecurityToken: stsToken, }; // 同步yaml文件 const tmpYamlDir = prepareTmpDir(); const syncResult = await syncYaml(tmpYamlDir, functionName, region, sconfig); // update Yaml const fc3Props = updateYamlByInputs(syncResult.yamlPath, syncResult.codePath, params); // Deploy try { const result = await deployFunction(functionName, syncResult.yamlPath, sconfig, fc3Props); return { content: [{ type: "text", text: `部署完成。output: ${result}` }] }; } catch (error) { return { isError: true, content: [{ type: "text", text: `部署失败:${JSON.stringify(error as any)}` }] }; } } // 创建或更新函数 if (remoteMode) { server.tool( "put-custom-runtime-function", "提供构建完成的匹配阿里云自定义运行时的zip格式的代码包的可下载链接以及其他函数部署配置,创建函数并部署代码到该函数。如果函数已存在,则尝试覆盖并更新目标函数。建议使用该方法前先确认函数是否存在,如果存在需要确认更新目标函数", { codeUri: codeUriSchema, functionName: functionNameSchema, region: regionSchema, cpu: cpuSchema.default(1), memorySize: memorySizeSchema.default(2048), customRuntimeConfig: customRuntimeConfigSchema, description: functionDescriptionSchema.optional(), diskSize: diskSizeSchema, instanceConcurrency: instanceConcurrencySchema, environmentVariables: environmentVariablesSchema.default({}), internetAccess: internetAccessSchema.default(true), logConfig: logConfigSchema.optional(), vpcConfig: vpcConfigSchema.optional(), role: functionRoleSchema.optional(), runtime: customRuntimeSchema.default("custom.debian10"), timeout: functionTimeoutSchema.default(3), layers: customRuntimeLayersSchema.default([]), tags: functionTagSchema.default([]), }, async (args) => { const { codeUri } = args; if (!codeUri) { return { isError: true, content: [{ type: "text", text: `执行失败,需要指定codeUri参数` }] }; } const location = path.join(os.tmpdir(), `code-${Date.now()}.zip`); // download codeUri to location await downloadFile(codeUri, location); if (!fs.existsSync(location)) { return { isError: true, content: [{ type: "text", text: `执行失败,需要指定本地代码工程根路径` }] }; } const nextArgs = { ...args, location, } return await createCustomRuntimeFunction(nextArgs); } ); } else { server.tool( "put-custom-runtime-function", "将构建完成的匹配阿里云自定义运行时的工程,部署到函数计算。代码工程不需要手动打包,会自动处理。如果函数已存在,则尝试覆盖并更新目标函数。建议使用该方法前先确认函数是否存在", { location: locationSchema, functionName: functionNameSchema, region: regionSchema, cpu: cpuSchema.default(1), memorySize: memorySizeSchema.default(2048), customRuntimeConfig: customRuntimeConfigSchema, description: functionDescriptionSchema.optional(), diskSize: diskSizeSchema, instanceConcurrency: instanceConcurrencySchema, environmentVariables: environmentVariablesSchema.default({}), internetAccess: internetAccessSchema.default(true), logConfig: logConfigSchema.optional(), vpcConfig: vpcConfigSchema.optional(), role: functionRoleSchema.optional(), runtime: customRuntimeSchema.default("custom.debian10"), timeout: functionTimeoutSchema.default(3), layers: customRuntimeLayersSchema.default([]), tags: functionTagSchema.default([]), }, async (args) => { const { location } = args; if (!fs.existsSync(location)) { return { isError: true, content: [{ type: "text", text: `执行失败,需要指定本地代码工程根路径` }] }; } return await createCustomRuntimeFunction(args); } ); } // 更新函数 if (remoteMode) { server.tool( "update-custom-runtime-function", "更新custom runtime函数。只需要提供需要更新的参数,未提供的参数将保持不变", { codeUri: codeUriSchema.optional(), functionName: functionNameSchema.describe("要更新的目标函数名称"), region: regionSchema, cpu: cpuSchema.optional(), memorySize: memorySizeSchema.optional(), customRuntimeConfig: customRuntimeConfigSchema.optional(), description: functionDescriptionSchema.optional(), diskSize: diskSizeSchema.optional(), instanceConcurrency: instanceConcurrencySchema.optional(), environmentVariables: environmentVariablesSchema.optional(), internetAccess: internetAccessSchema.optional(), logConfig: logConfigSchema.optional(), vpcConfig: vpcConfigSchema.optional(), role: functionRoleSchema.optional(), runtime: customRuntimeSchema.optional(), timeout: functionTimeoutSchema.optional(), layers: customRuntimeLayersSchema.optional(), tags: functionTagSchema.optional(), }, async (args) => { const { codeUri } = args; let location; if (codeUri) { location = path.join(os.tmpdir(), `code-${Date.now()}.zip`); // download codeUri to location try { await downloadFile(codeUri, location); } catch (error) { return { isError: true, content: [{ type: "text", text: `执行失败,下载代码工程失败: ${JSON.stringify(error as any)}` }] }; } if (!fs.existsSync(location)) { return { isError: true, content: [{ type: "text", text: `执行失败,下载代码工程失败` }] }; } } const nextArgs = { ...args, location, } return await updateCustomRuntimeFunction(nextArgs); } ) } else { server.tool( "update-custom-runtime-function", "更新并部署custom runtime函数。如果需要修改代码,必须先完成构建。如果需要更新函数配置,需要提供更新的参数,未提供的参数将保持不变", { location: locationSchema.describe("本地代码工程的根路径,需要部署更新代码时,需要提供本地代码工程的根路径,否则可不提供").optional(), functionName: functionNameSchema.describe("要更新的目标函数名称"), region: regionSchema, cpu: cpuSchema.optional(), memorySize: memorySizeSchema.optional(), customRuntimeConfig: customRuntimeConfigSchema.optional(), description: functionDescriptionSchema.optional(), diskSize: diskSizeSchema.optional(), instanceConcurrency: instanceConcurrencySchema.optional(), environmentVariables: environmentVariablesSchema.optional(), internetAccess: internetAccessSchema.optional(), logConfig: logConfigSchema.optional(), vpcConfig: vpcConfigSchema.optional(), role: functionRoleSchema.optional(), runtime: customRuntimeSchema.optional(), timeout: functionTimeoutSchema.optional(), layers: customRuntimeLayersSchema.optional(), tags: functionTagSchema.optional(), }, async (args) => { const { location } = args; if (location && !fs.existsSync(location)) { return { isError: true, content: [{ type: "text", text: `执行失败,指定的本地代码工程路径不存在` }] }; } return await updateCustomRuntimeFunction(args); } ) } // 查询函数 server.tool( "get-function", "获取创建的函数计算的函数信息", { functionName: functionNameSchema, region: regionSchema, }, async (args) => { const { functionName, region } = args; const accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID; const accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET; if (!accessKeyId || !accessKeySecret) { return { isError: true, content: [{ type: "text", text: `执行失败,请设置ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, ALIBABA_CLOUD_SECURITY_TOKEN环境变量` }] }; } const accountId = await getAccountId(); if (!accountId) { return { isError: true, content: [{ type: "text", text: `执行失败,获取accountId异常` }] }; } const fcClient = createFcClient(region); let getFunctionResult; try { const getFunctionRequest = new GetFunctionRequest({}) getFunctionResult = await fcClient.getFunction(functionName, getFunctionRequest) } catch (error) { return { isError: true, content: [{ type: "text", text: `获取函数信息失败:${JSON.stringify(error as any)}` }] }; } const functionInfo = { ...getFunctionResult.body, } const autoDomainName = getAutoCustomDomainName(accountId, functionName, region); let getCustomDomainResult; try { getCustomDomainResult = await fcClient.getCustomDomain(autoDomainName); } catch (error: any) { if (error.statusCode !== 404) { return { isError: true, content: [{ type: "text", text: `获取函数域名信息失败:${JSON.stringify(error as any)}` }] }; } getCustomDomainResult = null; } if (getCustomDomainResult) { const routes = getCustomDomainResult.body?.routeConfig?.routes if (routes && routes.length == 1) { const route = routes[0]; if (route.functionName == functionName) { functionInfo.domain = autoDomainName; } } } return { content: [{ type: "text", text: `获取函数信息: ${JSON.stringify(functionInfo)}` }] }; } ) server.tool( "list-functions", "获取函数计算的函数列表,只返回函数名称与部分函数信息,不返回所有函数信息。如果需要获取所有函数信息,请使用get-function工具", { region: regionSchema, prefix: listFunctionsPrefixSchema.optional(), nextToken: listFunctionsNextTokenSchema.optional(), limit: z.number().describe("函数列表的返回数量上限,默认50,最大100").min(1).max(100).default(50), tags: functionTagSchema.describe("函数标签,用于过滤函数列表,只返回包含所有标签的函数").optional(), runtime: z.string().describe("函数运行时,用于过滤函数列表,只返回指定运行时的函数").optional(), }, async (args) => { const { region } = args; const fcClient = createFcClient(region); const listFunctionsRequest = new ListFunctionsRequest({ ...args }); const functions = await fcClient.listFunctions(listFunctionsRequest); return { content: [{ type: "text", text: `获取函数列表: ${JSON.stringify(functions)}` }] }; } ) //删除函数 server.tool( "delete-function", "删除函数计算的函数", { functionName: functionNameSchema, region: regionSchema, }, async (args) => { const { functionName, region } = args; const accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID; const accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET; if (!accessKeyId || !accessKeySecret) { return { isError: true, content: [{ type: "text", text: `执行失败,请设置ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, ALIBABA_CLOUD_SECURITY_TOKEN环境变量` }] }; } const accountId = await getAccountId(); if (!accountId) { return { isError: true, content: [{ type: "text", text: `执行失败,获取accountId异常` }] }; } const fcClient = createFcClient(region); try { await fcClient.deleteFunction(functionName); } catch (error) { return { isError: true, content: [{ type: "text", text: `删除函数失败:${JSON.stringify(error as any)}` }] }; } const autoCustomDomainName = getAutoCustomDomainName(accountId, functionName, region); try { await fcClient.deleteCustomDomain(autoCustomDomainName); } catch (error) { return { isError: true, content: [{ type: "text", text: `删除函数域名路由配置失败:${JSON.stringify(error as any)}` }] }; } return { content: [{ type: "text", text: `删除函数成功` }] }; } ) // 查询路由配置 server.tool( "get-custom-domain-config", "查询函数计算的域名路由配置", { region: regionSchema, domain: domainSchema, }, async (args) => { const { region, domain } = args; const accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID; const accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET; if (!accessKeyId || !accessKeySecret) { return { isError: true, content: [{ type: "text", text: `执行失败,请设置ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, ALIBABA_CLOUD_SECURITY_TOKEN环境变量` }] }; } const accountId = await getAccountId(); if (!accountId) { return { isError: true, content: [{ type: "text", text: `执行失败,获取accountId异常` }] }; } const fcClient = createFcClient(region); try { const result = await fcClient.getCustomDomain(domain); return { content: [{ type: "text", text: `查询路由配置成功。result: ${JSON.stringify(result)}` }] }; } catch (error) { return { isError: true, content: [{ type: "text", text: `查询路由配置失败:${JSON.stringify(error as any)}` }] }; } } ) // 更新域名路由配置 server.tool( "update-custom-domain-config", "更新函数计算的域名路由配置,修改域名路由配置", { region: regionSchema, domain: domainSchema, updateCustomDomainConfig: updateCustomDomainConfigSchema, }, async (args) => { const { region, domain, updateCustomDomainConfig } = args; const accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID; const accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET; if (!accessKeyId || !accessKeySecret) { return { isError: true, content: [{ type: "text", text: `执行失败,请设置ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, ALIBABA_CLOUD_SECURITY_TOKEN环境变量` }] }; } const accountId = await getAccountId(); if (!accountId) { return { isError: true, content: [{ type: "text", text: `执行失败,获取accountId异常` }] }; } const fcClient = createFcClient(region); const updateCustomDomainRequest: UpdateCustomDomainRequest = new UpdateCustomDomainRequest({ body: { authConfig: updateCustomDomainConfig.authConfig, certConfig: updateCustomDomainConfig.certConfig, tlsConfig: updateCustomDomainConfig.tlsConfig, wafConfig: updateCustomDomainConfig.wafConfig, routeConfig: updateCustomDomainConfig.routeConfig, protocol: updateCustomDomainConfig.protocol, }, }); try { const result = await fcClient.updateCustomDomain(domain, updateCustomDomainRequest); return { content: [{ type: "text", text: `更新域名路由配置成功。result: ${JSON.stringify(result)}` }] }; } catch (error) { return { isError: true, content: [{ type: "text", text: `更新域名路由配置失败:${JSON.stringify(error as any)}` }] }; } } ) // 创建域名路由配置 server.tool( "create-custom-domain-config", "创建函数计算的域名路由配置,域名必须已经CNAME到函数计算的公网域名(格式为${uid}.${regionId}.fc.aliyuncs.com,例如14**49.cn-hangzhou.fc.aliyuncs.com)上,否则会创建失败。", { region: regionSchema, createCustomDomainConfig: createCustomDomainConfigSchema, }, async (args) => { const { region, createCustomDomainConfig } = args; const accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID; const accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET; if (!accessKeyId || !accessKeySecret) { return { isError: true, content: [{ type: "text", text: `执行失败,请设置ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, ALIBABA_CLOUD_SECURITY_TOKEN环境变量` }] }; } const accountId = await getAccountId(); if (!accountId) { return { isError: true, content: [{ type: "text", text: `执行失败,获取accountId异常` }] }; } const fcClient = createFcClient(region); const createCustomDomainRequest: CreateCustomDomainRequest = new CreateCustomDomainRequest({ body: { domainName: createCustomDomainConfig.domain, protocol: createCustomDomainConfig.protocol, routeConfig: createCustomDomainConfig.routeConfig, authConfig: createCustomDomainConfig.authConfig, certConfig: createCustomDomainConfig.certConfig, tlsConfig: createCustomDomainConfig.tlsConfig, wafConfig: createCustomDomainConfig.wafConfig, }, }); try { const result = await fcClient.createCustomDomain(createCustomDomainRequest); return { content: [{ type: "text", text: `创建域名路由配置成功。result: ${JSON.stringify(result)}` }] }; } catch (error) { return { isError: true, content: [{ type: "text", text: `创建域名路由配置失败:${JSON.stringify(error as any)}` }] }; } } ) // 删除域名路由配置 server.tool( "delete-custom-domain-config", "删除函数计算的域名路由配置,CNAME记录不会被删除,需要手动删除CNAME记录", { region: regionSchema, domain: domainSchema, }, async (args) => { const { region, domain } = args; const accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID; const accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET; if (!accessKeyId || !accessKeySecret) { return { isError: true, content: [{ type: "text", text: `执行失败,请设置ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, ALIBABA_CLOUD_SECURITY_TOKEN环境变量` }] }; } const accountId = await getAccountId(); if (!accountId) { return { isError: true, content: [{ type: "text", text: `执行失败,获取accountId异常` }] }; } const fcClient = createFcClient(region); try { const result = await fcClient.deleteCustomDomain(domain); return { content: [{ type: "text", text: `删除域名路由配置成功。result: ${JSON.stringify(result)}` }] }; } catch (error) { return { isError: true, content: [{ type: "text", text: `删除域名路由配置失败:${JSON.stringify(error as any)}` }] }; } } ) // 发布函数版本 server.tool( "publish-function-version", "将函数的最新代码发布为新版本", { functionName: functionNameSchema, region: regionSchema, description: functionVersionDescriptionSchema, }, async (args) => { const { functionName, region, description } = args; const accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID; const accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET; if (!accessKeyId || !accessKeySecret) { return { isError: true, content: [{ type: "text", text: `执行失败,请设置ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, ALIBABA_CLOUD_SECURITY_TOKEN环境变量` }] }; } const accountId = await getAccountId(); if (!accountId) { return { isError: true, content: [{ type: "text", text: `执行失败,获取accountId异常` }] }; } const fcClient = createFcClient(region); try { const request = new PublishFunctionVersionRequest({ description, }) const result = await fcClient.publishFunctionVersion(functionName, request); return { content: [{ type: "text", text: `发布函数版本成功。result: ${JSON.stringify(result)}` }] }; } catch (error) { return { isError: true, content: [{ type: "text", text: `发布函数版本失败:${JSON.stringify(error as any)}` }] }; } } ) // 获取函数版本 server.tool( "list-function-versions", "获取函数计算的函数版本列表", { functionName: functionNameSchema, region: regionSchema, nextToken: listFunctionVersionsNextTokenSchema.optional(), direction: listFunctionVersionsDirectionSchema, limit: listFunctionVersionsLimitSchema.optional(), }, async (args) => { const { functionName, region, nextToken, direction, limit } = args; const accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID; const accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET; if (!accessKeyId || !accessKeySecret) { return { isError: true, content: [{ type: "text", text: `执行失败,请设置ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, ALIBABA_CLOUD_SECURITY_TOKEN环境变量` }] }; } const accountId = await getAccountId(); if (!accountId) { return { isError: true, content: [{ type: "text", text: `执行失败,获取accountId异常` }] }; } const fcClient = createFcClient(region); const listFunctionVersionsRequest = new ListFunctionVersionsRequest({ functionName, direction, }) if (nextToken) { listFunctionVersionsRequest.nextToken = nextToken; } if (limit) { listFunctionVersionsRequest.limit = limit; } try { const listFunctionVersionsResult = await fcClient.listFunctionVersions(functionName, listFunctionVersionsRequest); return { content: [{ type: "text", text: `获取函数版本列表成功。result: ${JSON.stringify(listFunctionVersionsResult)}` }] }; } catch (error) { return { isError: true, content: [{ type: "text", text: `获取函数版本列表失败:${JSON.stringify(error as any)}` }] }; } } ) // 删除函数版本 server.tool( "delete-function-version", "删除函数计算的函数版本", { functionName: functionNameSchema, region: regionSchema, versionId: versionIdSchema, }, async (args) => { const { functionName, region, versionId } = args; const accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID; const accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET; if (!accessKeyId || !accessKeySecret) { return { isError: true, content: [{ type: "text", text: `执行失败,请设置ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, ALIBABA_CLOUD_SECURITY_TOKEN环境变量` }] }; } const accountId = await getAccountId(); if (!accountId) { return { isError: true, content: [{ type: "text", text: `执行失败,获取accountId异常` }] }; } const fcClient = createFcClient(region); try { const result = await fcClient.deleteFunctionVersion(functionName, versionId); return { content: [{ type: "text", text: `删除函数版本成功。result: ${JSON.stringify(result)}` }] }; } catch (error) { return { isError: true, content: [{ type: "text", text: `删除函数版本失败:${JSON.stringify(error as any)}` }] }; } } ) // 部署函数自定义运行时runtime的提示词 server.prompt( "deploy-custom-runtime-function", () => { const promptPath = resolve(__dirname, './static/custom_runtime_prompt.md'); const promptText = fs.readFileSync(promptPath, 'utf-8').toString(); return { messages: [{ role: "user", content: { type: "text", text: promptText } }] } } ) async function main() { const transport = new StdioServerTransport(); await server.connect(transport); } main().catch((error) => { process.stderr.write(JSON.stringify(error)); process.exit(1); });

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/aliyun/alibabacloud-fc-mcp-server'

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