Skip to main content
Glama
cheungxin

JianDaoYun MCP Server

by cheungxin

delete_form_data

Remove specific form data entries from JianDaoYun applications by providing data IDs, with optional automation triggering for workflow integration.

Instructions

Delete one or more form data entries

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
appIdYesThe JianDaoYun application ID
appKeyNoThe JianDaoYun application key (API key) (optional, will use JIANDAOYUN_APP_KEY from environment if not provided)
formIdYesThe form ID (can be form ID or app ID)
dataIdsYesData ID(s) to delete
isStartTriggerNoWhether to trigger automation

Implementation Reference

  • MCP tool handler implementation for 'delete_form_data'. Validates parameters, resolves form ID, instantiates JianDaoYunClient, calls deleteFormData, handles response and errors.
    case 'delete_form_data': {
      const { formId, dataIds, isStartTrigger } = args as {
        formId: string;
        dataIds: string | string[];
        isStartTrigger?: boolean;
      };
      const { appId, appKey, baseUrl } = getDefaultParams(args);
      
      // 验证必需参数
      if (!appKey) {
        throw new Error('appKey is required. Please set JIANDAOYUN_APP_KEY in MCP server configuration.');
      }
      if (!appId) {
        throw new Error('appId is required. Please provide it as parameter.');
      }
    
      try {
        // 创建客户端实例
        const jdyClient = new JianDaoYunClient({
          appId,
          appKey,
          baseUrl
        });
        
        const resolved = await resolveFormId(formId, appKey);
        const result = await jdyClient.deleteFormData(resolved.formId, dataIds, {
          isStartTrigger,
        });
    
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify({
                success: true,
                result,
                message: `成功删除 ${Array.isArray(dataIds) ? dataIds.length : 1} 条记录`,
                formUsed: resolved.formId,
                appId: resolved.appId || appId
              }, null, 2),
            },
          ],
        };
      } catch (error) {
        throw createEnhancedError(error, '删除表单数据');
      }
    }
  • src/index.ts:431-461 (registration)
    Tool registration entry for 'delete_form_data' in the ListToolsRequestSchema response, including name, description, and input schema definition.
    {
      name: 'delete_form_data',
      description: 'Delete one or more form data entries',
      inputSchema: {
        type: 'object',
        properties: {
          appId: {
            type: 'string',
            description: 'The JianDaoYun application ID',
          },
          appKey: {
            type: 'string',
            description: 'The JianDaoYun application key (API key) (optional, will use JIANDAOYUN_APP_KEY from environment if not provided)',
          },
          formId: {
            type: 'string',
            description: 'The form ID (can be form ID or app ID)',
          },
          dataIds: {
            type: ['string', 'array'],
            description: 'Data ID(s) to delete',
            items: { type: 'string' },
          },
          isStartTrigger: {
            type: 'boolean',
            description: 'Whether to trigger automation',
          },
        },
        required: ['appId', 'formId', 'dataIds'],
      },
    },
  • Core implementation of form data deletion in JianDaoYunClient class. Handles single or batch delete via API endpoints, constructs request, sends POST, processes response and errors.
    async deleteFormData(formId: string, dataId: string | string[], options?: { isStartTrigger?: boolean }): Promise<any> {
      try {
        const isMultiple = Array.isArray(dataId);
        const endpoint = isMultiple ? '/v5/app/entry/data/batch_delete' : '/v5/app/entry/data/delete';
        
        const requestData: any = {
          app_id: this.config.appId,
          entry_id: formId
        };
    
        if (isMultiple) {
          requestData.data_ids = dataId;
        } else {
          requestData.data_id = dataId;
        }
    
        if (options?.isStartTrigger !== undefined) {
          requestData.is_start_trigger = options.isStartTrigger;
        }
    
        const response = await this.axios.post<ApiResponse>(endpoint, requestData);
    
        if (response.data.code !== 0) {
          throw new Error(`Failed to delete form data: ${response.data.msg}`);
        }
    
        return response.data.data;
      } catch (error) {
        if (axios.isAxiosError(error)) {
          throw new Error(`API request failed: ${error.response?.data?.msg || error.message}`);
        }
        throw error;
      }
    }
  • Helper function to resolve formId, handling both direct form IDs and app IDs by fetching form lists if necessary, with suggestions for multiple forms.
    async function resolveFormId(inputId: string, appKey: string): Promise<{ formId: string; appId?: string; suggestions?: string[] }> {
      // 如果输入看起来像表单ID(通常24位字符),直接返回
      if (inputId.length === 24 && /^[a-f0-9]{24}$/i.test(inputId)) {
        return { formId: inputId };
      }
    
      // 尝试作为应用ID处理
      const appList = await getAppList(appKey);
      const targetApp = appList.find(app => app.app_id === inputId);
      
      if (targetApp) {
        // 这是一个应用ID,需要获取其下的表单列表
        try {
          const response = await axios.post(
            `${process.env.JIANDAOYUN_BASE_URL || 'https://api.jiandaoyun.com'}/api/v1/app/${inputId}/entry/list`,
            {},
            {
              headers: {
                'Authorization': `Bearer ${appKey}`,
                'Content-Type': 'application/json'
              }
            }
          );
          
          const forms = response.data || [];
          if (forms.length === 0) {
            throw new Error(`应用 "${targetApp.name}" 下没有找到可用的表单`);
          }
          
          // 如果只有一个表单,直接返回
          if (forms.length === 1) {
            return { 
              formId: forms[0].entry_id || forms[0]._id,
              appId: inputId
            };
          }
          
          // 多个表单时,返回建议列表
          const suggestions = forms.map((form: any) => 
            `${form.name || '未命名表单'} (${form.entry_id || form._id})`
          );
          
          return {
            formId: forms[0].entry_id || forms[0]._id, // 默认返回第一个
            appId: inputId,
            suggestions
          };
        } catch (error) {
          throw new Error(`无法获取应用 "${targetApp.name}" 下的表单列表: ${error instanceof Error ? error.message : '未知错误'}`);
        }
      }
      
      // 既不是标准表单ID也不是已知应用ID,直接尝试使用
      return { formId: inputId };
    }
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. It states the destructive action ('Delete') but lacks critical details: authentication requirements (appId/appKey), whether deletions are permanent/reversible, rate limits, error handling, or what happens with 'isStartTrigger'. This is inadequate for a mutation tool with 5 parameters.

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

Conciseness5/5

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

The description is a single, efficient sentence with zero waste. It front-loads the core action and resource, making it immediately understandable. No extraneous information or repetition.

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 destructive mutation tool with 5 parameters, no annotations, and no output schema, the description is incomplete. It lacks authentication context, behavioral traits (permanence, side-effects), error handling, and output expectations. Sibling tools suggest a rich form-data ecosystem, but the description doesn't situate this tool within it.

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?

Schema description coverage is 100%, so parameters are fully documented in the schema. The description adds no additional meaning beyond implying 'dataIds' can be singular or plural. It doesn't explain parameter interactions, dependencies, or provide examples. Baseline 3 is appropriate given schema coverage.

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 action ('Delete') and resource ('form data entries'), and specifies scope ('one or more'). It distinguishes from siblings like 'get_form_data', 'update_form_data', and 'submit_form_data' by indicating a destructive operation. However, it doesn't explicitly mention the JianDaoYun platform context, which is implied by the schema.

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 doesn't mention prerequisites (e.g., needing existing form data), exclusions, or comparisons to siblings like 'update_form_data' or 'query_form_data'. Usage context is implied but not stated.

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/cheungxin/jiandaoyun-mcp-server'

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