{
  "name": "DareBuild",
  "version": "2026-07-18",
  "origin": "https://elonman.darebuild.com",
  "recommended_agent_surfaces": [
    "DareBuild ChatGPT App/MCP connector",
    "Codex",
    "Claude Code",
    "equivalent coding agent with browser/session plus MCP or HTTP request tools"
  ],
  "plain_chatgpt_boundary": "Plain ChatGPT without the DareBuild connector cannot use one-time DareBuild login links, unauthenticated upload URLs, or private account actions. Authenticated actions need the DareBuild ChatGPT App/MCP connector, Codex, Claude Code, an equivalent tool-capable agent, or a user who logs in to DareBuild and copies the Account Codex webhook from the dashboard Agent webhooks section or Team settings.",
  "first_read_paths": [
    "https://elonman.darebuild.com/llms.txt",
    "https://elonman.darebuild.com/agents.md",
    "https://elonman.darebuild.com/agents/project-users.md"
  ],
  "discovery": {
    "agent_readme_url": "https://elonman.darebuild.com/agents.md",
    "llms_txt_url": "https://elonman.darebuild.com/llms.txt",
    "manifest_url": "https://elonman.darebuild.com/.well-known/darebuild-agent.json",
    "alternate_manifest_url": "https://elonman.darebuild.com/agents.json",
    "openapi_url": "https://elonman.darebuild.com/.well-known/darebuild-openapi.json",
    "alternate_openapi_url": "https://elonman.darebuild.com/agents.openapi.json",
    "account_mcp_url_template": "https://elonman.darebuild.com/api/codex/v1/account/<account-token>/mcp/",
    "account_mcp_bearer_url": "https://elonman.darebuild.com/api/codex/v1/account/mcp/",
    "oauth_protected_resource_url": "https://elonman.darebuild.com/.well-known/oauth-protected-resource",
    "oauth_authorization_server_url": "https://elonman.darebuild.com/.well-known/oauth-authorization-server",
    "oauth_register_url": "https://elonman.darebuild.com/oauth/register/",
    "oauth_authorize_url": "https://elonman.darebuild.com/oauth/authorize/",
    "oauth_token_url": "https://elonman.darebuild.com/oauth/token/",
    "project_mcp_url_template": "https://elonman.darebuild.com/api/codex/v1/<project-token>/mcp/",
    "project_mcp_bearer_url": "https://elonman.darebuild.com/api/codex/v1/project/mcp/",
    "project_users_url": "https://elonman.darebuild.com/agents/project-users.md",
    "project_users_well_known_url": "https://elonman.darebuild.com/.well-known/darebuild-project-users.md",
    "generated_projects_url": "https://elonman.darebuild.com/agents/generated-projects.md",
    "generated_projects_well_known_url": "https://elonman.darebuild.com/.well-known/darebuild-generated-projects.md",
    "check_url": "https://elonman.darebuild.com/.well-known/darebuild-agent-check.json",
    "alternate_check_url": "https://elonman.darebuild.com/agents.check.json",
    "client_url": "https://elonman.darebuild.com/agents/client.py",
    "alternate_client_url": "https://elonman.darebuild.com/.well-known/darebuild-agent-client.py",
    "install_url": "https://elonman.darebuild.com/agents/install.sh",
    "alternate_install_url": "https://elonman.darebuild.com/.well-known/darebuild-agent-install.sh",
    "login_url": "https://elonman.darebuild.com/",
    "session_account_url": "https://elonman.darebuild.com/api/codex/v1/account/current/"
  },
  "homepage_agent_flow": {
    "when": "Use this from Codex, Claude Code, or an equivalent coding agent with browser/session support when the user gives only darebuild.com, the DareBuild homepage, or a public project URL without a private credential. Plain ChatGPT without the DareBuild connector must use a copied Account Codex webhook instead.",
    "steps": [
      "Read https://elonman.darebuild.com/llms.txt first, then https://elonman.darebuild.com/agents.md.",
      "Ask the user for their DareBuild email address if it is not already provided, and explain that DareBuild will email them a login link to paste back.",
      "Open https://elonman.darebuild.com/ and submit the homepage email form to send a login-link email.",
      "Ask the user to paste the login link from email, or to log in, open the dashboard Agent webhooks section or Team settings, and paste the Account Codex webhook URL.",
      "After the user opens the email login link, GET https://elonman.darebuild.com/api/codex/v1/account/current/ with the logged-in session to discover the account webhook.",
      "Prefer the Account MCP server for supported agents; otherwise use the Account Codex webhook for account actions such as list, create, list_members, invite_user, list_project_collaborators, and invite_project_user."
    ],
    "credential_options": [
      "email_login_link_for_tool_capable_agents",
      "copied_account_codex_webhook_url"
    ],
    "plain_chatgpt_rule": "Plain ChatGPT without the DareBuild connector should ask the user to log in to DareBuild and paste the Account Codex webhook from the dashboard Agent webhooks section or Team settings. It should not ask for or accept one-time login links.",
    "email_form_action": "https://elonman.darebuild.com/create/account/",
    "session_account_discovery_url": "https://elonman.darebuild.com/api/codex/v1/account/current/"
  },
  "mcp": {
    "transport": "streamable_http_json_rpc",
    "methods": [
      "initialize",
      "tools/list",
      "tools/call"
    ],
    "auth": {
      "preferred": "oauth2_authorization_code_pkce",
      "scope": "darebuild.account",
      "resource_metadata_url": "https://elonman.darebuild.com/.well-known/oauth-protected-resource",
      "authorization_server_metadata_url": "https://elonman.darebuild.com/.well-known/oauth-authorization-server",
      "registration_endpoint": "https://elonman.darebuild.com/oauth/register/",
      "authorization_endpoint": "https://elonman.darebuild.com/oauth/authorize/",
      "token_endpoint": "https://elonman.darebuild.com/oauth/token/",
      "legacy_bearer": "Authorization: Bearer <Account Codex token>",
      "fallback": "tokenized_url"
    },
    "account_server_url_template": "https://elonman.darebuild.com/api/codex/v1/account/<account-token>/mcp/",
    "account_bearer_server_url": "https://elonman.darebuild.com/api/codex/v1/account/mcp/",
    "oauth_account_server_url": "https://elonman.darebuild.com/api/codex/v1/account/mcp/",
    "project_server_url_template": "https://elonman.darebuild.com/api/codex/v1/<project-token>/mcp/",
    "project_bearer_server_url": "https://elonman.darebuild.com/api/codex/v1/project/mcp/",
    "account_tools": [
      "list_projects",
      "create_project",
      "request_project_limit_approval",
      "connect_cloudflare",
      "disconnect_cloudflare",
      "configure_custom_domain",
      "remove_custom_domain",
      "delete_project",
      "list_members",
      "invite_user",
      "update_member_role",
      "remove_member",
      "list_project_collaborators",
      "invite_project_user",
      "remove_project_collaborator",
      "project_manifest",
      "project_preview",
      "project_push_changes",
      "project_list_media",
      "project_upload_media_base64",
      "project_protect_files",
      "project_create_migration",
      "project_get_migration",
      "project_create_or_update_task",
      "project_run_task",
      "project_list_modal_deployments",
      "project_deploy_modal",
      "project_destroy_modal",
      "project_update_settings"
    ],
    "project_tools": [
      "project_manifest",
      "project_preview",
      "project_push_changes",
      "project_list_media",
      "project_upload_media_base64",
      "project_protect_files",
      "project_create_migration",
      "project_get_migration",
      "project_create_or_update_task",
      "project_run_task",
      "project_list_modal_deployments",
      "project_deploy_modal",
      "project_destroy_modal",
      "project_update_settings"
    ],
    "account_project_tool_rule": "On the OAuth account MCP server, project_* tools accept project_id, project_url, project_hostname, project_subdomain, or project_public_code."
  },
  "prompt_routing": [
    {
      "intent": "project_user_invite",
      "matches": [
        "add or invite an email address to a public DareBuild project URL",
        "add the user editor@example.com to my project https://project-name.darebuild.com/",
        "check darebuild.com for instructions"
      ],
      "read_first": "https://elonman.darebuild.com/agents/project-users.md",
      "do_not": [
        "do not scrape, edit, or inject anything into the public project page",
        "do not claim DareBuild lacks an agent flow before reading the public docs",
        "do not try to complete authenticated project invites from plain ChatGPT unless the DareBuild App/MCP connector or equivalent tools and credentials are available"
      ],
      "recommended_surface": [
        "Codex",
        "Claude Code",
        "equivalent coding agent"
      ],
      "requires_private_credential": [
        "DareBuild login link from the user's email for tool-capable agents",
        "Account Codex webhook URL copied from the dashboard Agent webhooks section or Team settings after login"
      ],
      "user_facing_auth_request": "I need access approved by your DareBuild account before I can add the project user. If I am running in Codex, Claude Code, or another tool-capable agent, tell me your DareBuild email and I will submit it at DareBuild so you receive a login link by email to paste here. If I am plain ChatGPT without the DareBuild connector, log in to DareBuild, open the dashboard Agent webhooks section or Team settings, copy the Account Codex webhook URL, and paste it here instead.",
      "plain_chatgpt_auth_request": "Please log in to DareBuild, open the dashboard Agent webhooks section or Team settings, copy the Account Codex webhook URL, and paste it here. Do not paste a one-time login link; plain ChatGPT cannot use it.",
      "action": {
        "endpoint": "https://elonman.darebuild.com/api/codex/v1/account/<account-token>/projects/",
        "oauth_mcp_server": "https://elonman.darebuild.com/api/codex/v1/account/mcp/",
        "mcp_server": "https://elonman.darebuild.com/api/codex/v1/account/<account-token>/mcp/",
        "mcp_tool": "invite_project_user",
        "method": "POST",
        "payload": {
          "action": "invite_project_user",
          "project_url": "https://project-name.darebuild.com/",
          "email": "editor@example.com",
          "role": "editor"
        }
      }
    },
    {
      "intent": "project_media_upload",
      "matches": [
        "upload an image, video, audio file, font, or PDF for a DareBuild project",
        "add media assets to a generated project",
        "make an uploaded image or video available to project HTML/CSS/JS"
      ],
      "requires_private_credential": [
        "project_codex_api_url"
      ],
      "action": {
        "endpoint": "https://elonman.darebuild.com/api/codex/v1/<project-token>/media/",
        "method": "POST multipart/form-data",
        "field": "media"
      },
      "do_not": [
        "do not ask the user for AWS access keys, S3 credentials, or bucket names",
        "do not upload media to a third-party account outside DareBuild"
      ],
      "result_usage": "Use returned media[].url values in generated project files."
    }
  ],
  "artifacts": {
    "client": {
      "url": "https://elonman.darebuild.com/agents/client.py",
      "well_known_url": "https://elonman.darebuild.com/.well-known/darebuild-agent-client.py",
      "content_type": "text/x-python; charset=utf-8",
      "sha256": "c8c117e2a1846fd2868c8759d09f8263f3b723e6a1552db4f55f6255cde766ba",
      "bytes": 28376
    },
    "installer": {
      "url": "https://elonman.darebuild.com/agents/install.sh",
      "well_known_url": "https://elonman.darebuild.com/.well-known/darebuild-agent-install.sh",
      "content_type": "text/x-shellscript; charset=utf-8",
      "sha256": "43226e98c3344d71c4a6d5b826d0077376ede2f6ab29a0a3af16db7c2c00746d",
      "bytes": 2821
    }
  },
  "security": {
    "private_webhook_discovery": "requires_human_approved_magic_link_or_copied_webhook",
    "webhook_secret_handling": "Keep account and project webhook URLs secret; rotate them in the GUI if exposed.",
    "human_only_operations": [
      "billing_and_credit_card_entry",
      "unlock_locked_files",
      "unhide_files_hidden_from_ai",
      "remove_own_team_access",
      "downgrade_own_administrator_role"
    ]
  },
  "capability_catalog": {
    "project_management": [
      "list",
      "create",
      "delete",
      "request_project_limit_approval"
    ],
    "custom_domains": [
      "connect_cloudflare",
      "disconnect_cloudflare",
      "configure_custom_domain",
      "remove_custom_domain"
    ],
    "team_members": [
      "list_members",
      "invite_user",
      "update_member_role",
      "remove_member"
    ],
    "project_scoped_editors": [
      "list_project_collaborators",
      "invite_project_user",
      "remove_project_collaborator"
    ],
    "project_code": [
      "manifest",
      "preview",
      "changes",
      "media",
      "files/protection",
      "migrations",
      "tasks",
      "modal"
    ],
    "media_uploads": [
      "media/"
    ],
    "generated_project_patterns": [
      "platform_auth_links",
      "project_auth_password",
      "project_local_cookies",
      "stripe_checkout",
      "subscriptions",
      "webhooks",
      "live_bridges",
      "modal_gpu_tasks"
    ],
    "background_tasks": [
      "tasks/",
      "tasks/<task_id>/run/"
    ],
    "live_bridges": [
      "runner_service.sdk.bridge_start",
      "runner_service.sdk.bridge_status",
      "runner_service.sdk.bridge_stop",
      "project_websockets"
    ],
    "modal_gpu_tasks": [
      "modal/",
      "project_deploy_modal",
      "project_destroy_modal",
      "project_list_modal_deployments",
      "tasks/",
      "tasks/<task_id>/run/",
      "runner_service.sdk.modal_function_spawn",
      "runner_service.sdk.modal_function_remote",
      "runner_service.sdk.modal_function_get"
    ],
    "file_protection": [
      "lock",
      "hide",
      "lock_and_hide"
    ],
    "billing": [
      "billing.payment_required",
      "billing.payment_url"
    ]
  },
  "server_vs_frontend_code": {
    "frontend_safe_files": [
      "public/*.html",
      "public/*.css",
      "public/*.js",
      "public/images",
      "public/*.json",
      "public/*.md",
      "public/*.txt"
    ],
    "backend_server_features": [
      "python_files",
      "database_migrations",
      "auth_database_access",
      "background_tasks",
      "live_bridges",
      "modal_gpu_tasks",
      "custom_domains"
    ],
    "rule": "Frontend-safe public non-Python files can be edited without backend unlock. Backend/server code and DNS/task/database features require backend access."
  },
  "generated_project_patterns": {
    "docs_url": "https://elonman.darebuild.com/agents/generated-projects.md",
    "runtime_structure": {
      "default_backend": "public/homepage.py",
      "default_template": "public/homepage.html",
      "shared_helpers": "shared/",
      "migrations_endpoint": "migrations/",
      "tasks_endpoint": "tasks/",
      "single_slug_pages": true,
      "handler_returns": [
        "dict",
        "(dict, status_code)",
        "HttpResponse"
      ],
      "cookie_prefixes_forwarded": [
        "project_",
        "darebuild_project_"
      ],
      "cookie_filtering": {
        "response_set_cookie": "unprefixed_cookies_are_dropped",
        "next_request_cookies": "unprefixed_cookies_are_omitted",
        "failure_mode": "login_redirect_succeeds_then_user_returns_to_login_form"
      },
      "runner_dependencies": [
        "django",
        "psycopg2",
        "fastapi",
        "uvicorn",
        "requests",
        "TikTokLive",
        "modal"
      ],
      "runner_missing_dependencies": [
        "stripe",
        "django-allauth",
        "django-sesame"
      ],
      "sdk_helpers": [
        "runner_service.sdk.send_email",
        "runner_service.sdk.cache_get",
        "runner_service.sdk.cache_set",
        "runner_service.sdk.cache_delete",
        "runner_service.sdk.ws_publish",
        "runner_service.sdk.bridge_start",
        "runner_service.sdk.bridge_status",
        "runner_service.sdk.bridge_stop",
        "runner_service.sdk.modal_function_spawn",
        "runner_service.sdk.modal_function_remote",
        "runner_service.sdk.modal_function_get"
      ],
      "websockets": {
        "browser_url_template": "request.darebuild.websocket_url_template",
        "browser_host_url_template": "request.darebuild.websocket_host_url_template",
        "browser_public_code_url_template": "request.darebuild.websocket_public_code_url_template",
        "python_publish_helper": "runner_service.sdk.ws_publish",
        "message_shape": {
          "channel": "string",
          "event": "string|null",
          "data": "any"
        },
        "public_channel_warning": "Public project WebSocket channels are visible to anyone who can access the generated project URL."
      }
    },
    "live_bridges": {
      "available_for": [
        "paid_or_backend_unlocked_projects",
        "jamespsteinberg@gmail.com"
      ],
      "requires_backend_access": true,
      "platforms": [
        "tiktok"
      ],
      "execution": "core_celery_bridge_session",
      "default_channel": "tiktok-live",
      "sdk_helpers": [
        "runner_service.sdk.bridge_start",
        "runner_service.sdk.bridge_status",
        "runner_service.sdk.bridge_stop"
      ],
      "browser_events": {
        "comment": {
          "text": "string",
          "word": "string",
          "user": "object",
          "comment_count": "integer"
        },
        "bridge-status": {
          "status": "queued|running|stopping|stopped|expired|failed"
        }
      },
      "rules": [
        "Start bridges from logged-in/backend-unlocked page handlers and return immediately.",
        "Use project WebSockets on the same channel for browser comment delivery.",
        "Do not run TikTokLiveClient.run() or other long-lived loops inside handler(request)."
      ]
    },
    "modal_gpu_tasks": {
      "available_for": [
        "paid_or_backend_unlocked_projects",
        "jamespsteinberg@gmail.com"
      ],
      "requires_backend_access": true,
      "access_scope": "project_owned_or_explicitly_granted_functions_only",
      "source_of_truth": "darebuild_project_files_tasks_and_modal_deployments",
      "external_source_policy": "do_not_depend_on_stonemountain_or_deleted_local_folders",
      "project_owned_app_name_pattern": "darebuild-build-<build_id> or darebuild-build-<build_id>-*",
      "managed_deployment_app_name_pattern": "darebuild-build-<build_id>-<slug>",
      "explicit_grants_model": "BuildModalFunctionAccess",
      "managed_deployments_model": "BuildModalDeployment",
      "deployment_lifecycle": "project_deploy_modal creates_or_updates; project_destroy_modal stops; project_list_modal_deployments lists",
      "deployment_tools": [
        "project_list_modal_deployments",
        "project_deploy_modal",
        "project_destroy_modal"
      ],
      "project_owned_first_use_monitoring": "auto_record_grant_and_queue_slack",
      "managed_deployment_monitoring": "queue_slack_on_deploy_and_destroy",
      "execution": "background_tasks_runner",
      "project_endpoints": [
        "modal/",
        "tasks/",
        "tasks/<task_id>/run/"
      ],
      "runner_dependency": "modal",
      "sdk_helpers": [
        "runner_service.sdk.modal_function_spawn",
        "runner_service.sdk.modal_function_remote",
        "runner_service.sdk.modal_function_get"
      ],
      "preferred_long_running_call": "runner_service.sdk.modal_function_spawn",
      "polling_helper": "runner_service.sdk.modal_function_get",
      "rules": [
        "Use project_deploy_modal before invoking a Modal app that does not already exist.",
        "Deploy payload source_code must define def handler(*args, **kwargs); DareBuild wraps it so project code does not execute during modal deploy.",
        "Use background tasks for GPU, photo-analysis, or other long-running AI work.",
        "Invoke only project-owned or explicitly granted deployed Modal functions through runner_service.sdk helpers.",
        "Project-owned Modal app names must be exactly darebuild-build-<build_id> or start with darebuild-build-<build_id>-.",
        "Managed deploys generate app names as darebuild-build-<build_id>-<slug>.",
        "Keep launcher code, UI code, and Modal deploy source in DareBuild project files/tasks/deployments, not in stonemountain or another local repo.",
        "First successful project-owned Modal use is auto-recorded and queues Slack monitoring.",
        "Managed deploy and destroy actions queue Slack monitoring.",
        "Shared Modal functions must be registered as enabled project grants before task code invokes them.",
        "Keep Modal credentials in the runner service environment only.",
        "Do not put Modal tokens in generated project files, public templates, JavaScript, or task params."
      ]
    },
    "auth": {
      "default_decision": "Use platform account links when DareBuild user identity is enough; use project-auth-password when the generated application needs its own end-user accounts.",
      "platform_account_routes": [
        "/accounts/login/",
        "/accounts/google/login/",
        "/accounts/logout/",
        "/accounts/password/reset/",
        "/account/email/",
        "/create/account/",
        "/magic/"
      ],
      "platform_request_fields": [
        "request.user.is_authenticated",
        "getattr(request.user, 'email', '')",
        "request.user.username",
        "request.darebuild.is_group_member"
      ],
      "project_local_starter": "project-auth-password",
      "project_local_tables": [
        "project_auth_users",
        "project_auth_sessions"
      ],
      "project_local_cookie": "project_auth_session",
      "allowed_cookie_prefixes": [
        "project_",
        "darebuild_project_"
      ],
      "cookie_name_must_match_for": [
        "set_cookie",
        "request.COOKIES",
        "delete_cookie"
      ],
      "project_local_csrf_cookie_example": "project_myapp_csrf",
      "default_django_cookie_warning": "Do not use sessionid or csrftoken as generated-project session/CSRF cookies; Core does not forward unprefixed cookies into or out of runner requests.",
      "login_round_trip_test": [
        "login_response_sets_prefixed_cookie",
        "next_request_receives_cookie",
        "authenticated_page_renders",
        "protected_post_validates_csrf",
        "logout_deletes_same_cookie"
      ],
      "email_helper": "runner_service.sdk.send_email",
      "allauth_template_tags_available_in_runner": false,
      "google_oauth_rule": "Use /accounts/google/login/ for platform Google sign-in. For app-owned Google OAuth, ask for OAuth client configuration and secret handling before implementing an explicit authorize/callback flow."
    },
    "payments": {
      "darebuild_billing_is_app_payments": false,
      "stripe_python_sdk_available_in_runner": false,
      "recommended_api_client": "requests",
      "requires_safe_secret_handling": true,
      "checkout_fields": [
        "mode",
        "success_url",
        "cancel_url",
        "customer_email",
        "line_items",
        "metadata",
        "payment_intent_data.metadata"
      ],
      "order_statuses": [
        "started",
        "checkout_created",
        "paid",
        "payment_failed",
        "expired",
        "canceled"
      ],
      "stripe_ids_to_store": [
        "checkout_session_id",
        "payment_intent_id",
        "customer_id",
        "subscription_id"
      ]
    },
    "webhooks": {
      "platform_webhooks_main_is_for_darebuild_billing": true,
      "project_webhook_route_pattern": "/stripe_webhook/",
      "rules": [
        "verify_signature",
        "reject_invalid_payloads",
        "idempotency_by_event_id",
        "metadata_scoping",
        "return_json_success"
      ],
      "payment_events": [
        "checkout.session.completed",
        "checkout.session.async_payment_succeeded",
        "checkout.session.async_payment_failed",
        "checkout.session.expired",
        "payment_intent.succeeded",
        "payment_intent.payment_failed",
        "charge.dispute.created"
      ],
      "subscription_events": [
        "invoice.paid",
        "invoice.payment_failed",
        "customer.subscription.updated",
        "customer.subscription.deleted"
      ]
    }
  },
  "bootstrap": {
    "homepage_start_rule": "If a tool-capable agent starts from the DareBuild homepage without a webhook or email login link, ask for their DareBuild email, explain they will receive an email with a login link, submit the homepage email form, then ask them to paste the login link.",
    "session_account_discovery_url": "https://elonman.darebuild.com/api/codex/v1/account/current/",
    "session_account_discovery_rule": "After the user logs in with an email login link, GET this URL with the logged-in session cookie to receive the private account webhook URL and command catalog.",
    "standalone_install_script": "curl -fsSL https://elonman.darebuild.com/agents/install.sh -o darebuild-agent-install.sh && sh darebuild-agent-install.sh",
    "standalone_client_install": "curl -fsSL https://elonman.darebuild.com/agents/client.py -o darebuild_agent.py",
    "standalone_client_check": "python darebuild_agent.py check",
    "standalone_client_commands": "python darebuild_agent.py commands --format json",
    "standalone_client_bootstrap": "python darebuild_agent.py bootstrap --magic-link \"https://darebuild.com/magic/...\" --run-smoke --editor-email \"editor@example.com\"",
    "from_magic_link_command": "cd core\npython manage.py darebuild_codex_bootstrap \\\n  --magic-link \"https://darebuild.com/magic/...\" \\\n  --run-smoke \\\n  --editor-email \"editor@example.com\"",
    "from_account_webhook_command": "cd core\npython manage.py darebuild_codex_smoke \\\n  --account-webhook-url \"https://elonman.darebuild.com/api/codex/v1/account/<account-token>/projects/\" \\\n  --editor-email \"editor@example.com\"",
    "gui_webhook_steps": [
      "Log in to https://elonman.darebuild.com.",
      "Prefer GET https://elonman.darebuild.com/api/codex/v1/account/current/ from the logged-in session.",
      "Or open Team settings.",
      "Find Account Codex API.",
      "Copy the URL under Local project management."
    ]
  },
  "account_webhook": {
    "session_discovery_url": "https://elonman.darebuild.com/api/codex/v1/account/current/",
    "url_template": "https://elonman.darebuild.com/api/codex/v1/account/<account-token>/projects/",
    "mcp_server_url_template": "https://elonman.darebuild.com/api/codex/v1/account/<account-token>/mcp/",
    "mcp_bearer_server_url": "https://elonman.darebuild.com/api/codex/v1/account/mcp/",
    "methods": [
      "GET",
      "POST"
    ],
    "notes": [
      "GET is equivalent to POST action=list.",
      "The OAuth account MCP server is the preferred ChatGPT/App integration path.",
      "MCP tools expose the same account actions for agents that support MCP.",
      "The account MCP server also exposes project_* tools; pass project_id or project_url for project edits, media, file protection, migrations, tasks, and settings.",
      "list and create responses include project codex_api_url values.",
      "Project payloads include custom_domains with TXT verification and routing instructions.",
      "Use connect_cloudflare to obtain a human approval URL before asking DareBuild to write DNS records.",
      "Use DNS records, not Cloudflare Workers, to connect custom domains to DareBuild projects; use configure_custom_domain and the returned DNS instructions.",
      "Accounts default to 20 active projects; when create returns project_limit_reached, send request_project_limit_approval."
    ],
    "actions": [
      {
        "name": "list",
        "payload": {
          "action": "list"
        },
        "returns": [
          "projects",
          "starter_templates",
          "commands",
          "account",
          "capabilities",
          "project_limit"
        ]
      },
      {
        "name": "create",
        "payload": {
          "action": "create",
          "name": "New app",
          "starter_key": "blank",
          "subdomain": "new-app"
        },
        "returns": [
          "project"
        ],
        "errors": [
          "project_limit_reached",
          "subdomain_taken"
        ]
      },
      {
        "name": "connect_cloudflare",
        "payload": {
          "action": "connect_cloudflare"
        },
        "returns": [
          "cloudflare"
        ],
        "requires": [
          "team_admin"
        ],
        "notes": [
          "If cloudflare.connected is false, show cloudflare.approval_url to the human and wait for approval.",
          "If cloudflare.approval_link_ready is false, DareBuild platform OAuth setup is incomplete and the human approval link cannot work yet.",
          "Codex must not request or store Cloudflare credentials."
        ]
      },
      {
        "name": "disconnect_cloudflare",
        "payload": {
          "action": "disconnect_cloudflare"
        },
        "returns": [
          "cloudflare"
        ],
        "requires": [
          "team_admin"
        ],
        "notes": [
          "Removes the account Cloudflare connection.",
          "Future custom-domain DNS automation requires reconnecting Cloudflare."
        ]
      },
      {
        "name": "create_hello_world_custom_domain",
        "payload": {
          "action": "create",
          "name": "Test3 hello world",
          "starter_key": "hello-world",
          "subdomain": "test3",
          "custom_domain": "test3.darefail.com",
          "cloudflare": {
            "zone_name": "darefail.com",
            "proxy_mode": "dns_only"
          }
        },
        "returns": [
          "project",
          "custom_domain"
        ],
        "requires": [
          "account_webhook",
          "cloudflare_connection"
        ],
        "notes": [
          "Run connect_cloudflare first if the account is not connected.",
          "If no Cloudflare connection exists, the response returns cloudflare.approval_url for human approval.",
          "Use DNS records, not Cloudflare Workers, to connect custom domains to DareBuild projects."
        ]
      },
      {
        "name": "configure_custom_domain",
        "payload": {
          "action": "configure_custom_domain",
          "project_id": 123,
          "custom_domain": "test3.darefail.com",
          "cloudflare": {
            "zone_name": "darefail.com",
            "proxy_mode": "dns_only"
          }
        },
        "returns": [
          "project",
          "custom_domain"
        ],
        "requires": [
          "team_admin",
          "backend_access",
          "cloudflare_connection"
        ],
        "notes": [
          "Use the approved account Cloudflare connection for DNS writes.",
          "Do not ask the human for Cloudflare API keys; use connect_cloudflare and the returned approval_url.",
          "Use DNS records, not Cloudflare Workers, to connect custom domains to DareBuild projects; configure_custom_domain sets the project DNS routing path."
        ]
      },
      {
        "name": "remove_custom_domain",
        "payload": {
          "action": "remove_custom_domain",
          "project_id": 123,
          "custom_domain": "test3.darefail.com"
        },
        "returns": [
          "project",
          "custom_domain"
        ],
        "requires": [
          "team_admin",
          "backend_access"
        ],
        "notes": [
          "Returns the project to its DareBuild subdomain.",
          "If the account Cloudflare connection is still approved, DareBuild also removes the matching TXT record and DareBuild-created routing records."
        ]
      },
      {
        "name": "request_project_limit_approval",
        "payload": {
          "action": "request_project_limit_approval",
          "name": "New app",
          "starter_key": "blank"
        },
        "when": "Use when project_limit.limit_reached is true or create returns project_limit_reached.",
        "effect": "Sends DareBuild a Slack/email request for more project capacity."
      },
      {
        "name": "delete",
        "payload": {
          "action": "delete",
          "project_id": 123
        },
        "requires": [
          "team_admin"
        ]
      },
      {
        "name": "list_members",
        "payload": {
          "action": "list_members"
        }
      },
      {
        "name": "invite_user",
        "payload": {
          "action": "invite_user",
          "email": "editor@example.com",
          "role": "member"
        },
        "requires": [
          "team_admin"
        ]
      },
      {
        "name": "update_member_role",
        "payload": {
          "action": "update_member_role",
          "email": "editor@example.com",
          "role": "admin"
        },
        "requires": [
          "team_admin"
        ]
      },
      {
        "name": "remove_member",
        "payload": {
          "action": "remove_member",
          "email": "editor@example.com"
        },
        "requires": [
          "team_admin"
        ]
      },
      {
        "name": "list_project_collaborators",
        "payload": {
          "action": "list_project_collaborators",
          "project_url": "https://project-name.darebuild.com/"
        }
      },
      {
        "name": "invite_project_user",
        "payload": {
          "action": "invite_project_user",
          "project_url": "https://project-name.darebuild.com/",
          "email": "editor@example.com",
          "role": "editor",
          "allowed_paths": [
            "public/homepage.css",
            "public/homepage.js"
          ]
        },
        "notes": [
          "Use project_id from list or pass project_url/project_hostname when the user gives a public project URL."
        ],
        "requires": [
          "team_admin"
        ]
      },
      {
        "name": "remove_project_collaborator",
        "payload": {
          "action": "remove_project_collaborator",
          "project_url": "https://project-name.darebuild.com/",
          "email": "editor@example.com"
        },
        "requires": [
          "team_admin"
        ]
      }
    ]
  },
  "starter_keys": [
    "blank",
    "hello-world",
    "project-auth-password",
    "allauth-login-links",
    "todo-list",
    "background-timestamp-task"
  ],
  "project_api": {
    "base_url_template": "https://elonman.darebuild.com/api/codex/v1/<project-token>/",
    "mcp_server_url_template": "https://elonman.darebuild.com/api/codex/v1/<project-token>/mcp/",
    "mcp_bearer_server_url": "https://elonman.darebuild.com/api/codex/v1/project/mcp/",
    "endpoints": [
      {
        "method": "GET",
        "path": "manifest/",
        "purpose": "List project metadata, files, tasks, migrations, and permissions."
      },
      {
        "method": "GET",
        "path": "client.py",
        "purpose": "Download a small Python client for this project API."
      },
      {
        "method": "POST",
        "path": "preview/",
        "payload": {
          "page_slug": "homepage",
          "files": {
            "public/homepage.html": "<h1>Preview</h1>"
          }
        }
      },
      {
        "method": "POST",
        "path": "changes/",
        "payload": {
          "files": {
            "public/homepage.html": "<h1>Hello</h1>"
          },
          "publish": true,
          "message": "Update homepage"
        }
      },
      {
        "method": "GET",
        "path": "media/",
        "purpose": "List media uploaded through DareBuild for this project."
      },
      {
        "method": "POST",
        "path": "media/",
        "purpose": "Upload images, videos, audio, fonts, or PDFs through DareBuild-managed storage.",
        "content_type": "multipart/form-data",
        "field": "media",
        "notes": [
          "Use returned media[].url values in generated project files.",
          "Do not ask for AWS or S3 credentials; DareBuild chooses the storage account."
        ]
      },
      {
        "method": "POST",
        "path": "files/protection/",
        "payload": {
          "action": "lock_and_hide",
          "paths": [
            "public/homepage.py",
            "shared/__init__.py"
          ]
        },
        "notes": [
          "Codex can lock or hide files, but only a human can unlock or unhide them in the GUI."
        ]
      },
      {
        "method": "POST",
        "path": "migrations/",
        "payload": {
          "name": "create_todos",
          "sql": "create table if not exists todos (id serial primary key, title text not null);",
          "run": true
        }
      },
      {
        "method": "GET",
        "path": "migrations/<migration_id>/"
      },
      {
        "method": "POST",
        "path": "tasks/",
        "purpose": "Create or update a background task, including Modal GPU launcher tasks when backend access is available.",
        "payload": {
          "name": "Update timestamp",
          "code": "def run(params, context):\n    return {'ok': True}",
          "cron_minute": "0",
          "cron_hour": "*",
          "enabled": true
        }
      },
      {
        "method": "POST",
        "path": "tasks/<task_id>/run/",
        "purpose": "Queue a background task run.",
        "payload": {}
      },
      {
        "method": "POST",
        "path": "project/",
        "payload": {
          "name": "Renamed app",
          "subdomain": "renamed-app"
        }
      }
    ]
  },
  "media_uploads": {
    "project_endpoint": "https://elonman.darebuild.com/api/codex/v1/<project-token>/media/",
    "method": "POST multipart/form-data",
    "field": "media",
    "supported_content": [
      "images",
      "video",
      "audio",
      "fonts",
      "pdf"
    ],
    "storage_policy": "DareBuild manages per-account storage and returns public media URLs. Agents must not request AWS or S3 credentials.",
    "client_command": "python ../bin/darebuild_codex_client.py media hero.png intro.mp4"
  },
  "live_bridges": {
    "available_for": [
      "paid_or_backend_unlocked_projects",
      "jamespsteinberg@gmail.com"
    ],
    "requires_backend_access": true,
    "platforms": [
      "tiktok"
    ],
    "execution": "core_celery_bridge_session",
    "default_channel": "tiktok-live",
    "sdk_helpers": [
      "runner_service.sdk.bridge_start",
      "runner_service.sdk.bridge_status",
      "runner_service.sdk.bridge_stop"
    ],
    "browser_events": {
      "comment": {
        "text": "string",
        "word": "string",
        "user": "object",
        "comment_count": "integer"
      },
      "bridge-status": {
        "status": "queued|running|stopping|stopped|expired|failed"
      }
    },
    "rules": [
      "Start bridges from logged-in/backend-unlocked page handlers and return immediately.",
      "Use project WebSockets on the same channel for browser comment delivery.",
      "Do not run TikTokLiveClient.run() or other long-lived loops inside handler(request)."
    ]
  },
  "modal_gpu_tasks": {
    "available_for": [
      "paid_or_backend_unlocked_projects",
      "jamespsteinberg@gmail.com"
    ],
    "requires_backend_access": true,
    "access_scope": "project_owned_or_explicitly_granted_functions_only",
    "source_of_truth": "darebuild_project_files_tasks_and_modal_deployments",
    "external_source_policy": "do_not_depend_on_stonemountain_or_deleted_local_folders",
    "project_owned_app_name_pattern": "darebuild-build-<build_id> or darebuild-build-<build_id>-*",
    "managed_deployment_app_name_pattern": "darebuild-build-<build_id>-<slug>",
    "explicit_grants_model": "BuildModalFunctionAccess",
    "managed_deployments_model": "BuildModalDeployment",
    "deployment_lifecycle": "project_deploy_modal creates_or_updates; project_destroy_modal stops; project_list_modal_deployments lists",
    "deployment_tools": [
      "project_list_modal_deployments",
      "project_deploy_modal",
      "project_destroy_modal"
    ],
    "project_owned_first_use_monitoring": "auto_record_grant_and_queue_slack",
    "managed_deployment_monitoring": "queue_slack_on_deploy_and_destroy",
    "execution": "background_tasks_runner",
    "project_endpoints": [
      "modal/",
      "tasks/",
      "tasks/<task_id>/run/"
    ],
    "runner_dependency": "modal",
    "sdk_helpers": [
      "runner_service.sdk.modal_function_spawn",
      "runner_service.sdk.modal_function_remote",
      "runner_service.sdk.modal_function_get"
    ],
    "rules": [
      "Use project_deploy_modal before invoking a Modal app that does not already exist.",
      "Deploy payload source_code must define def handler(*args, **kwargs); DareBuild wraps it so project code does not execute during modal deploy.",
      "Use background tasks for GPU or image-analysis work.",
      "Invoke only project-owned or explicitly granted deployed Modal functions through runner_service.sdk helpers.",
      "Project-owned Modal app names must be exactly darebuild-build-<build_id> or start with darebuild-build-<build_id>-.",
      "Managed deploys generate app names as darebuild-build-<build_id>-<slug>.",
      "Keep launcher code, UI code, and Modal deploy source in DareBuild project files/tasks/deployments, not in stonemountain or another local repo.",
      "First successful project-owned Modal use is auto-recorded and queues Slack monitoring.",
      "Managed deploy and destroy actions queue Slack monitoring.",
      "Shared Modal functions must be registered as enabled project grants before task code invokes them.",
      "Prefer modal_function_spawn for long GPU work and modal_function_get for polling.",
      "Do not expose Modal tokens in generated project files, public templates, JavaScript, or task params.",
      "Modal credentials stay in the DareBuild runner; agents can deploy, call, and destroy project-owned apps without seeing tokens."
    ]
  },
  "custom_domains": {
    "account_action": "configure_custom_domain",
    "remove_action": "remove_custom_domain",
    "cloudflare_connection_action": "connect_cloudflare",
    "create_fields": [
      "subdomain",
      "custom_domain",
      "cloudflare"
    ],
    "cloudflare_connection_policy": "human_approved_oauth_connection_required",
    "cloudflare_token_policy": "operator_manual_fallback_only_never_request_from_end_users",
    "worker_policy": "Use DNS records, not Cloudflare Workers, to connect custom domains to DareBuild projects. Workers are allowed for explicitly requested Worker/proxy features outside the ordinary domain-attachment flow.",
    "cloudflare_permissions": [
      "Zone:DNS:Edit",
      "Zone:Zone:Read"
    ],
    "agent_rule": "If cloudflare.connected is false, give the human cloudflare.approval_url and retry after approval. If cloudflare.approval_link_ready is false, report that DareBuild platform OAuth setup is incomplete. Use DNS records, not Cloudflare Workers, to connect custom domains to DareBuild projects.",
    "manual_setup": {
      "verification_record": "TXT _darebuild-verify.<hostname> = darebuild-verify=<token>",
      "routing_record": "Set the DNS CNAME/ALIAS/ANAME from response.custom_domain.routing for DNS-only routing, or use Cloudflare for SaaS Custom Hostname when cloudflare.proxy_mode=cloudflare_saas. Do not use a Cloudflare Worker as the project-domain connection mechanism."
    }
  },
  "billing": {
    "card_entry": "gui_only",
    "display_price": "$20/month",
    "free_backend_access_emails": [
      "jamespsteinberg@gmail.com"
    ],
    "rule": "Do not send free backend access emails to checkout.",
    "payment_required_rule": "When a project response, manifest, or backend_locked error includes billing.payment_required=true, show billing.payment_url to the user and explain that payment is required before backend/database/task deployment can continue.",
    "payment_url_field": "billing.payment_url",
    "agent_must_not_pay": true
  },
  "project_scoped_editor": {
    "allowed_paths_field": "allowed_paths",
    "can": [
      "view_allowed_files",
      "edit_allowed_files"
    ],
    "cannot": [
      "manage_settings",
      "manage_billing",
      "manage_roles",
      "manage_users",
      "publish",
      "manage_tasks",
      "manage_migrations",
      "lock_hide_unlock_or_unhide_files"
    ]
  },
  "acceptance_workflow": [
    "Create project-auth-password and verify project-local auth.",
    "Create todo-list and verify the public to-do page.",
    "Create background-timestamp-task and verify hourly task metadata.",
    "Create blank, lock Python files, and edit only public/homepage.html.",
    "Create blank, invite a project-scoped editor, lock and hide Python files, and allow only CSS/JS paths."
  ]
}