Hosted Web Apps
Describe a small web tool and the agentic runtime builds it, installs it, and runs it on your own machine so you can open it in a browser.
A hosted web app is the second of the two app lanes. You describe a small web tool in plain language, and the runtime writes the project files, installs its dependencies, and runs it on your own machine so you can open it in a browser tab.
Read the boundary before you read anything else. It is narrow on purpose.
What a hosted app is, exactly
A hosted web app runs on your own machine, for you. Specifically:
- It is behind a non-default cargo feature (
hosted-apps). A stock build does not have it; the four hosted RPCs answerunimplemented. - It is served at a bare loopback address —
http://127.0.0.1:<port>/, on a port the runtime picks when it starts. There is no reverse proxy and no public address. - The generated code runs as an ordinary subprocess under the same operating-system user as the gateway. It is not a Mote, it does not go through the runtime's isolated execution path, it is not journaled, and there is no isolation boundary around it.
- So: do not run a hosted app whose generated code you have not read, and do not treat this lane as a way to give a web tool to other people.
The two lanes are different things
The runtime has two kinds of app, and they are not variations on each other. See apps for the overview.
| Scheduled app | Hosted web app | |
|---|---|---|
| What it carries | a blueprint — a graph of agent steps | a real web project file tree |
| What you get | a run that produces a result | a page you open in a browser |
| How it starts | you run it, or a schedule fires it | you press Run and the runtime brings up a dev server |
| Can it be scheduled? | yes — see scheduling | no; registering one as a schedule target is refused |
A scheduled app is scaffolded from a fixed skeleton — the same set of files every time. A hosted app is scaffolded from a dynamic manifest: a model first plans which source files this particular app needs, and then each planned file is authored. The two authoring paths do not share a shape. Do not carry an assumption from one to the other.
What you need first
Node and npm on your machine. The runtime shells out to npm to install the app's
dependencies and to run its dev server. These are a runtime dependency of a hosted app,
not a build dependency of the runtime.
node --version
npm --versionA build with the hosted-apps feature. It is off by default, and the prebuilt
release binary does not carry it — you build from a repository checkout. The console (the
built-in web interface) is also a separate feature, and building it from a checkout needs
the console assets built first.
just console-dist
cargo install --path crates/kx-cli --features console,kx-gateway/hosted-appsWithout hosted-apps, everything else still works — the hosted app just cannot be
started, and the console hides its Run control.
A running gateway. A bare kx serve refuses to start; you must state an auth
posture. On your own machine, that is the loopback dev flag.
kx serve --dev-allow-localThe console is served at http://127.0.0.1:8888 by default. --console-listen <addr:port>
moves it (loopback addresses only); --no-console turns it off.
A served model, if you want the app planned for your goal. The planning and authoring steps are model steps. Without a served model the runtime falls back to the framework template's default page — a project that installs and runs, but that is a starting page rather than the tool you described. See serving a model and local inference.
Create one
In the console, open Apps and use the New App form. The Apps page has two sections, Scheduled and Hosted; a hosted app lands in the second.
You give it a name, choose the Hosted lane, and pick a framework:
- Auto — the default. It resolves to the React template; so does any framework label the runtime does not recognise.
- React (a single-page app) — the simplest of the three. Pick this unless you have a reason not to.
- Next.js — pick this when the app needs server rendering or file-based routing.
- Svelte — the third supported template.
Then describe what the app should do. That description is the goal handed to the planner.
The handle is derived from the name you type; there is no separate handle field. A name
like Room Tone becomes the handle apps/local/room-tone, and the app's project branch
carries that same handle.
What happens when you press Run
The console's control on a hosted app card is Run. It starts the app and opens the live page in a new browser tab as soon as the dev server is actually accepting connections — you do not have to watch for the URL yourself.
Starting is a four-stage lifecycle, and the status you see is one of exactly six states. Nothing stops the app for you: once it is running it stays running until you stop it through the SDK or the gateway exits.
| State | What is happening |
|---|---|
Stopped | Not running — never started, or it was stopped. |
Materializing | The project files are being written to a working directory on disk. |
Installing | npm install is running. It is skipped when node_modules is already there. |
Starting | The dev server was spawned but is not yet accepting connections. |
Running | The dev server is accepting connections, and the loopback URL is live. |
Failed | Materializing, installing, or starting did not succeed; a short reason is attached. |
Three details worth knowing:
- Starting is idempotent. Pressing Run on an app that is already coming up or already running gives you its current status back rather than a second dev server.
- A rebuild is the explicit exception, and it is not a console button. It is a flag on
the start call —
startHostedApp(handle, { rebuild: true })— that kills the current dev server, deletes the installednode_modules, and starts over. - Stopping kills the child process. There is no Stop button in the console today; stopping is a TypeScript-SDK call. Shutting the gateway down also ends it — the dev server is a supervised child and does not outlive it.
The live URL is http://127.0.0.1:<port>/ and it is reachable only from your own machine.
If it fails, the status carries a tail of the install and dev-server output — the last 200 lines. That log is the first place to look.
What the model plans, and what it does not
The build configuration is owned by the template, not by the model. The package manifest, the bundler and TypeScript configuration, the HTML entry, and the app entry point are written by the runtime and always win over anything the model produced at those paths. That is deliberate: it means a hosted app installs and runs whatever the model wrote.
The model plans only the source tree for your goal — the main page or root component, child components each in their own file, a stylesheet the component imports, small helper or types modules, and at least one test. The planner is told to aim for a focused set, typically four to ten source files, but that is wording in the instruction handed to the model, not a bound anything enforces.
That plan is untrusted output, so it is decoded fail-closed before a single file is written: it is size-checked before parsing, decoded into fixed structures that reject unknown fields, and every path must be relative and safe. The enforced ceiling is that a manifest may declare at most 48 files. Anything outside that envelope is refused rather than partially applied.
The plan is saved with the project, so restarting a half-finished scaffold resumes it — it writes the files still missing rather than re-planning from scratch.
Reading and editing the files
The project lives in the app's branch, which carries the same handle as the app, and you can read it from the command line.
kx app list
kx app files apps/local/room-tone
kx app cat apps/local/room-tone src/App.tsxFor changing what the app does, see editing an app and files and branches.
Driving it from code
The command line can read a hosted app's files, but it has no verb that starts or stops one. Starting is a console or TypeScript-SDK action today; stopping is TypeScript-SDK only.
kx app list
kx app files apps/local/room-tone
kx app cat apps/local/room-tone src/App.tsxThe Python SDK does not expose the hosted-app lifecycle. Use the console or the TypeScript SDK to start and stop a hosted app.
# Not available in the Python SDK today.
# Hosted apps are started from the console or the TypeScript SDK.import { KxClient, app } from "@kortecx/sdk";
const kx = new KxClient("http://127.0.0.1:50151");
// One app, one branch: the project branch handle IS the app handle.
const handle = "apps/local/room-tone";
// A hosted app carries a project branch instead of a blueprint.
const saved = await app("Room Tone").hosted("vite_react", handle).save({ client: kx, handle });
// Start it. Returns immediately; the lifecycle runs in the background.
await kx.startHostedApp(saved.handle);
// Poll until the dev server is accepting connections.
let status = await kx.getHostedAppStatus(saved.handle);
while (status.state === "materializing" || status.state === "installing" || status.state === "starting") {
await new Promise((r) => setTimeout(r, 1000));
status = await kx.getHostedAppStatus(saved.handle);
}
if (status.state === "running") {
console.log(status.url); // http://127.0.0.1:<port>/
} else {
console.error(status.detail, status.recentLogs);
}
await kx.stopHostedApp(saved.handle);hosted() takes "auto", "vite_react", "next_js", or "svelte", plus the branch
handle the project files live in. On a gateway built without the hosted-apps feature,
startHostedApp throws because the RPC is unimplemented.
What a hosted app can reach
A hosted app is a web project. It does not carry tool grants, and it is not wired into the runtime's agentic capabilities by being a hosted app. If you want it to reach the runtime, it has to call in as an ordinary client through the governed request seam, under a warrant — the same path any other client takes. Until you write that, treat a hosted app as a self-contained local page.
A hosted app cannot call another app. No mechanism for that exists at any layer. What does chain is agents inside one app — a blueprint graph in the scheduled lane. See workflows.
Next
The two app lanes
How scheduled and hosted apps differ, and which one you want.
Scheduled apps
The other lane: a blueprint that runs on demand or on a schedule.
Editing an app
Changing what an app does after it exists.
Running it for real
What the runtime does and does not promise outside your own machine.
Scheduled Apps
Author an app, run it once by hand, then put it on a timetable with a cron trigger that fires it unattended in your own timezone.
Editing an App
Open an App's files and type, or describe the change in a sentence — every proposed change is shown as a before/after per file, nothing is applied until you accept, and one click rolls it back.