Authoring a Template Through the Admin MCP Toolset

Pointing kelta mcp serve at a sandbox, and the MCP tool behind each step of building a template app.

Every authoring step of the two example templates (examples/templates/crm/ and examples/templates/inspections/) mapped to the MCP tool that performs it, so an agent can build the same app in a sandbox through MCP instead of the CLI. The steps and error numbers come from each template’s BUILD-LOG.md (CRM #n, Inspections I#n).

Connecting to a sandbox#

A sandbox is its own tenant: the parent’s token is refused on it (the gateway rejects a personal access token on any tenant other than the one it was issued in). Point the stdio bridge at the sandbox with the sandbox’s own token:

kelta sandbox create -n authoring            # prints the sandbox slug and a one-time admin credential
# sign in to the sandbox (see `kelta sandbox --help`), then mint a PAT inside it:
KELTA_TENANT=<sandbox-slug> KELTA_TOKEN=<sandbox session token> kelta token create --name mcp
export SANDBOX_PAT=klt_...                   # the token printed once by `token create`
kelta mcp serve --toolset all --tenant <sandbox-slug> --token-env SANDBOX_PAT
  • --tenant replaces the profile’s tenant for every tool the server exposes: the bridged hosted tools ({mcpUrl}/{slug}/mcp/user and /mcp/admin) and the cli_ local tools (cli_metadata_export, cli_metadata_apply, cli_dashboards_validate, …).
  • --token-env names the variable holding the token, so the token is never in argv or in the client config. KELTA_TENANT / KELTA_TOKEN work too and rank below the flags.
  • --tenant without a token for that tenant is refused at start-up instead of failing every call with 401.
  • kelta mcp install <client> --toolset admin --tenant <slug> --token-env SANDBOX_PAT prints the client configuration with the same flags.
  • The hosted MCP endpoint takes personal access tokens (klt_…) only. A session token from the sandbox sign-in works for the CLI but not for the bridge, hence the token create step.
  • Create and delete sandboxes from a server (or CLI) bound to the parent: with --tenant set, cli_sandbox_* acts on the sandbox itself.

Coverage#

--toolset all bridges the user and admin toolsets; tools marked (user) are on the user toolset. cli_ tools are local to kelta mcp serve.

StepBuild-log evidenceMCP toolStatus
Collectionsboth logs: every collection created by hand in the build sandboxapply_collection (idempotent: collection, inline fields, field-scoped picklist values and display field in one call), create_collection (optionally with inline fields), update_collection, delete_collectioncovered
Fields, including native types and typed defaults#7, #8 (--type TEXT became STRING), I#4 (string default broke every create)add_field, update_field, remove_field. Every uppercase FieldType name passes through verbatim (TEXT stays TEXT); defaultValue takes a JSON boolean or numbercovered
Global picklists#4 (picklists get printed no values), #5, #6apply_picklist (idempotent), get_picklist (includes the values), list_picklists, deactivate_picklist_valuecovered
Field-scoped picklists#14, #15 (needed raw POST /api/fields and /api/picklist-values)apply_collection with inline values on the field, or add_field with picklistSourceType: "FIELD" and no picklistSourceId, then apply_field_picklist (idempotent, prune deactivates extras)covered
Validation rulesInspections rule on inspections.statuscreate_validation_rule, update_validation_rule, list_validation_rules, delete_validation_rulecovered
Page layoutsboth logs: one layout per collection with sections and related listsapply_layout (whole tree, idempotent)covered
List views (table)LIST_VIEW items in each template’s metadata.jsonapply_listview (idempotent)covered
List views (kanban: “Pipeline board”, “Inspection board”)view_type: KANBAN + type_config.kanban (laneField/cardFields) on LIST_VIEW items in metadata.jsonapply_listview (idempotent), create_listview and update_listview take viewType and typeConfigcovered
Flows#3 (no delete), #11, I#5create_flow, update_flow, delete_flow, list_flows; reference kelta://docs/flowscovered
Flow test runsInspections counter flow; CRM “Stamp closed deals”(user) update_record to trigger, get_flow_run, execute_flowcovered
Dashboard#10 (widget config keys undocumented)apply_dashboard (idempotent); reference kelta://docs/dashboardscovered
Dashboard validate / dataI#8 (kelta api POST …/validate needed --yes)validate_dashboard, dashboard_data (hosted admin tools, take a dashboard name or id); local alternative: cli_dashboards_validate, cli_dashboards_datacovered
Seed records with parent referencesthe records sections of each template’s metadata.json: key fields plus references (field → parent collection + natural-key field), resolved to the parent id by the importerseed_records (references: {"account": "accounts.name"} resolves keys before writing; batches of 100)covered; atomic operations stamp createdBy/updatedBy since KLT-500 (#12, recorded in .claude/docs/concerns.md)
Install a packageeach template’s whole install: kelta metadata apply metadata.json --yes (metadata items, list views, dashboard, then the records sections)apply_metadata (dryRun, conflictMode) and diff_metadata (preview, no writes), hosted admin tools taking the package JSON; local alternative: cli_metadata_apply, cli_metadata_diff (read the package from a file, act on the --tenant tenant)covered
Export#13, I#6 (whole tenant exported, filtered with jq)export_metadata with collections (only those collections and what hangs off them), a hosted admin tool returning the package JSON in its result; local alternative: cli_metadata_export, which writes the file on the machine running kelta mcp servecovered
Sandbox lifecycleboth logs: sandbox create / sandbox deletecli_sandbox_create, cli_sandbox_list, cli_sandbox_delete (from a server bound to the parent)covered

Edit this page on GitHub