Skip to main content
Glama

apipost_update

Modify API documentation in ApiPost MCP by updating interface details, parameters, authentication, and responses to maintain accurate specifications.

Instructions

修改API接口文档。规则同创建:responses 只用 fields(必填),不要传 data;headers/query/body/cookies 统一用字段列表,嵌套用 .,数组用 [],example 填真实值;所有字段含父级必须写 desc,父级需显式声明。例如:{"key":"data","desc":"返回体","type":"object"},{"key":"data.user","desc":"用户","type":"object"},{"key":"data.user.id","desc":"用户ID","type":"integer","example":1}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
target_idYes要修改的接口ID
nameNo新的接口名称(可选)
methodNo新的HTTP方法(可选)
urlNo新的接口URL(可选)
descriptionNo接口详细描述(可选)。提供空字符串""可清空描述
headersNoHeaders参数JSON数组字符串(可选)。提供"[]"可删除所有headers。格式:[{"key":"Content-Type","desc":"内容类型","type":"string","required":true,"example":"application/json"}]
queryNoQuery参数JSON数组字符串(可选)。提供"[]"可删除所有query参数。格式:[{"key":"page","desc":"页码","type":"integer","required":false,"example":"1"}]
bodyNoBody参数JSON数组字符串(可选)。提供"[]"可删除所有body参数。格式:[{"key":"name","desc":"用户名","type":"string","required":true,"example":"张三"}]
cookiesNoCookies参数JSON数组字符串(可选)。提供"[]"可删除所有cookies。格式:[{"key":"session_id","desc":"会话ID","type":"string","required":false,"example":"abc123"}]
authNo认证配置JSON字符串(可选)。提供"{}"可删除认证配置。格式:{"type":"bearer","bearer":{"key":"your_token"}}
responsesNo响应示例JSON数组字符串(可选)。提供"[]"可删除所有响应示例。格式:[{"name":"成功响应","status":200,"data":{"code":0},"fields":[{"key":"code","desc":"状态码","type":"integer","example":"0"}]}]

Implementation Reference

  • src/index.ts:924-944 (registration)
    Registration of the 'apipost_update' tool in the MCP server, including name, description, and detailed inputSchema for parameters like target_id, name, method, url, etc.
        name: 'apipost_update',
        description: '修改API接口文档。规则同创建:responses 只用 fields(必填),不要传 data;headers/query/body/cookies 统一用字段列表,嵌套用 .,数组用 [],example 填真实值;所有字段含父级必须写 desc,父级需显式声明。例如:{"key":"data","desc":"返回体","type":"object"},{"key":"data.user","desc":"用户","type":"object"},{"key":"data.user.id","desc":"用户ID","type":"integer","example":1}',
        inputSchema: {
            type: 'object',
            properties: {
                target_id: { type: 'string', description: '要修改的接口ID' },
                name: { type: 'string', description: '新的接口名称(可选)' },
                method: { type: 'string', enum: ['GET', 'POST', 'PUT', 'DELETE'], description: '新的HTTP方法(可选)' },
                url: { type: 'string', description: '新的接口URL(可选)' },
                description: { type: 'string', description: '接口详细描述(可选)。提供空字符串""可清空描述' },
                headers: { type: 'string', description: 'Headers参数JSON数组字符串(可选)。提供"[]"可删除所有headers。格式:[{"key":"Content-Type","desc":"内容类型","type":"string","required":true,"example":"application/json"}]' },
                query: { type: 'string', description: 'Query参数JSON数组字符串(可选)。提供"[]"可删除所有query参数。格式:[{"key":"page","desc":"页码","type":"integer","required":false,"example":"1"}]' },
                body: { type: 'string', description: 'Body参数JSON数组字符串(可选)。提供"[]"可删除所有body参数。格式:[{"key":"name","desc":"用户名","type":"string","required":true,"example":"张三"}]' },
                cookies: { type: 'string', description: 'Cookies参数JSON数组字符串(可选)。提供"[]"可删除所有cookies。格式:[{"key":"session_id","desc":"会话ID","type":"string","required":false,"example":"abc123"}]' },
                auth: { type: 'string', description: '认证配置JSON字符串(可选)。提供"{}"可删除认证配置。格式:{"type":"bearer","bearer":{"key":"your_token"}}' },
                responses: { type: 'string', description: '响应示例JSON数组字符串(可选)。提供"[]"可删除所有响应示例。格式:[{"name":"成功响应","status":200,"data":{"code":0},"fields":[{"key":"code","desc":"状态码","type":"integer","example":"0"}]}]' }
            },
            required: ['target_id'],
            additionalProperties: false
        }
    },
  • The core handler for 'apipost_update' tool. Checks permissions, retrieves existing API details via '/open/apis/details', merges provided arguments with original config using helpers like buildApiConfig and normalizeResponses, constructs update payload, performs API update via '/open/apis/update', and returns formatted success response with modification summary.
    case 'apipost_update':
        if (!checkSecurityPermission('write')) {
            throw new Error(`🔒 安全模式 "${APIPOST_SECURITY_MODE}" 不允许修改操作。需要 "limited" 或 "full" 模式。`);
        }
        const targetId = args.target_id;
        const newName = args.name;
        const newMethod = args.method;
        const newUrl = args.url ? applyUrlPrefix(args.url) : undefined;
        if (!targetId) {
            throw new Error('请提供要修改的API接口ID');
        }
        // 获取原接口信息
        const getResult = await apiClient.post('/open/apis/details', {
            project_id: currentWorkspace.projectId,
            target_ids: [targetId]
        });
        if (getResult.data.code !== 0) {
            throw new Error(`获取接口详情失败: ${getResult.data.msg}`);
        }
        const originalApi = getResult.data.data.list[0]; // 获取数组中的第一个接口
        if (!originalApi) {
            throw new Error(`未找到接口详情 (ID: ${targetId})。可能原因:1) 接口不存在 2) 无权限访问 3) 接口已被删除。请检查接口ID是否正确。`);
        }
        // 构建增量更新配置对象
        const { config: newConfig, providedFields } = buildApiConfig(args);
        const mergedDescription = providedFields.has('description')
            ? newConfig.description
            : (originalApi.description || '');
        const mergedRequest = {
            auth: providedFields.has('auth') ? (newConfig.auth || { type: 'inherit' }) : (originalApi.request?.auth || { type: 'inherit' }),
            pre_tasks: originalApi.request?.pre_tasks || [],
            post_tasks: originalApi.request?.post_tasks || [],
            header: {
                parameter: providedFields.has('headers')
                    ? convertParams(newConfig.headers || [])
                    : (originalApi.request?.header?.parameter || [])
            },
            query: {
                query_add_equal: originalApi.request?.query?.query_add_equal ?? 1,
                parameter: providedFields.has('query')
                    ? convertParams(newConfig.query || [])
                    : (originalApi.request?.query?.parameter || [])
            },
            body: providedFields.has('body')
                ? buildBodySection(newConfig.body || [])
                : (originalApi.request?.body || buildBodySection([])),
            cookie: {
                cookie_encode: originalApi.request?.cookie?.cookie_encode ?? 1,
                parameter: providedFields.has('cookies')
                    ? convertParams(newConfig.cookies || [])
                    : (originalApi.request?.cookie?.parameter || [])
            },
            restful: originalApi.request?.restful || { parameter: [] }
        };
        const responseSection = providedFields.has('responses')
            ? normalizeResponses(newConfig.responses, {
                fallbackExamples: [],
                useDefaultWhenMissing: false,
                keepEmpty: true,
                isCheckResult: originalApi.response?.is_check_result ?? 1
            })
            : {
                example: originalApi.response?.example || [],
                is_check_result: originalApi.response?.is_check_result ?? 1
            };
        const updateTemplate = {
            project_id: currentWorkspace.projectId,
            target_id: targetId,
            parent_id: originalApi.parent_id || '0',
            target_type: originalApi.target_type || 'api',
            name: newName || originalApi.name,
            method: newMethod || originalApi.method,
            url: newUrl || originalApi.url,
            protocol: originalApi.protocol || 'http/1.1',
            description: mergedDescription,
            version: (originalApi.version || 0) + 1,
            mark_id: originalApi.mark_id || '1',
            is_force: originalApi.is_force ?? -1,
            sort: originalApi.sort ?? 0,
            status: originalApi.status ?? 1,
            is_deleted: originalApi.is_deleted ?? -1,
            is_conflicted: originalApi.is_conflicted ?? -1,
            request: mergedRequest,
            response: responseSection,
            attribute_info: originalApi.attribute_info || {},
            tags: originalApi.tags || []
        };
        // 执行修改
        const updateResult = await apiClient.post('/open/apis/update', updateTemplate);
        if (updateResult.data.code !== 0) {
            throw new Error(`修改失败: ${updateResult.data.msg}`);
        }
        // 统计修改的字段
        const changedFields = [];
        if (newName && newName !== originalApi.name)
            changedFields.push('名称');
        if (newMethod && newMethod !== originalApi.method)
            changedFields.push('方法');
        if (newUrl && newUrl !== originalApi.url)
            changedFields.push('URL');
        // 检查是否有配置相关的更新
        if (providedFields.size > 0)
            changedFields.push('配置');
        const changedFieldsText = changedFields.length > 0 ? `\n修改字段: ${changedFields.join(', ')}` : '\n仅更新版本';
    
        let updateText = `接口修改成功!\n接口ID: ${targetId}\n`;
        if (newName)
            updateText += `新名称: ${newName}\n`;
        if (newMethod)
            updateText += `新方法: ${newMethod}\n`;
        if (newUrl)
            updateText += `新URL: ${newUrl}\n`;
        updateText += `版本: v${updateTemplate.version}\n修改字段: ${changedFields.join(', ') || '仅更新版本'}`;
        return {
            content: [{ type: 'text', text: updateText }]
        };
  • Helper function buildApiConfig used by apipost_update to parse and validate tool input parameters into structured config, ensuring all fields have descriptions.
    function buildApiConfig(args) {
        const config = {};
        const providedFields = new Set();
        if (args.description !== undefined) {
            config.description = args.description;
            providedFields.add('description');
        }
        if (args.headers !== undefined) {
            config.headers = parseConfigParam(args.headers);
            ensureFieldsHaveDesc(config.headers, 'headers');
            providedFields.add('headers');
        }
        if (args.query !== undefined) {
            config.query = parseConfigParam(args.query);
            ensureFieldsHaveDesc(config.query, 'query');
            providedFields.add('query');
        }
        if (args.body !== undefined) {
            config.body = parseConfigParam(args.body);
            ensureFieldsHaveDesc(config.body, 'body');
            providedFields.add('body');
        }
        if (args.cookies !== undefined) {
            config.cookies = parseConfigParam(args.cookies);
            ensureFieldsHaveDesc(config.cookies, 'cookies');
            providedFields.add('cookies');
        }
        if (args.auth !== undefined) {
            config.auth = parseApiConfig(args.auth);
            providedFields.add('auth');
        }
        if (args.responses !== undefined) {
            config.responses = parseConfigParam(args.responses);
            ensureResponsesFieldsHaveDesc(config.responses);
            providedFields.add('responses');
        }
        return { config, providedFields };
    }
  • Helper function normalizeResponses crucial for processing responses in apipost_update, converting user-provided fields to ApiPost-compatible example structures.
    function normalizeResponses(responses, options = {}) {
        const { fallbackExamples = [], useDefaultWhenMissing = true, keepEmpty = true, isCheckResult = 1 } = options;
        const hasInput = Array.isArray(responses);
        const inputLength = hasInput ? responses.length : 0;
        // 用户显式提供了空数组并且允许保留空响应
        if (hasInput && inputLength === 0) {
            return { example: keepEmpty ? [] : fallbackExamples, is_check_result: isCheckResult };
        }
        // 未提供响应,使用回退或默认
        if (!hasInput) {
            if (fallbackExamples.length > 0) {
                return { example: fallbackExamples, is_check_result: isCheckResult };
            }
            if (!useDefaultWhenMissing) {
                return { example: [], is_check_result: isCheckResult };
            }
            const defaultData = generateResponseData(undefined);
            return {
                example: [{
                        example_id: '1',
                        raw: JSON.stringify(defaultData, null, 4),
                        raw_parameter: [],
                        headers: [],
                        expect: {
                            code: '200',
                            content_type: 'application/json',
                            is_default: 1,
                            mock: JSON.stringify(defaultData),
                            name: '成功响应',
                            schema: { type: 'object', properties: {} },
                            verify_type: 'schema',
                            sleep: 0
                        }
                    }],
                is_check_result: isCheckResult
            };
        }
        // 已经是 ApiPost 的响应结构,直接透传
        if (responses.some(isApiPostResponseExample)) {
            return { example: responses, is_check_result: isCheckResult };
        }
        // 简化格式 -> ApiPost 兼容格式
        const converted = responses.map((resp, index) => ({
            example_id: String(index + 1),
            raw: (() => {
                const fields = Array.isArray(resp.fields) ? resp.fields : [];
                if (fields.length === 0) {
                    throw new Error('responses.fields 必填且不能为空,data 字段已禁用,请提供字段列表');
                }
                const expandedFields = expandFieldListWithParents(fields);
                const descMap = buildDescMap(expandedFields);
                const rawData = buildJsonFromFieldList(expandedFields);
                return APIPOST_INLINE_COMMENTS && expandedFields.length > 0
                    ? stringifyWithComments(rawData, descMap)
                    : JSON.stringify(rawData, null, 4);
            })(),
            raw_parameter: convertParams(expandFieldListWithParents(resp.fields || [])),
            headers: [],
            expect: {
                code: String(resp.status ?? 200),
                content_type: 'application/json',
                is_default: index === 0 ? 1 : -1,
                mock: JSON.stringify(buildJsonFromFieldList(expandFieldListWithParents(resp.fields || []))),
                name: resp.name || (index === 0 ? '成功响应' : `响应${index + 1}`),
                schema: resp.schema || { type: 'object', properties: {} },
                verify_type: 'schema',
                sleep: 0
            }
        }));
        return { example: converted, is_check_result: isCheckResult };
    }

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/jlcodes99/apipost-mcp'

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