manage_bitable_field
Manage fields (columns) in Bitable tables. Supports listing, creating, updating, and deleting fields with various types.
Instructions
[Official API] Manage fields (columns) inside a Bitable table. action=list, create, update (Feishu requires type even when only renaming), delete.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Operation to perform | |
| app_token | Yes | Bitable app token. Accepts native token, wiki node, or Feishu URL. | |
| table_id | Yes | Table ID | |
| field_id | No | Field ID — required for update/delete. | |
| field_name | No | Field display name — required for create, optional for update. | |
| type | No | Field type (1=Text, 2=Number, 3=SingleSelect, 4=MultiSelect, 5=DateTime, 7=Checkbox, 11=User, 13=Phone, 15=URL, 17=Attachment, 18=Link, 20=Formula, 21=DuplexLink, 22=Location, 23=GroupChat, 1001=CreateTime, 1002=ModifiedTime, 1003=Creator, 1004=Modifier). Required for create AND update — Feishu API rejects update without it. | |
| property | No | Field-type-specific properties (optional). E.g. SingleSelect: {options:[{name:"A"},{name:"B"}]}. |
Implementation Reference
- src/tools/bitable.js:173-201 (handler)The main handler function for the manage_bitable_field tool. Dispatches on action (list, create, update, delete) and calls the corresponding client methods on the official client.
async manage_bitable_field(args, ctx) { const c = ctx.getOfficialClient(); const appToken = await ctx.resolveDocId(args.app_token); switch (args.action) { case 'list': return json(await c.listBitableFields(appToken, args.table_id)); case 'create': { need(args.field_name, 'field_name', 'create'); need(args.type, 'type', 'create'); const config = { field_name: args.field_name, type: args.type }; if (args.property) config.property = args.property; return json(await c.createBitableField(appToken, args.table_id, config)); } case 'update': { need(args.field_id, 'field_id', 'update'); need(args.type, 'type', 'update'); const config = {}; if (args.field_name) config.field_name = args.field_name; if (args.type) config.type = args.type; if (args.property) config.property = args.property; return json(await c.updateBitableField(appToken, args.table_id, args.field_id, config)); } case 'delete': { need(args.field_id, 'field_id', 'delete'); const r = await c.deleteBitableField(appToken, args.table_id, args.field_id); return text(r.deleted ? `Field ${r.fieldId} deleted` : `Field deletion returned deleted=${r.deleted}`); } } }, - src/tools/bitable.js:54-68 (schema)The input schema definition for the manage_bitable_field tool. Defines parameters: action (enum: list/create/update/delete), app_token, table_id, field_id, field_name, type, property.
name: 'manage_bitable_field', description: '[Official API] Manage fields (columns) inside a Bitable table. action=list, create, update (Feishu requires `type` even when only renaming), delete.', inputSchema: { type: 'object', properties: { action: { type: 'string', enum: ['list', 'create', 'update', 'delete'], description: 'Operation to perform' }, app_token: { type: 'string', description: 'Bitable app token. Accepts native token, wiki node, or Feishu URL.' }, table_id: { type: 'string', description: 'Table ID' }, field_id: { type: 'string', description: 'Field ID — required for update/delete.' }, field_name: { type: 'string', description: 'Field display name — required for create, optional for update.' }, type: { type: 'number', description: `Field type (${FIELD_TYPE_NOTE}). Required for create AND update — Feishu API rejects update without it.` }, property: { type: 'object', description: 'Field-type-specific properties (optional). E.g. SingleSelect: {options:[{name:"A"},{name:"B"}]}.' }, }, required: ['action', 'app_token', 'table_id'], }, - src/server.js:37-57 (registration)The tool module is loaded via require('./tools/bitable') and its schemas/handlers are aggregated into the global TOOLS and HANDLERS maps used by the MCP server.
const TOOL_MODULES = [ require('./tools/bitable'), require('./tools/calendar'), require('./tools/contacts'), require('./tools/diagnostics'), require('./tools/docs'), require('./tools/drive'), require('./tools/events'), require('./tools/groups'), require('./tools/im-read'), require('./tools/messaging-bot'), require('./tools/messaging-user'), require('./tools/okr'), require('./tools/profile'), require('./tools/tasks'), require('./tools/uploads'), require('./tools/wiki'), ]; const TOOLS = TOOL_MODULES.flatMap((m) => m.schemas); const HANDLERS = Object.fromEntries(TOOL_MODULES.flatMap((m) => Object.entries(m.handlers))); - Client-side helper methods (listBitableFields, createBitableField, updateBitableField, deleteBitableField) that the manage_bitable_field handler delegates to for actual API calls.
async listBitableFields(appToken, tableId) { const res = await this._asUserOrApp({ uatPath: `/open-apis/bitable/v1/apps/${appToken}/tables/${tableId}/fields`, sdkFn: () => this.client.bitable.appTableField.list({ path: { app_token: appToken, table_id: tableId } }), label: 'listFields', }); return { items: res.data.items || [] }; }, async createBitableField(appToken, tableId, fieldConfig) { const res = await this._asUserOrApp({ uatPath: `/open-apis/bitable/v1/apps/${appToken}/tables/${tableId}/fields`, method: 'POST', body: fieldConfig, sdkFn: () => this.client.bitable.appTableField.create({ path: { app_token: appToken, table_id: tableId }, data: fieldConfig }), label: 'createField', }); return { field: res.data.field, fallbackWarning: res._fallbackWarning || null }; }, async updateBitableField(appToken, tableId, fieldId, fieldConfig) { const res = await this._asUserOrApp({ uatPath: `/open-apis/bitable/v1/apps/${appToken}/tables/${tableId}/fields/${fieldId}`, method: 'PUT', body: fieldConfig, sdkFn: () => this.client.bitable.appTableField.update({ path: { app_token: appToken, table_id: tableId, field_id: fieldId }, data: fieldConfig }), label: 'updateField', }); return { field: res.data.field }; }, async deleteBitableField(appToken, tableId, fieldId) { const res = await this._asUserOrApp({ uatPath: `/open-apis/bitable/v1/apps/${appToken}/tables/${tableId}/fields/${fieldId}`, method: 'DELETE', sdkFn: () => this.client.bitable.appTableField.delete({ path: { app_token: appToken, table_id: tableId, field_id: fieldId } }), label: 'deleteField', }); return { fieldId: res.data.field_id, deleted: res.data.deleted }; }, - src/auth/profile-router.js:33-43 (helper)Read-only override registration: when action=list, the manage_bitable_field call is considered read-only for profile routing purposes.
manage_bitable_field: (a) => a?.action === 'list', manage_bitable_view: (a) => a?.action === 'list', manage_bitable_record: (a) => a?.action === 'search', }; function isReadOnlyCall(name, args) { if (READ_ONLY_PREFIXES.some(p => name.startsWith(p))) return true; const override = READ_ONLY_OVERRIDES[name]; if (override && override(args)) return true; return false; }