| name | build |
| description | Build Bifrost workflows, forms, agents, apps, tables, and files for both Solution workspaces (v2) and the global _repo workspace (v1). Supports SDK-first (local dev + git) and MCP-only modes. |
Bifrost Build
Build Bifrost artifacts — apps, workflows, forms, agents, tables, and files. This hub detects your workspace mode and routes you to the right entry doc.
Prerequisites
echo "SDK: $BIFROST_SDK_INSTALLED | Login: $BIFROST_LOGGED_IN | MCP: $BIFROST_MCP_CONFIGURED"
echo "Source: $BIFROST_HAS_SOURCE | Path: $BIFROST_SOURCE_PATH"
command -v bifrost >/dev/null && bifrost auth default
If the SDK is false/empty or the CLI is not authenticated: Direct the user
to run /bifrost:setup first.
Connection model
Bifrost can store credentials for multiple instance URLs. The nearest .env
in the current folder or a parent binds that workspace to one connection; a
folder without a binding uses the user's saved default.
bifrost auth default is read-only. Its Default connection line shows the
saved fallback, while Current connection shows what commands from this
folder will use. Before discovery or mutation, confirm the current connection
is the intended instance. If it is wrong, run from the intended workspace or
neutral folder. Do not change the saved default merely to work with a debug
stack; the debug skill creates a dedicated folder binding.
A Codex sandbox may be unable to read the host OS keyring and can therefore
make an existing login look absent. Before invoking setup or login, rerun the
same read-only bifrost auth default probe with host access from the exact
workspace you intend to use. If that host probe succeeds, reuse it; never log
in again merely to work around a sandbox-only credential failure.
Most entity commands do not accept --url; the folder binding is their
connection selector. Never repoint a bound folder by overriding only
BIFROST_API_URL, because folder-loaded tokens may belong to its original URL.
BIFROST_DEV_URL is only a base for preview and platform links. It does not
select or prove the authenticated CLI connection. If it is empty and a link is
needed, ask the user for the base URL. Never invent a host.
Step 1: Detect Workspace Mode
Walk up from the current directory looking for bifrost.solution.yaml (written by bifrost solution init):
dir="$PWD"; found=""
while [ "$dir" != "/" ]; do
[ -f "$dir/bifrost.solution.yaml" ] && found="$dir/bifrost.solution.yaml" && break
dir="$(dirname "$dir")"
done
echo "${found:-NOT_FOUND}"
Found → Solution workspace (v2). Read references/solutions.md and follow it.
- Entities (apps, workflows, forms, agents, tables, configs) and declared file locations are deploy-owned. They ship with the solution and are installed/updated by
bifrost solution deploy — NOT by live CLI mutations. Calling bifrost forms create (or any entity create/update) in a solution workspace 409s because deploy owns those records.
- You author app code in
apps/ and Python workflows in functions/, then deploy with bifrost solution deploy.
Not found → Global _repo workspace (v1). Read references/repo.md and follow it.
- Entities are mutated live via entity CLI verbs (create, update, delete).
- File-backed entities (workflow
.py, app .tsx) are synced by the watch daemon after the user starts it.
- MCP-only mode (no local source) also follows repo.md.
Do not use .bifrost/*.yaml as a mode marker. It is an export artifact and may be absent from any workspace.
Step 2: Confirm Org + Access Before Scaffolding
This is mode-agnostic — always do it before creating anything.
-
Which org? Ask in natural language. Resolve to a UUID:
bifrost orgs list --json
bifrost orgs get "Org Name" --json
-
Who has access? Confirm the access tuple (organization, access_level, role_ids) and apply it consistently to the app and every supporting workflow, form, and agent. Mismatched access is the most common reason a working app silently 403s.
Compatibility rule: when an app is assigned to roles X (under Org A or global), every supporting entity must satisfy at least one of:
- Global scope (any org, available to all roles), OR
- Org A scoped +
access_level=authenticated (any logged-in user in Org A), OR
- Same role(s) X assigned to it.
Example — Finance app for Org A, role-restricted to finance:
bifrost apps create --name "Finance" --slug finance --organization "Org A" \
--access-level role_based --role-ids finance --app-model inline_v1
bifrost forms create --name "Submit Invoice" --workflow <uuid> \
--organization "Org A" --access-level role_based --role-ids finance
bifrost workflows register --path workflows/finance.py --function-name process_invoice \
--org "Org A" --access-level role_based --role-ids finance
Every workflow the Finance app calls must be either global, Org-A+authenticated, or finance-role — otherwise the Finance user gets a 403 at execution time.
Discover roles:
bifrost roles list --json
Global Hard Rules (Both Modes)
- In a Solution workspace, entities are deploy-owned — never mutate them live. Creating or updating a form, agent, table, config, app, or workflow via the entity CLI create/update verbs against a solution-managed record 409s (deploy owns them). Author the content in the workspace and ship it with
bifrost solution deploy. Solution file locations are declared in .bifrost/files.yaml; runtime file bytes are user data, not source files to edit under _solutions/. (This rule does NOT apply in the global _repo workspace, where live mutation is the normal path — see the mode dispatcher above.)
- Never run the watch/push/pull/sync/git commands unsolicited. These are user-driven, have broad blast radius, or launch interactive TUIs. Describe them to the user and ask them to run the command themselves. This applies in both solution and repo mode.
- Never call
bifrost api for third-party integration APIs (HaloPSA, Pax8, NinjaOne, etc.). bifrost api is the Bifrost platform API only. Call integration APIs from within a workflow using the SDK, not the bifrost api passthrough.
- Check before using
bifrost api GET <path>. If you don't know whether a platform endpoint exists, check generated/openapi-digest.md or the entity's --help flag first. Never guess URL patterns.
- Do NOT read
.bifrost/*.yaml for discovery. It is an export artifact, not the source of truth. Use entity list/get commands (bifrost forms list --json, bifrost workflows get <ref> --json, etc.).
MCP Tool Naming Convention (CRITICAL for Discoverability)
When workflows are exposed as MCP tools (via agents), their name becomes the MCP tool name and description becomes the MCP tool description. Claude.ai uses deferred tool search: tools compete on relevance ranking across ALL connected MCP servers. Generic names like list_findings get buried.
Format: {context}_{action} — prefix every tool name with a distinctive context word.
Descriptions: Must include the agent/feature name and enough distinctive vocabulary to win search ranking. Lead with what it does; include the domain context.
| Bad name | Good name | Bad description | Good description |
|---|
list_findings | list_agent_tuning_findings | "List findings" | "List agent tuning findings from Bifrost AI agent run reviews with filtering and pagination" |
review_agent_runs | review_agent_tuning_runs | "Review an agent's runs" | "Review a Bifrost AI agent's recent conversation runs and create tuning findings for prompt issues" |
dry_run_prompt | dry_run_agent_tuning_prompt | "Test a candidate prompt" | "Generate a candidate prompt from confirmed agent tuning findings and dry-run test it against historical runs" |
Rules:
- Every tool name MUST contain a context prefix that identifies its agent/feature (e.g.
agent_tuning_, halopsa_, documentation_)
- The
description MUST mention the agent or feature name — this is what tool_search ranks on
- Descriptions should be self-contained — someone seeing ONLY the description (no server name) should know what domain this tool belongs to
- Follow professional MCP conventions:
microsoft_docs_search, outlook_email_search, execute_halopsa_sql
Reference Index
| I need to… | Read |
|---|
| Build in a Solution workspace | references/solutions.md |
Build in the global _repo workspace | references/repo.md |
| Build or modify an app (TSX/React) | references/apps.md · references/web-sdk-v2.md |
| Write or debug a Python workflow | references/workflows-python.md · references/python-sdk.md |
| Build or configure an agent | references/entities.md |
| Create a form | references/entities.md |
| Create/update/delete any CLI entity | references/entities.md |
| Work with tables (read/write structured data) | references/tables.md |
| Work with app/user files | references/solutions.md · references/web-sdk-v2.md |
| MCP-only mode (no local source) | references/mcp-mode.md |
| Exact CLI flag for a command | generated/cli-reference.md |
| Does a platform endpoint exist? | generated/openapi-digest.md |
Maintaining the Reference Docs
The generated/* appendices are regenerated by python api/scripts/skill-truth/generate.py and CI fails if they drift. The curated references/*.md are hand-written; references/sources.yaml maps each to the source files it documents + the sha it was last verified against. When test_staleness_is_reported_not_fatal (run on the host) reports a file as stale, re-read the changed source, fix the prose, and bump that file's verified_at_sha. This mirrors the bifrost-documentation skill's manifest + diff-mode pattern: re-verify only what changed, not the whole SDK.
Session Summary
At end of session, provide:
## Session Summary
### Completed
- [What was built/accomplished]
### Notes for Future Sessions
- [Relevant context]