Used towrite cloud function source code that runs on the Bmob server, and when MCP is configured, use deploy_cloud_function → invoke_cloud_function to complete upload and verification, or use list_cloud_functions → get_cloud_function to sync online functions to local.
First determine which channel to use
- Bmob MCP configured: prefer using
bmob-mcp- Upload source code:
deploy_cloud_function - Verify separately:
invoke_cloud_function - Sync online → local:
list_cloud_functions→get_cloud_function(agent writes local files)
- Upload source code:
- MCP not configured: follow the Cloud Function documentation and REST
/1/functions/<name>/ console workflow to provide code and curl
Syntax baseline
By default, write in the Web/Node style of the Bmob Cloud Function documentation:
function onRequest(request, response, modules) {
response.send("hello");
}
- GET direct parameters:
request.query.xxx - POST / REST parameters:
request.body.xxx - Return result:
response.send(...) - Database / file / HTTP / encryption: from
modulesgetoData、oFile、oHttp、oCrypto, etc.
Known behaviors that must be followed
- When called via the REST API, parameters are taken from
request.body, notrequest.query - In cloud functions, many callbacks return astring, requiring
JSON.parse(data)before using it as an object - Known behavior: the server may convert the passed-in
request.bodyvalue into a string; when numbers, booleans, arrays, or objects are involved, explicitlyparseInt/=== "true"/JSON.parse modules.oData'swhereis a JSON object, do notJSON.stringify:- ✅ Inside cloud functions:
db.find({ "table": "Level", "where": { "status": 1 } }) - ❌ Wrong:
"where": JSON.stringify(where)— this turns the condition into a string, causing queries to fail or behave abnormally - Only REST GET query parameters
whererequire a URL-encoded JSON string (seebmob-database-restful);Do notapply the REST style insideoData
- ✅ Inside cloud functions:
Default workflow
1. Write source code
- The function name must match the name the user wants to call
- Prefer writing a minimal verifiable version first, then expand gradually
- If you need to query / modify tables, first confirm the table name and field names; if the user has MCP configured, first read
get_project_tables
2. Upload source code
When MCP is configured, prefer calling:
deploy_cloud_functionfuncName: cloud function namecode: source code textlanguage:1=javascript,2=javaverify: pass when immediate verification is needed1verify_data: verification input JSON string, default{}
3. Verify result
- If the upload tool has set
verify=1, directly check the returnedverify.response - If verification is needed multiple times, call separately
invoke_cloud_function - When verification fails, first compare theupload result、execution return、passed-in parameterstogether
4. After successful deployment: tell the user how to call it
deploy_cloud_function When successful, the response will include invokeGuide. When explaining the calling method to the user:
- Do notwrite only a bare URL (such as
POST https://api.codenow.cn/1/functions/xxx) — REST must include complete headers and body - PreferUse
invokeGuide.rest.curl(already includesX-Bmob-Application-Id、X-Bmob-REST-API-Key、Content-Typeand the example body) - Based on the current project typeshow only one best-matching SDK example (selected from
invokeGuide.sdk):- Read the codebase to determine:
package.json/ Vue / React →javascript;app.json/ Mini Program →wechat_miniprogram;build.gradle/ Android SDK →android;Podfile/ ObjC →ios;BmobCloud.run/ SwiftPM →swift;pubspec.yaml/bmob_plugin→flutter; no SDK or user wants curl →restful - When unsure: REST curl + note "if your project is on the XX platform, refer to invokeGuide.sdk.XX"
- Read the codebase to determine:
- Need a more detailed curl boilerplate: you can call
generate_code→type=调用云函数 - After showing the invocation examples, proactively ask the user whether they want to try a test run(when MCP is configured):
- Example wording: "The cloud function has been deployed. Above are the REST / SDK invocation methods.Would you like me to help you do a test run with simulated parameters via MCP?」
- User agrees → based on the
request.bodyfields in the cloud function source code,infer or confirm with the userthe test parameters - Call
invoke_cloud_function:funcName= function name,data= the test input parameters' JSON string(e.g.{"limit":10,"skip":0,"status":1}) - Give the execution result (success / error / response body) back to the user; on failure, troubleshoot against "upload result + execution response + passed-in parameters"
- User has not configured MCP or did not agree to a test run: only provide invocation instructions, do not execute automatically
How to construct MCP test-run parameters
- Read the cloud function source code and list the fields it reads from
request.body(e.g.limit、skip、status) - Provide a set ofreasonable default valuesand show them to the user, for example
{ "limit": 10, "skip": 0 } - The user can modify them or directly say "test with this set of parameters"
invoke_cloud_function'sdatamust be a JSON string:"{\"limit\":10,\"skip\":0}"
Sync cloud functions (online → local)
Trigger words:同步云函数、同步函数、拉取云函数、下载云函数、把线上云函数拉到本地。
When MCP is configured, execute the following process (MCP pull + agent writes to disk):
sequenceDiagram
participant U as User
participant A as Agent
participant M as Bmob MCP
participant FS as Local cloudfunctions/
U->>A: 同步云函数
A->>M: list_cloud_functions
M-->>A: {functions: ["hello", "rsync_img"]}
loop 每个函数(或用户指定的单个)
A->>M: get_cloud_function {funcName}
M-->>A: {code, suggestedFileName: "hello.js"}
A->>FS: 写入 cloudfunctions/hello.js
end
A->>U: 已同步 N 个文件到 cloudfunctions/
1. Pull the online list and source code
- Call
list_cloud_functionsto get thefunctionsarray - If the user specified a single function name (e.g. "sync hello"), you can skip list and directly
get_cloud_function - For each name, call
get_cloud_function; in the responsecodeis already plaintext,suggestedFileNameis the recommended file name (e.g.hello.js)
2. Determine the local directory
Look for an existing cloud function directory in order of priority:
cloudfunctions/bmob/cloud-functions/functions/
If none exist, create cloudfunctions/。
3. Write the file
- Path:
{目录}/{suggestedFileName}(e.g.cloudfunctions/hello.js) - Content:
get_cloud_functionreturned bycodethe original - If a file with the same name already exists locally: first tell the user it will be overwritten, or ask whether to keep the local version
4. Report the result
Tell the user: which functions were synced, the write paths, the language type (languageName)。
When MCP is not configured: provide a REST curl boilerplate (GET /1/functions and GET /1/functions/<name>), and explain that the code field needs to be base64-decoded manually.
Recommended verification method
Function with no parameters
{
"verify": 1,
"verify_data": "{}"
}
Function with parameters
Make verify_data exactly match the scenario to verify, for example:
{
"verify": 1,
"verify_data": "{\"name\":\"tom\",\"count\":1}"
}
Common patterns
Return a simple string
function onRequest(request, response, modules) {
response.send("ok");
}
Read POST parameters
function onRequest(request, response, modules) {
var name = request.body.name || "guest";
response.send("hello " + name);
}
Return the result after looking up the table
function onRequest(request, response, modules) {
var db = modules.oData;
db.find({"table":"Games"}, function(err, data) {
if (err) {
response.send(err);
return;
}
response.send(JSON.parse(data));
});
}
Conditional query + pagination (pass an object to where)
function onRequest(request, response, modules) {
var db = modules.oData;
var limit = parseInt(request.body.limit, 10) || 10;
var skip = parseInt(request.body.skip, 10) || 0;
var where = { "status": 1 };
if (request.body.status !== undefined) {
where.status = parseInt(request.body.status, 10);
}
db.find({
"table": "Level",
"limit": limit,
"skip": skip,
"order": "sortOrder",
"where": where
}, function(err, data) {
if (err) {
response.send(err);
return;
}
response.send(JSON.parse(data));
});
}
wherePass the object directly.orderThe prefix-indicates descending order (e.g."-sortOrder")。limit/skip/countis a number.
Anti-pattern
| Incorrect usage | Consequence | Correct usage |
|---|---|---|
"where": JSON.stringify(where) |
The condition becomes a string, so the query returns nothing or behaves abnormally | "where": where or inline {"status": 1} |
Putting REST's encodeURIComponent(JSON.stringify(where)) into oData |
Same as above | Cloud function oData and the REST query are two different sets of APIs |
In the cloud function callback, directly using data.xxx without parsing |
data is a string, and property access fails |
First JSON.parse(data) |
How to handle failures
- Cloud function does not exist: confirm that
funcNamematches the upload target - Validation return structure is incorrect: check whether you are using
request.bodyorrequest.query - Abnormal number/boolean checks: handle it as "the value will become a string"
- Database callback type is incorrect: first
JSON.parse(data) - Conditional query returns no results / queries the entire table:
wherewhetherJSON.stringifywas misused; an object should be passed - Still failing: go back to the minimal version, keeping only
response.send("ok")to validate the publishing pipeline
When to degrade
Do not force automatic upload in the following cases:
- The user has not configured MCP
- When a large amount of source code is needed and the tool input parameters are inconvenient to carry it
- The user explicitly only wants sample code, not a real deployment
In this case, provide the source code + REST upload instructions, and make it clear that online verification was not performed.