Build an app locally
Build a Keboola app on your own computer: with an AI agent (Claude Code, Claude Desktop, Cursor, VS Code or the ChatGPT app) from one prompt, or by hand with kbagent or your own Git repository.
Build an app on your own computer when you want your own editor, your own agent or your own Git workflow. Keboola still hosts and runs the app: it clones the repository, installs dependencies, starts the app and serves it behind a secure URL. You don’t manage servers, ports or Docker, only your code and a small configuration folder.
There are two ways to do it:
- With an AI agent: an agent on your computer reads your data, writes the code, creates the app and deploys it from one prompt.
- By hand: you write the code and create the app yourself, from a terminal with kbagent or from the Keboola UI with your own repository.
To build inside Keboola instead, Kai does the same from the Create App screen, with a live preview. For what the Python/JS stack can do (frameworks, full-stack, APIs for agents), see What are Keboola apps.
Before you start
Section titled “Before you start”- A Keboola project. No project yet? Create a free one.
- A table in Storage with the data you want the app to show. No data yet? Download the sample opportunity.csv and load it as in Manual Data Loading, which takes a few minutes and gives you the table
in.c-csv-import.opportunity; Describe the app has a prompt for it. For your own data, use a data source connector. - Git, which pushes the app’s code.
- For the agent and the terminal: kbagent, connected to that project. Connecting asks for your stack URL, the part of your project’s address before
/admin; for a free project from the link above, it’shttps://connection.us-east4.gcp.keboola.com. Creating the push token for the app’s repository needs admin rights in the project. - For the agent: Claude Code, Claude Desktop, Cursor, VS Code or the ChatGPT app. Using another agent? See Other agents.
- For building by hand: your local development tools, and for your own repository a Git account where you host it.
With an AI agent
Section titled “With an AI agent”With the dataapp-developer plugin from Keboola’s AI Kit, the agent reads your data, writes the code, creates the app with a Git repository that Keboola manages, pushes the code there and deploys it. You end up with a running app at its own URL, and the code in a repository you can keep changing.
Set up your client
Section titled “Set up your client”-
Add the AI Kit marketplace and the
kbagentplugin, then run/kbagent:setupwith your stack URL, which installs kbagent and signs you in. kbagent with AI agents has the commands. -
Add the app-building plugin from the same marketplace:
/plugin install dataapp-developer@keboola-claude-kit -
Paste the prompt from Describe the app. Approve the commands it asks to run, unless you’ve allowed them.
The plugin gives the agent a skill with Keboola’s app layout, Storage access and deployment rules, plus app templates.
- Connect Keboola’s MCP server for your stack, as in Using with Claude Desktop.
- Open Customise → Plugins → Add → Add from marketplace, paste
keboola/ai-kit, and adddataapp-developer. The same route installs thekbagentplugin; see kbagent with AI agents. - Start a new chat and paste the prompt from Describe the app, with its first sentence changed to “Build a Keboola app through the Keboola MCP server.” The skill prefers the MCP route in Claude Desktop, described in The MCP route; if it also finds kbagent, it asks which one to use. Without a way to push to Git, it builds a Streamlit app instead.
- Install kbagent and connect your project in a terminal, as in First, in a terminal.
- Add the AI Kit marketplace as in Cursor, with the full URL
https://github.com/keboola/ai-kit. Under Keboola Ai Kit, add bothkbagentanddataapp-developer. - Paste the prompt from Describe the app into Cursor’s chat. Approve the terminal commands it asks to run.
If Cursor offers to sign you in to a keboola MCP server, decline to stay on kbagent. The plugin’s own server points at the US GCP stack (us-east4), so signing in to it can send the agent to a project there.
VS Code runs the agent through GitHub Copilot, so you need the Copilot extension with agent mode.
- Install kbagent and connect your project in a terminal, as in First, in a terminal.
- Install the plugins from source as in VS Code: run Chat: Install Plugin from Source, paste
https://github.com/keboola/ai-kit, confirm the Trust prompt, and pickkbagent. Do the same fordataapp-developer. - Open the Chat view (
⌃⌘I, orCtrl+Alt+Ion Windows), switch to agent mode, and paste the prompt from Describe the app. Approve the terminal commands it asks to run.
-
Install kbagent and connect your project in a terminal, as in First, in a terminal.
-
Turn on Developer mode and add the marketplace as in ChatGPT app, then install
kbagentanddataapp-developerfrom the Personal tab. From a shell, that’s:Terminal window codex plugin marketplace add https://github.com/keboola/ai-kitcodex plugin add kbagent@keboola-claude-kitcodex plugin add dataapp-developer@keboola-claude-kit -
Start a new chat and paste the prompt from Describe the app. Approve the commands it asks to run.
Describe the app
Section titled “Describe the app”Say what the app shows, which data it uses and where the code goes, and ask for a new, deployed app. Without the word new, the skill prefers changing an app that already exists. For example:
Build a Keboola app using kbagent, not an MCP server, in the project kbagentis connected to. It shows the number of orders per day as a line chart, fromthe orders table. Put the code in a new Keboola-managed Git repository, deploythe app, check that it loads its data, and give me its URL and its page inKeboola (<Keboola URL>/admin/projects/<project-id>/data-apps/<config-id>).Swap the orders table and the chart for your own data and keep the rest as it is; the agent fills in the page link itself. If kbagent knows more than one project, replace “the project kbagent is connected to” with the project’s alias, from the Alias column of kbagent project list. With the sample data from Before you start, use this one:
Build a Keboola app using kbagent, not an MCP server, in the project kbagentis connected to. It shows the number of opportunities created per month as aline chart, from the in.c-csv-import.opportunity table (CreatedDate column).Put the code in a new Keboola-managed Git repository, deploy the app, checkthat it loads its data, and give me its URL and its page in Keboola(<Keboola URL>/admin/projects/<project-id>/data-apps/<config-id>).The agent reads the skill, finds the table and queries a sample before it writes any code. Name a framework too if it matters to you. To use your own GitHub repository instead, put its URL in the prompt; the repository then has to follow the layout in the skill’s reference.
If the agent can reach Keboola more than one way, it may ask which to use, or offer to sign you in to an MCP server. Outside Claude Desktop, pick kbagent to follow this page and decline that sign-in. An MCP sign-in can reach other projects, and the agent may build wherever it finds the data first; that’s why the prompt names both kbagent and the project. The plugin’s own MCP server is fixed to the US GCP stack (us-east4): Claude Code can’t connect to it, Cursor offers a sign-in, and the ChatGPT app’s Codex engine reports that it needs one. The MCP route describes the other way in.
The MCP route
Section titled “The MCP route”Through a Keboola MCP server, the agent doesn’t run kbagent. It calls the server’s app tools instead, such as modify_python_js_data_app, create_python_js_data_app_git_credential and deploy_data_app. To take this route on purpose, connect the MCP server for your stack: Claude Desktop, Cursor, VS Code, ChatGPT.
- It creates the app with a Keboola-managed repository, and a draft of it next to the production app.
- The draft runs in development mode at its own URL, so you preview the app before anything goes live. If the repository has a
keboola-config/supervisord-dev/program, the draft reloads each push within seconds; otherwise the agent redeploys it. A draft can’t be public, even if you asked for a public app. - The production app stays undeployed until you approve the draft. Then the agent merges the draft into production and deploys it.
- The repository block is in the configuration from the start, so the workspace bug doesn’t apply.
Check the app
Section titled “Check the app”- The agent finishes with the app’s URL and its page in Keboola.
- The app asks for its password, which is on that page next to Open App.
- To let other people open it, see Publish and share.
- If the app opens without data, ask the agent to read the app’s log. Troubleshooting lists the common causes, including
Promise.withResolvers is not a functionfrom a too-new@keboola/api-client.
What you get by default
Section titled “What you get by default”Unless the prompt says otherwise, a dashboard comes out as a Python/JS app built with Node.js and Chart.js, with its code in a new Keboola-managed Git repository. The app runs at the XSmall size, sleeps after 15 minutes without visitors, gets access to your Storage data and sits behind a shared password. On the kbagent route, the app can read Storage only once the repository block is added; see If the app can’t read Storage.
The agent usually can’t show you that password, because kbagent data-app password needs a Manage API token. To find the app’s page, open Apps from the left navigation and then your app. The example prompt in Describe the app asks the agent for a direct link to that page.
To make the app public, say so in the prompt. Anyone with its URL can then open it and see the data it shows. Changing an existing app’s sign-in, including to single sign-on, belongs in its Authentication settings.
Other agents
Section titled “Other agents”Any agent that can run shell commands can follow From a terminal. For the push, it has to hand Git the token without a prompt, because an agent’s shell can’t answer one, and keep the token out of the push URL, where it would end up in the shell history. Many agents also start a new shell for each command, so a variable exported in one command is gone by the next. One command handles all of that: it creates the push token from step 3, reads the secret from kbagent’s JSON output with jq, and pushes through a one-off credential helper, so the secret never appears in a command or its output:
GIT_PUSH_TOKEN="$(kbagent --json data-app git-credentials-create --project <alias> --app-id <id> \ --type http_token --permissions readWrite --yes | jq -r .data.credential.secret)" \git -c credential.helper= \ -c credential.helper='!f() { echo username=kbagent; echo "password=$GIT_PUSH_TOKEN"; }; f' \ push <https-url> HEAD:mainIt needs jq, and each run creates a new token, so use it in place of the git-credentials-create command in step 3. If the push fails with Authentication failed, run the kbagent part on its own to see its error, such as a 403 when kbagent’s token lacks admin rights.
Have it load kbagent’s full command reference with kbagent context first (the context reference). If the agent can’t install plugins, give it the skill as files: the folder is on GitHub, with the app templates and reference guides the skill points to.
The skill as a download
Section titled “The skill as a download”To add the skill to an agent by hand, download it below. The download is a copy of the skill folder: the skill itself, ready-made app templates (Python, Node.js, full-stack, Streamlit), and reference guides your agent can draw on. The current folder is on GitHub. When you create a Python/JS app in the UI, Keboola offers the skill too, Download Skill or View on GitHub, and the app’s Overview links it as AI Skill for Building.
⬇ Download the app-building skill (with templates)
By hand
Section titled “By hand”Write the code yourself, then create the app from a terminal with kbagent, which gives it a Keboola-managed repository, or, in the Keboola UI, connect a repository you host.
App structure
Section titled “App structure”A Keboola app is a standard web app. The typical scaffold is:
src/App.tsxfor the frontend (React).server/index.tsfor server-side API routes (Express).
All data-fetching logic, meaning SQL queries and anything that uses your Storage token, belongs in the server-side routes.
// server/index.ts — example route (illustrative)app.get("/api/rows", async (req, res) => { // Use the Keboola Storage client here, server-side only. // Never expose your Storage token to the browser.});The repository also needs a small keboola-config/ folder that tells Keboola how to start the app. The skill’s reference spells it out.
From a terminal
Section titled “From a terminal”kbagent creates the app with a Keboola-managed repository, and you push your code there.
-
Install kbagent and connect your project. Then
kbagent project listshows three values you need: your project’s name in kbagent (Alias,<alias>below), its Project ID (<project-id>) and its Stack URL (<Keboola URL>). -
Create the app. It prints the App ID (
<id>below) and the Config ID (<config-id>), and doesn’t deploy yet, because the new repository is empty:Terminal window kbagent data-app create --project <alias> --name "Orders per day" --slug orders-per-day --use-managed-git-repo -
Get the repository’s HTTPS URL (
<https-url>) and a push token. The token is a one-time secret, so save it now. An agent runs only the first of these commands and then pushes with the one in Other agents, which creates the token without printing it.Terminal window kbagent data-app git-repo --project <alias> --app-id <id>kbagent data-app git-credentials-create --project <alias> --app-id <id> --type http_token --permissions readWrite --yes -
Commit your code and push it to
main. Clearing Git’s credential helper for this push makes Git ask for the token instead of sending a stored login, which fails withRepository not found. When it asks, use any username and the token as the password.Terminal window git -c credential.helper= push <https-url> HEAD:main -
Until keboola/cli#765 ships, add the repository block to the app’s configuration, or the app gets no Storage access (why):
Terminal window kbagent config update --project <alias> --component-id keboola.data-apps --config-id <config-id> --merge --configuration '{"parameters":{"dataApp":{"git":{"repository":"<https-url>","branch":"main","private":true}}}}' -
Deploy, then print the app’s URL:
Terminal window kbagent data-app deploy --project <alias> --app-id <id> --waitkbagent data-app detail --project <alias> --app-id <id>
The password is on the app’s page, <Keboola URL>/admin/projects/<project-id>/data-apps/<config-id>, next to Open App. With a Manage API token, kbagent data-app password --project <alias> --app-id <id> prints it too. If the app opens without data, kbagent data-app logs --project <alias> --app-id <id> shows its log; if it doesn’t start at all, kbagent data-app runs --project <alias> --app-id <id> shows why.
Sync to your project
Section titled “Sync to your project”To run the app from a Git repository you host, develop locally, push, and connect the repository in the UI:
- In your project, create a Python/JS app (Apps → + Create App → Python / JS).
- On the app’s configuration page, open Git Repository and set the Project URL. For a private repo, toggle Private and add your credentials.
- Pick the branch (Load Branches).
- Click Deploy App. Keboola clones the repo, installs dependencies, and runs it. Push changes and Redeploy to ship them.

How development works
Section titled “How development works”The day-to-day loop, whichever way you build:
- Code lives in a Git repository: yours, or a private Keboola-managed repository that Kai, kbagent or an MCP server creates for the app, such as
https://git.europe-west3.gcp.keboola.com/keboola/app-<id>.gitwith the App ID as<id>(kbagent data-app git-repoprints the exact URL). - Data access happens server-side. Your backend queries Storage (Storage API or real-time SQL via the Query Service) using the auto-injected
KBC_TOKEN, so the browser never sees the token. Environment variables and code patterns are in Reference → Data access. - Ship a change: push to the connected branch and redeploy. If Kai built the app, just tell Kai what to change; if an agent built it, ask the agent.
- Debug on the app detail: the app’s page has Overview / Advanced Settings / All Runs / Terminal Logs / Versions tabs (a Drafts tab appears while a draft exists). Env variables, theme, and data mappings live under Advanced Settings. The app sleeps when idle and wakes on the next visit; drafts hot-reload as Kai edits.
Access your data
Section titled “Access your data”Apps read Keboola data through Input Mapping, the Storage API, or Storage Access (real-time SQL via the Query Service). See Reference → Data access for environment variables, code patterns, and Storage Access setup.
If the app can’t read Storage
Section titled “If the app can’t read Storage”Until keboola/cli#765 ships (still the case in kbagent 0.95.0), an app created with --use-managed-git-repo gets no workspace, however often you redeploy it with kbagent. It runs, but its code finds no WORKSPACE_ID. An app built from the plugin’s Node.js template logs Missing env vars: WORKSPACE_ID (or KBC_WORKSPACE_MANIFEST_PATH). Checking runtime.workspace.enabled in the configuration doesn’t catch it, because that flag is already on.
The app’s configuration is missing its repository block. The prompt above asks the agent to check that the app loads its data, so it should notice and add the block; kbagent’s rules make it ask you to confirm that change first. If it doesn’t notice, ask it to. By hand, it’s step 5 of From a terminal, followed by another kbagent data-app deploy. If you no longer have the config ID from create, kbagent --json data-app detail --project <alias> --app-id <id> shows it as config_id. After the fix ships, deploy adds the block itself.
If the app still reads no data, or you didn’t create it with kbagent, Storage Access may be off for the app or the project. Troubleshooting has the fix.
Change the app later
Section titled “Change the app later”If an agent built the app, ask it for the change. It pushes to the same repository and deploys again, and the app restarts on each deploy. To edit the code in a Keboola-managed repository yourself, clone it from kbagent data-app git-repo with a fresh token from git-credentials-create, clearing Git’s credential helper as in steps 3 and 4 of From a terminal: git -c credential.helper= clone <https-url>. With your own repository, push to the connected branch and Redeploy, as in Sync to your project.
Stopping and waking the app, secrets, settings and deleting are in Operate and update an app. kbagent’s data-app commands don’t cover drafts or copying an app, and kbagent data-app deploy --config-version runs an older configuration for one deploy without restoring it. Drafts, copying and a real rollback happen in the Keboola UI.
Next: Authentication →