Skip to main content

BFF Save Feature

Backend Function (BFF) save feature is an optional switch that allows AI to create and modify Backend Function scripts through MCP tools.

Note

This feature is disabled by default and must be explicitly enabled in MCP configuration. Once enabled, AI can automatically save BFF scripts to the platform, use with caution.


Why Need a Separate Switch?

Backend Function is server-side code with certain sensitivity and risks:

  • Efficiency: AI can directly create and modify BFF scripts without manual copy-paste
  • ⚠️ Potential Risk: Incorrect BFF scripts may affect production environment
  • ⚠️ Permission Control: Not all team members should have BFF modification permissions
  • ⚠️ Audit Requirement: Need to track who (including AI) modified BFF scripts

Therefore, we designed the BFF save feature as an optional switch, allowing teams to decide whether to enable it based on actual situations.


How to Enable

Add --enable-bff-save parameter in MCP configuration:

Claude Desktop / Claude Code Configuration Example:

{
"mcpServers": {
"lovrabet-dataset": {
"command": "npx",
"args": [
"-y",
"@lovrabet/dataset-mcp-server",
"--enable-bff-save"
],
"env": {
"LOVRABET_APP_CODE": "your-app-code"
}
}
}
}

Cursor / Windsurf Configuration Example:

{
"mcpServers": {
"lovrabet-dataset": {
"command": "npx",
"args": [
"-y",
"@lovrabet/dataset-mcp-server",
"--enable-bff-save"
],
"env": {
"LOVRABET_APP_CODE": "your-app-code"
}
}
}
}

Method 2: Global Installation Startup

If you have globally installed @lovrabet/dataset-mcp-server:

{
"mcpServers": {
"lovrabet-dataset": {
"command": "lovrabet-dataset-mcp",
"args": ["--enable-bff-save"],
"env": {
"LOVRABET_APP_CODE": "your-app-code"
}
}
}
}

Method 3: Start from Source

{
"mcpServers": {
"lovrabet-dataset": {
"command": "node",
"args": [
"/path/to/lovrabet-dataset-mcp/dist/index.js",
"--enable-bff-save"
],
"env": {
"LOVRABET_APP_CODE": "your-app-code"
}
}
}
}

Deprecated Parameter

⚠️ --dangerously-bff-save (Deprecated)

The old parameter --dangerously-bff-save is deprecated, functionality is identical to --enable-bff-save.

If your configuration uses the old parameter, recommend migrating:

// ❌ Old parameter (deprecated)
"args": ["--dangerously-bff-save"]

// ✅ New parameter (recommended)
"args": ["--enable-bff-save"]

Tools Available After Enabling

After enabling --enable-bff-save, MCP will provide the following 3 additional tools:

1. list_bff_scripts - List All Backend Functions

Get all BFF scripts under the application (only ENDPOINT type).

Parameters:

{
appCode?: string; // Application code (optional, use environment variable)
cookie?: string; // Authentication cookie (optional, use stored after login)
}

Return Example:

[
{
"id": 123,
"name": "getUserInfo",
"description": "Get user detailed information",
"scriptType": "ENDPOINT",
"createTime": "2026-03-20 10:30:00",
"updateTime": "2026-03-26 14:20:00",
"createUser": "user@example.com"
}
]

Use Cases:

  • Browse existing BFF scripts
  • Find reusable backend functions
  • Confirm script ID before modification

2. get_bff_script_info - Get Script Details

Get complete information of BFF script by ID, including source code.

Parameters:

{
id: number; // BFF script ID (required)
appCode?: string; // Application code (optional)
cookie?: string; // Authentication cookie (optional)
}

Return Example:

{
"id": 123,
"name": "getUserInfo",
"description": "Get user detailed information",
"scriptContent": "export default async function(params, context) {\n const userId = params.userId;\n const user = await context.client.models.customer.getOne({ id: userId });\n return { success: true, data: user };\n}",
"scriptType": "ENDPOINT",
"createTime": "2026-03-20 10:30:00",
"updateTime": "2026-03-26 14:20:00",
"createUser": "user@example.com",
"updateUser": "user@example.com"
}

Use Cases:

  • View existing code before modification
  • Learn from other script implementations
  • Debug problem scripts

3. save_or_update_bff_script - Save or Update Backend Function

Save new BFF script or update existing script.

Parameters:

{
id?: number; // Script ID (required for update, omit for new)
description: string; // Function description (required)
scriptContent: string; // JavaScript/TypeScript code (required)
appCode?: string; // Application code (optional)
cookie?: string; // Authentication cookie (optional)
}

Return Example (Success):

{
"success": true,
"id": 124,
"message": "BFF script saved successfully"
}

Return Example (Conflict):

{
"success": false,
"blocked": true,
"message": "Last submitter is other@example.com, please operate manually"
}

Important Mechanisms:

  1. Automatic Cache Clearing: Automatically call Runtime API to clear script cache after successful save
  2. Force Validation: Force validate dataset and field references before save
  3. Conflict Detection: Detect if last submitter is current user (see below)
  4. Block Mechanism: If returns blocked: true, AI must not auto-retry

Conflict Detection Mechanism

4-Level Conflict Detection

When saving BFF script, MCP will detect conflicts through toolbox API:

LevelScenarioRiskAI Behavior
NONENew script🟢 NoneSave directly
LOWOwn script🟢 LowAllow save
HIGHOthers recently modified (less than 30 days)🔴 HighBlock, prompt user
MEDIUMOthers earlier modified (more than 30 days)🟡 MediumBlock, prompt user

Conflict Handling Flow

Save Request

├─ New → ✅ Save directly

└─ Update → Check last submitter

├─ Self → ✅ Allow save

└─ Others → Check time

├─ Less than 30 days → 🔴 blocked: true

└─ More than 30 days → 🟡 blocked: true

AI Behavior Guidelines

When returning blocked: true:

  1. Should Do:

    • Inform user of conflict
    • Prompt last submitter information
    • Suggest user operate manually or coordinate
    • Provide method to view existing code
  2. Must Not Do:

    • Auto-retry save
    • Ignore conflict warning
    • Force overwrite others' code

Example Prompt:

⚠️ Conflict detected!

**Conflict Information**:
- Script ID: 123
- Last submitter: colleague@company.com
- Modified: 2 hours ago

**Suggested Actions**:
1. Coordinate with colleague@company.com
2. Or operate manually in platform interface

I will not automatically overwrite others' code.

BFF Code Writing Guidelines

Basic Structure

export default async function(params, context) {
// 1. Parameter validation
const userId = params.userId;
if (!userId) {
return { success: false, message: "userId is required" };
}

// 2. Data access (use context.client)
const user = await context.client.models.customer.getOne({
id: userId
});

// 3. Business logic
if (!user) {
return { success: false, message: "User not found" };
}

// 4. Return result
return {
success: true,
data: user
};
}

Two Runtime Contexts

1. Frontend SDK (Frontend)

// Returns wrapper
const data = await client.sql.execute({ sqlCode: 'xxx' });
if (!data.execSuccess) {
throw new Error('SQL execution failed');
}
const results = data.execResult || [];

2. Backend Function (Backend)

// Returns array directly, no wrapper
const rows = await context.client.sql.execute({ sqlCode: 'xxx' });
// rows is T[] type, errors throw exceptions directly

Important Differences:

  • SQL Execution: BFF returns array T[] directly, SDK returns { execSuccess, execResult }
  • Error Handling: BFF errors throw exceptions, SDK returns { execSuccess: false }
  • Data Operations: Both call methods same, only return structure different

Usage Examples

Example 1: Create New BFF Script

User Request:

Create a BFF function to get user information and order count by user ID

AI Execution Steps:

  1. Generate code:
export default async function(params, context) {
const userId = params.userId;
if (!userId) {
return { success: false, message: "userId is required" };
}

// Get user information
const user = await context.client.models.customer.getOne({
id: userId
});

if (!user) {
return { success: false, message: "User not found" };
}

// Count orders
const orders = await context.client.models.order.filter({
where: { customer_id: { $eq: userId } },
select: ["id"]
});

return {
success: true,
data: {
user: user,
orderCount: orders.length
}
};
}
  1. Call save_or_update_bff_script:
{
"description": "Get user information and order count by user ID",
"scriptContent": "export default async function(params, context) { ... }"
}
  1. Return result:
{
"success": true,
"id": 125,
"message": "BFF script saved successfully"
}

Example 2: Update Existing BFF Script (No Conflict)

User Request:

Modify BFF script #123, add error handling

AI Execution Steps:

  1. Call get_bff_script_info({ id: 123 })
  2. Modify code (add try-catch)
  3. Call save_or_update_bff_script:
{
"id": 123,
"description": "Get user detailed information (with error handling)",
"scriptContent": "export default async function(params, context) { try { ... } catch (error) { return { success: false, message: error.message }; } }"
}

Example 3: Update Existing BFF Script (With Conflict)

Scenario: Last submitter is colleague, modified 2 hours ago.

AI Execution Steps:

  1. Call get_bff_script_info({ id: 123 })
  2. Modify code
  3. Call save_or_update_bff_script
  4. Returns blocked: true:
{
"success": false,
"blocked": true,
"message": "Last submitter is colleague@company.com, please operate manually"
}
  1. AI Should Inform User:
⚠️ Conflict detected!

**Conflict Information**:
- Script ID: 123
- Last submitter: colleague@company.com
- Modified: 2 hours ago

**Suggested Actions**:
1. Coordinate with colleague@company.com
2. Or operate manually in platform interface

I will not automatically overwrite others' code.

Best Practices

1. Coding Standards

  • ✅ Parameter validation at function start
  • ✅ Use context.client for data access
  • ✅ Unified return structure { success, data/message }
  • ✅ Add clear function description
  • ✅ Handle all possible errors

2. Conflict Avoidance

  • ✅ Call get_bff_script_info to view details before modification
  • ✅ Coordinate in advance for large modifications
  • ✅ Use descriptive naming and comments
  • ✅ Regularly clean up unused scripts

3. Performance Optimization

  • ✅ Use select to query only necessary fields
  • ✅ Use filter for batch operations instead of loops
  • ✅ Avoid deep nested queries
  • ✅ Reasonably use SQL queries

Security Recommendations

Production Environment

  1. Restrict Permissions: Only enable BFF save feature for those who need it
  2. Code Review: AI-generated BFF scripts should have manual review
  3. Backup Mechanism: Backup important scripts before modification
  4. Audit Logs: Regularly check BFF script modification history

Team Collaboration

  1. Coordination: Communicate before modifying others' scripts
  2. Version Control: Add version and modification records in scripts
  3. Audit Logs: Regularly view BFF script modification history
  4. Naming Conventions: Use clear naming conventions

Troubleshooting

Issue 1: BFF Tools Unavailable

Reason: --enable-bff-save parameter not enabled

Solution:

  1. Check MCP configuration file
  2. Confirm args contains --enable-bff-save
  3. Restart MCP server

Issue 2: Save Returns blocked: true

Reason: Others have recently modified this script

Solution:

  1. View returned conflict information
  2. Communicate with last submitter
  3. Operate manually in platform interface

Issue 3: Script Cache Not Cleared

Reason: Cache automatically cleared after save, but there may be delay

Solution:

  1. Wait 1-2 minutes
  2. Clear browser cache
  3. Retry request


Last Updated: 2026-03-26 Version: v1.0