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 };
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. While it mentions that the tool modifies API documentation, it doesn't describe what happens on success/failure, whether changes are reversible, permission requirements, rate limits, or what the response looks like. The formatting rules provided are helpful but don't constitute comprehensive behavioral transparency for a mutation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is relatively concise but front-loads formatting rules rather than the core purpose. While the formatting guidance is important, it dominates the description at the expense of other critical information. The single paragraph structure could be improved with clearer separation between purpose, usage, and formatting requirements.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with 11 parameters, no annotations, and no output schema, the description is incomplete. It focuses heavily on formatting rules but neglects behavioral aspects like error handling, success responses, authentication requirements, and side effects. The description doesn't adequately compensate for the lack of structured metadata about this complex update operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema description coverage, the schema already documents all 11 parameters thoroughly. The description adds some value by providing formatting examples and clarifying that certain parameters can be cleared with empty values, but doesn't significantly enhance understanding beyond what the schema provides. The baseline of 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('修改' meaning 'modify') and resource ('API接口文档' meaning 'API interface documentation'), making the purpose immediately understandable. However, it doesn't explicitly differentiate this update tool from potential siblings like 'apipost_detail' or 'apipost_smart_create', which might also involve API documentation operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It mentions '规则同创建' (rules same as creation), which implies a relationship with creation tools but doesn't specify when to choose update over creation or other siblings. There's no mention of prerequisites, error conditions, or typical use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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