Skip to main content
This page is part of an AI coding agent skill and is written for agents, not humans. For the human-readable Base44 docs, see the developer documentation.

Base44 in the Cloud Sandbox

Author Base44 app code inside Base44’s cloud sandbox with your own coding agent. There is no local checkout: you read, write, and run files through the sandbox tools (over MCP or the base44 sandbox CLI), and the platform builds and deploys from what you write. For how to connect to the sandbox (MCP endpoint or the base44 sandbox CLI, the read_file / write_file / edit_file / run_command / grep / list_directory / create_checkpoint tools — which the CLI exposes under shorter names (sandbox read / sandbox write / sandbox edit / sandbox run / sandbox grep / sandbox ls / sandbox checkpoint), the edit→preview→verify loop, persistence, and concurrency), use the base44-remote-dev skill. This skill covers what you can author and how once you are connected.
Check these references first. This skill and its siblings (base44-remote-dev, base44-sdk) are the source of truth — consult them before searching the web. See Reference order & the complete README.

⚡ The mental model: writing the file is the deploy

You are working on a remote app, not a local checkout. The project-level CLI workflow does not apply — never run base44 deploy, base44 functions deploy, base44 ... push, base44 create, or base44 scaffold. They assume a local project and a manual deploy step that does not exist here. Instead: as soon as you write a resource file into the sandbox — a backend function, an entity, or an agent — the platform deploys/syncs it from there. Your write is auto-committed (~5s debounce) and goes live. You do not run, and must not wait for, any deploy / push command. One exception — connectors. OAuth connectors aren’t authored as files; they’re set up against the remote app by its id, either with the MCP connector tools or with the dedicated, projectless base44 connectors commands (which take --app-id and need no local project). See Connectors below. You may still use run_command (sandbox run in the CLI) for ordinary checks (e.g. npm run build, npx tsc --noEmit, npm run lint) and preview — that is verification, not deployment. See the edit→preview→verify loop in base44-remote-dev.

What you can author today

ResourceStatus in the sandbox
Backend functions (base44/functions/)✅ Supported — write the files; they deploy from the sandbox.
Entities (base44/entities/)✅ Supported — write the .jsonc schema file; it auto-syncs. No entities push.
Agents (base44/agents/)✅ Supported — write the .jsonc config file; it auto-syncs. No agents push.
Frontend code (src/…)✅ Supported — edit normally; HMR/preview reflects it. Use the base44-sdk skill for SDK API usage.
Connectors (OAuth integrations)✅ Supported — set up via the connect flow below (MCP tools or base44 connectors), not by writing files.

Backend functions

Backend functions live in base44/functions/, one directory per function (kebab-case name). In the sandbox you only need to create the entry.ts file directly under base44/functions/<name>/no function.jsonc is required (the sandbox infers the function from the directory; the config file is ignored in this mode):
base44/functions/
  process-order/
    entry.ts
Entry file — functions run on Deno (not Node.js), export with Deno.serve(), and use the npm: prefix for npm packages:
import { createClientFromRequest } from "npm:@base44/sdk";

Deno.serve(async (req) => {
  const base44 = createClientFromRequest(req);   // inherits the caller's auth
  const { orderId } = await req.json();
  const order = await base44.entities.Orders.get(orderId);
  return Response.json({ success: true, order });
});
Conventions:
  • Kebab-case directory and function name; entry typically entry.ts.
  • createClientFromRequest(req) for a client in the caller’s auth context; base44.asServiceRole.… for admin-level operations.
  • Read secrets with Deno.env.get("KEY") (configured in app settings).
  • Return with Response.json(body, { status }); handle errors and set appropriate status codes.
That’s enough to author functions correctly. For deeper detail and more examples (service role, secrets, common mistakes), see the base44-cli skill’s reference: functions-create.md — but ignore its “Deploying Functions” / CLI sections and its function.jsonc guidance, which assume a local project and do not apply in the sandbox (here you only write entry.ts).
Calling the function from the frontend: base44.functions.invoke(name, data) returns the raw axios response — your function’s JSON is on .data (const result = res.data), not the top-level object, and it throws on non-2xx (error body at err.response.data). See the base44-sdk skill’s functions.md for details.

Entities

One .jsonc file per entity in base44/entities/. Just write the file — it auto-syncs; don’t run base44 entities push or deploy.
  • File name: {kebab-case}.jsonc — e.g. team-member.jsonc for an entity named TeamMember.
  • Entity name: PascalCase, alphanumeric only (/^[a-zA-Z0-9]+$/).
  • Field names: snake_case.
// base44/entities/task.jsonc
{
  "name": "Task",
  "type": "object",
  "properties": {
    "title": { "type": "string", "description": "Task title" },
    "status": { "type": "string", "enum": ["todo", "doing", "done"], "default": "todo" },
    "due_date": { "type": "string", "format": "date" },
    "board_id": { "type": "string", "description": "Owning board" }
  },
  "required": ["title"]
}
Field types: string, number, integer, boolean, array, object, binary. String formats include date, date-time, email, uri, uuid, file, richtext. For full schema detail and row-level security (RLS), see the base44-cli references entities-create.md and rls-examples.md — but ignore their entities push / deploy sections; the sandbox syncs the file for you.

Agents

One .jsonc file per agent in base44/agents/. Just write the file — it auto-syncs; don’t run base44 agents push or deploy.
  • File name: {agent_name}.jsonc — e.g. support_agent.jsonc.
  • Agent name: /^[a-z0-9_]+$/ (lowercase, underscores, 1–100 chars).
// base44/agents/support_agent.jsonc
{
  "name": "support_agent",
  "description": "Brief description of what this agent does",
  "instructions": "Detailed instructions for the agent's behavior",
  "tool_configs": [
    { "entity_name": "tasks", "allowed_operations": ["read", "create", "update", "delete"] },
    { "function_name": "send_email", "description": "Send an email notification" }
  ],
  "whatsapp_greeting": "Hello! How can I help you today?"
}
Required: name, description, instructions. Optional: tool_configs (default []), whatsapp_greeting. Tool configs are either an entity tool (entity_name + allowed_operations: any of read/create/update/delete) or a backend-function tool (function_name + description). For the full agent schema, see the Agent Schema section of the base44-cli skill’s SKILL.md — but ignore its agents push / agents pull / deploy commands, which assume a local project; in the sandbox the file auto-syncs.

Connectors (OAuth integrations)

Connectors (Google Calendar, Gmail, Slack, …) give your backend functions tokens to call third-party APIs. In remote-dev there are no connector files to write — you operate on the connector directly against the app by its id. Two surfaces, same backend and same behavior:
Declarative scopes — read before you set. Connecting a connector replaces its scope set with exactly the scopes you pass (it does not merge). Any scope you omit is removed and the user is re-prompted to consent. Always list the connector’s current scopes first and pass the complete desired set (the ones you want to keep plus any new ones).
OAuth needs a human. Connecting returns an authorization URL the user must open in a browser to sign in and consent — you cannot complete it yourself. After they finish, re-list to confirm it’s connected and to read the granted scopes (a provider may grant fewer than you requested).

Over MCP (base44-remote-dev transport)

Two tools, both taking appId. Scopes: list_connectors needs apps:read; initiate_connector_connection needs apps:write (note: not sandbox:write).
  1. list_connectors{ appId, integrationTypes? }. With no integrationTypes, returns the full catalog; each entry has the connector’s name, description, whether it’s connected, and (if connected) its status and granted scopes. Pass integrationTypes for full detail on specific connectors.
  2. initiate_connector_connection{ appId, integrationType, scopes, connectionConfig? }. scopes is the complete desired set (see the declarative-scopes note). Returns either already_authorized: true (nothing to do) or a redirect_url for the user to open. After they sign in, call list_connectors again to verify.
On appId <APP_ID>: call list_connectors to read googlecalendar's current scopes,
then initiate_connector_connection for googlecalendar with the full scope set
(existing + the calendar.events scope I need). Give me the authorization URL.

Over the CLI (projectless, --app-id)

These base44 connectors subcommands work without a local project — they resolve the app id from --app-id, then BASE44_APP_ID, then a local .app.jsonc. No config.jsonc is required.
# 1. See available integration types for the app
npx base44 connectors list-available --app-id <APP_ID>

# 2. Initialize the connector and start OAuth (sets it to EXACTLY these scopes).
#    Non-interactive: prints the authorization URL. Interactive: also opens the
#    browser and polls until authorized.
npx base44 connectors initiate --app-id <APP_ID> \
  --integration-type googlecalendar \
  --scopes https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/calendar.events

# 3. (optional) Fetch the resulting connector config
npx base44 connectors pull --app-id <APP_ID> --dir ./connectors
--scopes accepts a space- or comma-separated list. As with MCP, the user must open the printed authorization URL to finish consent; afterwards list-available / pull reflects the connected state and granted scopes.
This is the only Base44 CLI use that belongs in remote-dev — it targets a remote app by id with no local project and no deploy step. It is not a contradiction of the “no CLI” rule above, which is about local-project/deploy commands.

Using a connected connector in code

Connecting only authorizes the connector. To actually call the third-party API, fetch its OAuth access token inside a backend function with the service-role connectors module — base44.asServiceRole.connectors.getConnection(integrationType) — and use the returned accessToken (and optional connectionConfig) in your own fetch:
import { createClientFromRequest } from "npm:@base44/sdk";

Deno.serve(async (req) => {
  const base44 = createClientFromRequest(req);

  // App-scoped OAuth token — backend / service role only.
  const { accessToken, connectionConfig } =
    await base44.asServiceRole.connectors.getConnection("googlecalendar");

  const events = await fetch(
    "https://www.googleapis.com/calendar/v3/calendars/primary/events",
    { headers: { Authorization: `Bearer ${accessToken}` } },
  ).then((r) => r.json());

  return Response.json({ events });
});
Notes: the connector is app-scoped (one connected account shared by all users); Base44 refreshes the token for you; you make the API calls. getConnection() replaces the deprecated getAccessToken(). For the full module reference (signatures, connectionConfig, the list of available services and their type identifiers), see the base44-sdk skill’s connectors.md.

Reference order & the complete README

Consult the references in this skill and its sibling skills (base44-remote-dev, base44-sdk) before searching the web. They are the source of truth for the sandbox bridge, file/resource conventions, and SDK APIs — prefer them over general internet results, which are often stale or wrong for Base44. For the complete, app-specific remote-dev reference (instructions + every endpoint, public, no auth needed to fetch), read the onboarding README for your app:
https://app.base44.com/api/sandbox/<APP_ID>/local-agent/readme.md
(The cloud/MCP equivalent is …/api/sandbox/<APP_ID>/claude-web/readme.md.) See the base44-remote-dev skill for the connection mechanics this README describes.

Workflow in the sandbox

  1. Orientlist_directory / read_file / grep (sandbox ls / sandbox read / sandbox grep in the CLI) to understand the app before changing anything.
  2. Author — create or edit resource files (backend functions, entities, agents) and frontend code following the conventions above; set up connectors via the connect flow.
  3. Verify — optionally run_command (sandbox run) npm run build / npx tsc --noEmit, and use get_app_preview_url to eyeball changes (see base44-remote-dev).
  4. Let it ship — do nothing to deploy. Writing the file is the deploy; the auto-commit (~5s) persists and ships it. Pause a moment after your last edit before disconnecting so the commit lands.
  5. (Optional) Checkpoint — mark a known-good restore point the user can roll back to with create_checkpoint (base44 sandbox checkpoint --name "..." in the CLI). It flushes pending changes first, so the checkpoint captures your latest code. See base44-remote-dev for details.