This skill provides a complete guide to building pages, retrieving data in real time, and manipulating data using the Mingdao Cloud HAP V3 API.
Overview
Mingdao Cloud HAP (High-performance Application Platform) is a super application platform, through which many applications can be built. Through the HAP V3 API, you can:
- In a custom view pluginCall the V3 API to manipulate data
- In a standalone frontend pageUse the V3 API to orchestrate business logic
- Retrieve and manipulate in real timeData in Mingdao Cloud applications
Core capabilities:
- ✅ Complete API usage workflow (from building an application from scratch to data manipulation)
- ✅ Detailed field type handling specifications
- ✅ Complete Filter syntax
- ✅ In-depth query guide for associated fields
- ✅ Common pitfalls and solutions
- ✅ Performance optimization best practices
Detailed documentation: Refer to references/hap-api-usage-guide.md to get the complete API usage specifications
Quick Start
1. Obtain API credentials
Method 1: Extract from MCP configuration (recommended)
If the user has already configured the HAP application execution MCP, the AI assistant shouldautomatically extract the authentication key from the MCP configuration, rather than asking the user to enter it manually.
Automated extraction steps
-
Read the Cursor global settings file
- macOS:
~/Library/Application Support/Cursor/User/settings.json - Windows:
%APPDATA%\Cursor\User\settings.json - Linux:
~/.config/Cursor/User/settings.json
- macOS:
-
Find the MCP configuration
- In the
mcpServersobject, find servers starting withhap-mcp-server configurations - Identify the application execution MCP (contains the
urlfield and the URL points toapi.mingdao.com/mcp)
- In the
-
Parse parameters from the URL
- MCP configuration format example:
{ "mcpServers": { "hap-mcp-应用名": { "url": "https://api.mingdao.com/mcp?HAP-Appkey=6802bfa5da37d75f&HAP-Sign=MWZmZWU1YmMyMzE4ZTAxYjY3NTViYjM5NzhlNTdhOTIwZWFhYTc2Y2I2YzljNWMzNDFmMjk4NTM2N2M0YTg2OA==", "type": "http" } } } -
Extract the authentication key
- Extract from the URL query parameters the
HAP-Appkeyvalue - Extract from the URL query parameters the
HAP-Signvalue - Note: URL parameters may be URL-encoded and need to be decoded correctly
- Extract from the URL query parameters the
Code example (AI assistant operation)
// 1. 读取配置文件
const settingsPath = process.platform === 'darwin'
? `${process.env.HOME}/Library/Application Support/Cursor/User/settings.json`
: process.platform === 'win32'
? `${process.env.APPDATA}/Cursor/User/settings.json`
: `${process.env.HOME}/.config/Cursor/User/settings.json`;
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
// 2. 查找 HAP MCP 配置
const mcpServers = settings.mcpServers || {};
const hapMcpConfig = Object.entries(mcpServers).find(
([name, config]) => name.startsWith('hap-mcp-') && config.url
);
if (hapMcpConfig) {
const [, config] = hapMcpConfig;
const url = new URL(config.url);
// 3. 提取 Appkey 和 Sign
const appkey = url.searchParams.get('HAP-Appkey');
const sign = url.searchParams.get('HAP-Sign');
// 4. 使用提取的密钥
console.log('Appkey:', appkey);
console.log('Sign:', sign);
}
Actual operation process
When the user needs to call the HAP API, the AI should:
-
Check whether MCP is configured
- Read the Cursor global settings file
- Find the
hap-mcp-*configuration
-
Extract authentication information
- If an MCP configuration is found, automatically extract the Appkey and Sign from the URL
- If multiple MCP configurations are found, ask the user which application to use
-
Use the extracted key
- Use the extracted
HAP-AppkeyandHAP-Sign - If extraction fails, prompt the user to provide it manually or check the MCP configuration
- Use the extracted
Notes
- ✅ Prioritize using the MCP configuration: If the user has configured MCP, prioritize extracting from the configuration
- ✅ URL decoding: Note that URL parameters may be encoded and need to be properly decoded
- ✅ Multiple applications: If multiple HAP MCPs are configured, ask the user which application to use
- ⚠️ Configuration does not exist: If no MCP configuration is found, prompt the user to configure MCP first or manually provide the key
- ⚠️ Permission issue: If the configuration file cannot be read, prompt the user to check the file permissions
Method 2: Manual retrieval
If the user has not configured MCP or needs to provide it manually:
- Log in to Mingdao Cloud → Application → Settings → API Key
- Copy the Appkey and Sign
- Or provide the MCP configuration information and let the AI extract it automatically
2. Configure request headers
All HAP V3 API requests require the following request headers:
const headers = {
'Content-Type': 'application/json',
'HAP-Appkey': 'your-app-key',
'HAP-Sign': 'your-sign-key'
};
⚠️ Note: request headers use HAP-Appkey and HAP-Sign(not AppKey and Sign)
3. Get API documentation
Use Apifox MCP Server (recommended):
{
"应用 API - API 文档": {
"command": "npx",
"args": [
"-y",
"apifox-mcp-server@latest",
"--site-id=5442569"
]
}
}
Online documentation resources:
Core workflow
Phase 1: Preparation
Step 1: Get API credentials
- Preferred method: Automatically extract the Appkey and Sign from the Cursor MCP configuration (if the user has configured it)
- Alternative method: Manually retrieve from the HAP backend or have the user provide them
Step 2: Configure API request headers
- Set the request headers using the extracted or provided Appkey and Sign
- Set the
HAP-AppkeyandHAP-Signrequest headers
Phase 2: Create application structure
Step 3: Get application information (optional)
GET /v3/app/info
Step 4: Create worksheet
POST /v3/app/worksheets
{
"name": "客户信息表",
"alias": "customers",
"fields": [
{
"name": "客户名称",
"alias": "customer_name",
"type": "Text",
"isTitle": true,
"required": true
}
]
}
Detailed specifications: Refer to references/hap-api-usage-guide.md Section 1
Phase 3: Populate data
Step 5: Prepare option field mappings
- For single-select/multi-select fields, you need to get the option key (UUID) first
- Query the worksheet structure to get the options list
Step 6: Create records
POST /v3/app/worksheets/{worksheet_id}/rows
{
"fields": [
{
"id": "customer_name",
"value": "明道云科技有限公司"
},
{
"id": "customer_type",
"value": ["74c7b607-864d-4cc4-b401-28acba2636e9"] // ⚠️ 使用选项key
}
],
"triggerWorkflow": true
}
Key points:
- ⚠️ Option fields must use the key, not the display text
- ⚠️ Option fields must use array format even for single-select
- ✅ Numeric fields pass numbers when writing, and return strings when reading
Detailed specifications: Refer to references/hap-api-usage-guide.md Section 3
Phase 4: Query and analyze data
Step 7: Query record list
POST /v3/app/worksheets/{worksheet_id}/rows/list
{
"filter": {
"type": "group",
"logic": "AND",
"children": [
{
"type": "condition",
"field": "customer_type",
"operator": "eq",
"value": ["74c7b607-864d-4cc4-b401-28acba2636e9"] // 使用key
}
]
},
"sorts": [{
"field": "annual_budget",
"isAsc": false
}],
"pageIndex": 1,
"pageSize": 20
}
Detailed specifications: Refer to references/hap-api-usage-guide.md Section 4
Filter specification ⭐Key point
Filter object structure
Basic structure:
Filter = {
type: 'group' | 'condition';
// type='group' 时的字段
logic?: 'AND' | 'OR';
children?: Filter[]; // 子条件,最多两层嵌套
// type='condition' 时的字段
field?: string; // 字段ID或别名
operator?: string; // 操作符
value?: any[]; // 值数组
}
Rules:
- The top level must be of
grouptype - At most two levels of nesting: group → group → condition
- The children of the same group must have consistent types
- group must specify
logic(AND/OR) - condition must specify
field,operator
Complete operator list
| Operator | Description | Requires value | Value format | Applicable fields |
|---|---|---|---|---|
eq |
Equals | ✅ | ["值"] |
All types |
ne |
Not equal to | ✅ | ["值"] |
All types |
contains |
Contains | ✅ | ["值"] |
Text, MultipleSelect |
notcontains |
Does not contain | ✅ | ["值"] |
Text, MultipleSelect |
startswith |
Starts with | ✅ | ["值"] |
Text |
endswith |
Ends with | ✅ | ["值"] |
Text |
gt |
Greater than | ✅ | ["值"] |
Number, Date |
gte |
Greater than or equal to | ✅ | ["值"] |
Number, Date |
lt |
Less than | ✅ | ["值"] |
Number, Date |
lte |
Less than or equal to | ✅ | ["值"] |
Number, Date |
between |
Between | ✅ | ["最小值", "最大值"] |
Number, Date |
isempty |
Is empty | ❌ | Not required | All types |
isnotempty |
Is not empty | ❌ | Not required | All types |
belongsto |
Belongs to | ✅ | ["ID1", "ID2"] |
Relation, Department |
in |
In... | ✅ | ["值1", "值2"] |
All types |
concurrent |
Also contains | ✅ | ["值1", "值2"] |
MultipleSelect |
Filter examples
Example 1: Single-select field filtering (⚠️ must use key)
{
"type": "group",
"logic": "AND",
"children": [{
"type": "condition",
"field": "customer_type",
"operator": "eq",
"value": ["74c7b607-864d-4cc4-b401-28acba2636e9"] // ✅ 使用key
}]
}
// ❌ 错误: value: ["成交客户"] // 不能用显示文本!
Example 2: Numeric range filtering (⚠️ value must be a string array)
{
"type": "condition",
"field": "annual_budget",
"operator": "between",
"value": ["500000", "2000000"] // ✅ 字符串数组
}
// ❌ 错误: value: [500000, 2000000] // 不能用数字!
Example 3: Relation field filtering (⚠️ must use belongsto)
{
"type": "condition",
"field": "related_customer",
"operator": "belongsto", // ✅ 关联字段用 belongsto
"value": ["customer-row-id"]
}
// ❌ 错误: operator: "eq" // 关联字段不支持 eq!
Detailed specification: Reference references/hap-api-usage-guide.md Section 4
Field type handling specification
Key field type handling
1. Option fields (SingleSelect/MultipleSelect) ⭐⭐⭐
Write: Must pass an array of option keys
{
"id": "customer_type",
"value": ["74c7b607-864d-4cc4-b401-28acba2636e9"] // 选项key
}
Read: Returns an array of objects containing key and value
{
"customer_type": [
{
"key": "74c7b607-864d-4cc4-b401-28acba2636e9",
"value": "成交客户"
}
]
}
⚠️ Key point:
- Even for single-select, use an array
["key"] - Cannot pass display text
["成交客户"], must use key - When filtering, must use key, cannot use display text
2. Attachment field (Attachment) ⭐
Write: Supports URL and base64
{
"id": "attachments",
"type": "0", // 0=覆盖, 1=追加
"value": [{
"name": "产品宣传册.pdf",
"url": "https://example.com/brochure.pdf"
}]
}
Read: Returns an array of attachment objects
{
"attachments": [{
"file_id": "...",
"file_name": "...",
"downloadUrl": "https://...", // ⚠️ 使用 downloadUrl
"file_size": 2048576
}]
}
⚠️ Important note:
- Attachment upload is processed asynchronously, usually requires 5-10 seconds
- API returning success does not mean the attachment upload is complete
- Use
downloadUrlinstead ofurl
3. Relation field (Relation) ⭐⭐⭐
Write: Pass an array of record IDs
{
"id": "related_customer",
"value": ["945e6503-3823-4e91-9d84-a53f8bdd6fc5"] // 记录rowid
}
Read: Returns an array of objects (containing only sid and name)
{
"related_customer": [{
"sid": "945e6503-3823-4e91-9d84-a53f8bdd6fc5",
"name": "明道云科技有限公司"
}]
}
Get complete related data:
// 方法1: 使用专用 API
GET /v3/app/worksheets/{worksheet_id}/rows/{row_id}/relations/{field_id}
// 方法2: 使用 sid 查询目标表
POST /v3/app/worksheets/{target_worksheet_id}/rows/list
{
"filter": {
"type": "group",
"logic": "AND",
"children": [{
"type": "condition",
"field": "rowid", // ⚠️ 使用系统字段 rowid
"operator": "in",
"value": ["sid1", "sid2"] // 传入关联记录的 sid
}]
}
}
Detailed specification: Reference references/hap-api-usage-guide.md Section 6
4. Member field (Collaborator)
Write: Pass an array of user IDs
{
"id": "owner",
"value": ["user-account-id-123"] // 用户ID,不是用户名
}
Get user ID:
POST /v3/users/lookup
{
"name": "张三" // 精确匹配姓名
}
5. Numeric field (Number)
Write: Pass a number type
{
"id": "annual_budget",
"value": 1000000.50
}
Read: Returns a string
{
"annual_budget": "1000000.50"
}
⚠️ Note: Write numbers, read strings
Detailed specification: Reference references/hap-api-usage-guide.md Sections 2, 3
triggerWorkflow parameter details ⭐Important
triggerWorkflow The parameter controls whether to trigger worksheet-related workflows during data operations.
Applicable scope:
- ✅ Create record
- ✅ Batch create
- ✅ Update record
- ✅ Batch update
- ✅ Delete record
- ✅ Batch delete
Parameter description:
| Parameter value | Description | Default value | Use cases |
|---|---|---|---|
true |
Trigger workflow | ✅ Yes | Normal business operations, need to execute automated processes |
false |
Do not trigger workflow | ❌ No | Data migration, batch initialization, test data |
✅ Should be set to true scenarios:
- Normal business operations (users submit forms, update status, etc.)
- Operations that require automated processing
❌ Should be set to false scenarios:
- Data migration and import
- Batch data initialization
- Scheduled sync tasks
- Testing and debugging
Performance impact:
triggerWorkflow: false- API responds quickly, usually < 500mstriggerWorkflow: true- Need to wait for workflow execution, may take 1-5 seconds
Detailed description: Refer to references/hap-api-usage-guide.md Section 3.2
Common pitfalls and solutions ⭐⭐⭐
Pitfall 1: Filtering option fields using display text
Problem: Returns empty results when filtering single-select/multi-select fields
Incorrect example:
{
"field": "customer_type",
"operator": "eq",
"value": ["成交客户"] // ❌ 使用了显示文本
}
Correct approach:
{
"field": "customer_type",
"operator": "eq",
"value": ["74c7b607-864d-4cc4-b401-28acba2636e9"] // ✅ 使用选项key
}
Solution:
- Query the worksheet structure during initialization and cache the option mapping
- Or query one record first and get the key from the returned data
- Build a value → key mapping table
Pitfall 2: Filtering numeric fields using numeric types
Problem: Numeric filtering returns no results or throws an error
Incorrect example:
{
"field": "annual_budget",
"operator": "gt",
"value": [1000000] // ❌ 数字类型
}
Correct approach:
{
"field": "annual_budget",
"operator": "gt",
"value": ["1000000"] // ✅ 字符串数组
}
Mnemonic: The value of the filter condition is always an array of strings
Pitfall 3: Using the wrong operator for linked fields
Problem: Using the wrong operator to filter linked fields
Incorrect example:
{
"field": "related_customer",
"operator": "eq", // ❌ 关联字段不支持 eq
"value": ["customer-id"]
}
Correct approach:
{
"field": "related_customer",
"operator": "belongsto", // ✅ 使用 belongsto
"value": ["customer-id"]
}
Pitfall 4: N+1 query problem for linked fields
Problem: Querying linked data one by one on the list page
Incorrect example:
// ❌ 性能灾难:100个产品 = 1 + 100 = 101次请求
const products = await getProductList(); // 1次请求
for (const product of products) {
const categoryId = product.category[0].sid;
const category = await getCategoryById(categoryId); // 100次请求!
}
Correct approach: Batch query
// ✅ 性能优化:100个产品 = 1 + 1 = 2次请求
const products = await getProductList(); // 1次请求
// 收集所有分类ID
const categoryIds = new Set();
products.forEach(p => {
if (p.category && p.category.length > 0) {
categoryIds.add(p.category[0].sid);
}
});
// 批量查询所有分类
const categories = await getRows('category-worksheet-id', {
filter: {
type: 'condition',
field: 'rowid',
operator: 'in',
value: Array.from(categoryIds)
}
}); // 1次请求
// 建立映射
const categoryMap = {};
categories.rows.forEach(cat => {
categoryMap[cat.rowid] = cat;
});
Detailed description: Refer to references/hap-api-usage-guide.md Section 7
Performance optimization recommendations
1. Query optimization
- Use pagination appropriately: pageSize should not exceed 1000
- Specify returned fields: use the fields parameter to return only the fields you need
- Use field IDs: better query performance than aliases
- Avoid excessive nesting: keep Filter nesting within 2 levels
- Make good use of views: for complex filters, create a view first, then query the view
2. Batch operation optimization
- Batch create: at most 100 records at a time
- Batch update: at most 100 records at a time
- Including linked fields: reduce to 30-50 records per batch
- Including attachments: recommend handling separately, do not batch
- Delay between batches: 1-2 seconds between batches
3. Related Field Optimization
- Reduce Nested Queries: Use the get_record_relations API to fetch at once
- Batch Query: Avoid the N+1 query problem
- Cache Related Data: Frequently accessed related data can be cached
- Control showFields: Only display necessary fields to reduce data volume
Detailed Description: Reference references/hap-api-usage-guide.md Section 8
🤖 AI Assistant Usage Guide
When the user needs to call the HAP V3 API, the AI assistant should follow these principles:
1. Automatically Extract Authentication Keys
Priority order:
-
Prefer extracting from MCP configuration(Recommended)
- Read the Cursor global settings file
- Find
hap-mcp-*configuration - Extract from the URL
HAP-AppkeyandHAP-Sign - If multiple configurations are found, ask the user which application to use
-
User provides manually
- If no MCP configuration is found, prompt the user to provide the Appkey and Sign
- Or guide the user to configure MCP first
-
Guide MCP configuration
- If the user has MCP configuration information, help the user configure it in Cursor
- Then extract the keys from the configuration
2. Configure Request Headers
After extracting the keys, automatically configure the request headers:
const headers = {
'Content-Type': 'application/json',
'HAP-Appkey': extractedAppkey, // 从 MCP 配置提取
'HAP-Sign': extractedSign // 从 MCP 配置提取
};
3. Handle Multiple Applications
If the user has configured multiple HAP MCPs:
- Explicitly specify the application name: If the user mentions a specific application name, use the corresponding configuration
- Ask the user: If not specified, list all configured applications and let the user choose
- Use by default: If there is only one configuration, use it directly
4. Error Handling
- Configuration does not exist: Prompt the user to configure MCP first or provide the keys manually
- URL parsing failed: Check whether the URL format is correct
- Missing parameters: Check whether both the Appkey and Sign are present
- Permission issue: If the configuration file cannot be read, prompt the user to check file permissions
5. Practical Operation Example
Scenario: The user says "Help me call the HAP API to query data"
AI Operation Process:
- Read the Cursor global settings file
~/Library/Application Support/Cursor/User/settings.json - Find
mcpServersinhap-mcp-*configuration - If a configuration is found, extract the Appkey and Sign from the URL
- If multiple configurations are found, ask the user which application to use
- Configure the API request headers using the extracted keys
- Execute the API call
Scenario: The user provided MCP configuration information
AI Operation Process:
- First help the user add the MCP configuration to the Cursor global settings file
- Then extract the Appkey and Sign from the configuration
- Use the extracted keys for subsequent API calls
Best Practices
1. Initialization Phase
Must-do items:
- Query all worksheet structures
- Cache the key-value mappings of all option fields
- Cache worksheet IDs and field IDs
- Build a user name → ID mapping
Example code:
// 1. 获取工作表结构
const structure = await getWorksheetStructure(worksheetId);
// 2. 提取选项字段映射
const optionMaps = {};
structure.fields.forEach(field => {
if (field.type === 'SingleSelect' || field.type === 'MultipleSelect') {
optionMaps[field.id] = {};
field.options.forEach(opt => {
optionMaps[field.id][opt.value] = opt.key; // value → key
});
}
});
// 3. 使用时查找key
const customerTypeKey = optionMaps['customer_type']['成交客户'];
2. Query phase
Recommendations:
- Prefer field IDs over aliases
- Option fields must use keys; convert them in advance
- For numeric fields, value uses a string
- For relation fields, use the belongsto operator
- Set pageSize appropriately (100-500 recommended)
3. Write phase
Checklist:
- The value of an option field is in array format
- Option fields pass the key, not the value
- Numeric fields pass the numeric type
- Relation fields pass the rowid
- Member fields pass the accountId
- Attachment fields have the type parameter set
4. Error handling
Common error codes:
error_code: 1- Successerror_code: -1- Failure; check error_msgerror_code: 4- Insufficient permissionserror_code: 10- Parameter error
Recommendations: All API calls must check error_code and success
Detailed description: Reference references/hap-api-usage-guide.md Section 9
Common API endpoint quick reference
| Scenario | API endpoint | Key parameters |
|---|---|---|
| Create worksheet | POST /v3/app/worksheets |
fields |
| Add field | POST /v3/app/worksheets/{id} |
addFields |
| Create record | POST /v3/app/worksheets/{id}/rows |
fields |
| Batch create | POST /v3/app/worksheets/{id}/rows/batch |
rows |
| Query records | POST /v3/app/worksheets/{id}/rows/list |
filter, sorts |
| Update record | POST /v3/app/worksheets/{id}/rows/{row_id} |
fields |
| Batch update | PUT /v3/app/worksheets/{id}/rows/batch |
rowIds, fields |
| Delete record | DELETE /v3/app/worksheets/{id}/rows/{row_id} |
permanent |
| Batch delete | DELETE /v3/app/worksheets/{id}/rows/batch |
rowIds, permanent |
| Pivot analysis | POST /v3/app/worksheets/{id}/rows/pivot |
rows, values |
| Find user | POST /v3/users/lookup |
name |
| Find department | POST /v3/departments/lookup |
name |
| Get region | POST /v3/regions |
search, id |
Reference resources
Core documentation
references/hap-api-usage-guide.md- Complete guide to HAP V3 API usage specifications- Quick start - API usage flow
- Worksheet creation specifications
- Field type parameter details
- Create/update record specifications (triggerWorkflow details)
- Query filter specifications (Filter object structure, operator list)
- Pivot analysis specifications
- Complete guide to relation fields
- Common pitfalls and solutions
- Performance optimization recommendations
- Best practices summary
Online documentation
Related skills
- HAP frontend and backend project setup guide - Build a standalone website using HAP as a database
- HAP MCP usage guide - Learn how to use HAP MCP for application management
- HAP view plugin development guide - Develop HAP custom view plugins
Key concepts quick reference
Field types (type):
- Basic:
Text,Number,Date,Time - Selection:
SingleSelect,MultipleSelect - Relation:
Relation,Collaborator,Department - Other:
Attachment,Rating
Filter operators (operator):
- Comparison:
eq,ne,gt,gte,lt,lte - Text:
contains,startswith,endswith - Range:
between,in - Relation:
belongsto - Empty value:
isempty,isnotempty
subType parameter:
- Collaborator:
0=single select,1=multiple select - Relation:
1=single record,2=multiple records - Time:
1=hour:minute,6=hour:minute:second - Date:
3=year-month-day,6=year-month-day hour-minute-second
Troubleshooting checklist
Filter returns no results:
- Did the option field use key instead of value?
- Did the numeric field value use a string?
- Did the relation field use belongsto?
- Is the Filter nesting more than 2 levels deep?
- Is the field ID correct?
Create/update failed:
- Were all required fields provided?
- Does the relation field's dataSource exist?
- Is the option field's key valid?
- Is the member field's accountId valid?
- Is the numeric field out of range?
Data anomaly:
- Did you wait 5-10 seconds for the attachment?
- Is the date precision subType correct?
- Has the related record been deleted?
Skill version: v2.0
Last updated: 2026-01-11
Based on: HAP API V3
Detailed specification: Reference references/hap-api-usage-guide.md