Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}
logging
{}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
extensions
{
  "io.modelcontextprotocol/ui": {}
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
setup_statusA

Setup state per service: enabled, keys set/missing (never values), missing tools with install commands, approvals mode, and next steps. Call this first; nothing here needs a config file.

setup_servicesB

Turn services on or off (research is always on). Ask the user which ones they want first. Returns setup_status.

setup_setA

Set ONE non-secret config key (e.g. asc_key_id, team_id, support_email). Secrets are refused: use setup_credentials so they never pass through the chat. An empty value clears the key.

setup_approvalsA

Set human approvals for live writes: 'required' (recommended). 'off' is refused here; only the human can switch it off, on the setup_credentials page.

setup_credentialsA

Open a local browser page (127.0.0.1, random port, one-time token) where the USER types the credentials of the given (default: all enabled) services. Secrets never reach you. Returns at once with the url; tell the user to fill the form and Save, then call setup_status().

config_doctorA

Report config status: which keys are present/missing (secrets are masked).

config_setA

Write NON-secret settings to ~/.appfactory/config.toml (0600). Fields left empty are unchanged.

Secrets (passwords, sessions, tokens, API keys, phone) are refused here so they never pass through the model: the human enters them on the page opened by setup_credentials().

asc_token_checkA

Check App Store Connect auth through the asc CLI: binary present, which credentials it uses (config.toml asc_* keys as env, else the asc keychain profile) and one live read-only call.

A successful asc apps list --limit 1 proves key id, issuer and .p8 together.

asc_list_appsA

List the apps in App Store Connect (LIVE; requires issuer_id).

asc_get_appC

Find the App Store Connect app by bundle id (LIVE).

asc_create_bundle_idA

Register a bundle id in App Store Connect (LIVE write), then its capabilities.

The App ID capabilities (IN_APP_PURCHASE, APPLE_ID_AUTH/PRIMARY_APP_CONSENT, HEALTHKIT if spec.health.enabled) must exist BEFORE any key, profile or signing step. With app_dir the spec's capabilities are checked right away; apply_capabilities=true also applies them. Human approval.

asc_create_appA

Create an app SHELL in App Store Connect (fastlane produce — requires Apple ID). AUTOMATIC.

The one ASC write that does not go through the asc CLI: Apple's public API cannot create apps and asc web apps create needs the same interactive 2FA web session, so produce stays.

App names are globally unique. Pass candidate_names → the MCP AUTOMATICALLY picks the first available one (on a "name taken" error it moves to the next) and returns app_id. app_name (single name) is for backward compatibility; it's converted to a one-element candidate list.

asc_create_subscription_groupC

Create a subscription group for the app (LIVE write).

asc_finalize_subscriptionA

FINALIZE one subscription (ORDER: localization → availability (all but CHN) → price → intro offer). The intro offer follows the SPEC: pass the spec product's intro ({"type":"free","duration":"P3D"}); it is created per territory. Offer products: pass nothing (no intro offer). period is ignored (the old embedded offers were wrong). Prefer store_setup, which does every product idempotently.

asc_finalize_submission_requirementsA

Fill submit-blocking app-level fields in one call: Content Rights + Copyright + Age Rating (4+) + Free Price + App Review Contact + App Review Notes (7-item test flow). App Privacy EXCLUDED (not in Apple's API → set via ASC web UI; appDataUsages endpoints all 404). Called before submit, per app. RULE: if copyright is omitted, it's read from config ("copyright" key — set your own via config_set); if contact_email is omitted, support_email is used (NOT apple_id, which is only the developer-account login). If review_notes is omitted, a generic 7-item template is filled with app_name/ai_services (Apple 2.1).

asc_append_subscription_disclosureA

APPEND subscription disclosure + Terms/EULA + Privacy link to the description (per language) (Apple 3.1.2). Idempotent (skips if the marker is present). If terms_url is omitted, Apple's standard EULA is used. Truncated to ≤4000.

asc_ensure_subscription_pricesA

Walk ALL of the app's subscriptions; set a price on those that have NONE (clears MISSING_METADATA). Idempotent (those with a price are skipped). Price comes from usd_price_by_product[productId] or default_usd.

asc_add_subscription_group_localizationD

Subscription group display name (required for MISSING_METADATA).

asc_localize_subscriptionB

Localize the subscription in MULTIPLE LANGUAGES. items={locale:{name,description}}. IAP-unsupported languages are skipped.

asc_localize_groupC

Localize the subscription group name in multiple languages.

asc_create_subscriptionC

Create a subscription product. period: ONE_WEEK/ONE_MONTH/.../ONE_YEAR (LIVE write).

asc_submit_for_reviewA

SUBMIT the app to App Store review. Always needs out-of-band human approval (appfactory approve <id>), even with approvals off. Without a valid approval_id nothing is submitted.

env_doctorB

Check the local toolchain: xcode, swift, node, asc (App Store Connect CLI), fastlane (app creation only), uv, git, maestro + Java 17+ + maestro-live (end-to-end flows, Viewer).

build_xcode_versionA

Return the Xcode version (the first validation tool of the build_* group).

build_list_simulatorsA

List the available iOS simulators (iPhones are surfaced first).

build_boot_simC

Boot the simulator and open Simulator.app.

build_screenshotC

Capture a screenshot from the booted simulator → out_path (PNG).

build_for_simC

Build the project for the simulator (verification). project = .xcodeproj/.xcworkspace path.

build_testC

xcodebuild test (on the simulator).

maestro_testA

Run the app's Maestro flows (.maestro/) on the booted simulator through tools/maestro-live: it starts maestro mcp, opens the Maestro Viewer (http://localhost:7777, or the next free port) in the browser so the founder watches the run live, and runs each flow with the MCP run tool. Returns pass/fail per flow (JUnit also in build/maestro/report.xml). tags: comma-separated include filter, e.g. "smoke". The app must already be installed (build_for_sim + simctl install). Writes .appfactory/verify/maestro.json: the features gate and testflight_ship require every smoke flow green. There is no headless option here: the Viewer is mandatory on the Mac.

build_archiveC

xcodebuild archive (generic iOS) → .xcarchive.

build_export_ipaC

xcodebuild -exportArchive → .ipa.

supabase_list_projectsB

List Supabase projects (LIVE).

supabase_list_orgsA

List Supabase organizations (org_id for project creation).

supabase_get_keysB

Get the project's url + anon key (anon→app). The service_role key is never returned to the agent; it is saved to ~/.appfactory/supabase/.json (0600) for server-side use.

supabase_run_sqlB

Run SQL on the project (schema/migration) — LIVE write, human approval. Destructive statements (DROP, TRUNCATE, ALTER … DROP, GRANT/REVOKE on auth, DELETE/UPDATE without WHERE) always need approval.

supabase_set_secretB

Write an edge function secret (FAL_KEY etc.) — server-side, never enters the app. Human approval.

supabase_create_projectA

Create a new Supabase project (LIVE — provisions resources). Human approval.

app_scaffoldA

Scaffold a new SwiftUI app from app.spec.json (+xcodegen) and init the pipeline manifest.

spec: optional full spec dict, a dict of overrides on the defaults, or a path to an app.spec.json; otherwise the defaults for name/bundle_id. The spec is written to the app dir and drives products, StoreKit file, placements, locales, onboarding length, monetization mode (subscription strips the credit economy) and the Supabase backend mode.

github_create_repoB

Open a PRIVATE GitHub repo under the configured GitHub account (github_user, else the active gh login) + push.

dry_run=True (default) returns the exact command without running it; a live run needs human approval.

github_pushB

Commit + push changes (regular tracking). Human approval.

firebase_setupB

Set up Firebase Analytics (MANDATORY for every app): GCP project + iOS app + GoogleService-Info.plist → Resources/. Fully automatic (gcloud authed + firebase-tools). Live event tracking (from the phone).

app_inject_configB

Fill in the scaffolded app's AppConfig + StoreKit tokens.

paywall_strategy: "hard_only" (hard paywall only) | "hard_and_offer" (default, hard paywall + a discounted offer paywall on dismiss). Credit fields fall back to defaults if omitted (15/10/10/30/60) — credit pack amounts must be kept in sync with the server-side ai-proxy PACK_MAP.

onboarding_planA

Return guidance for onboarding step-count selection (does not generate code).

Usage: call this tool to ask the user how many onboarding steps they want, show the returned guidance, let them choose. Then during scaffold, the OnboardingStep array in Views.swift is written by hand with the chosen count and app-specific content (following the per-screen Claude Design boards) — this tool just clarifies the decision point and doesn't modify files.

STANDARD: onboarding is a quiz-style Q&A with ~5 personalization questions (OnboardingStep.kind=.question), so new apps match that count (~5), not "at least one".

animation_fetch_recolorA

Fetch a CUTE app-specific Lottie animation + recolor it to the palette → Resources/Animations/.json.

Source: the free LottieFiles library (Simple License = commercial OK, no attribution). The most-viewed match is picked and its colors are mapped to the app palette (dominant→primary, others→accent, black/white kept). Build-time recolor — NO runtime color code in Swift; lottie-spm renders it with .named(slot). slot: loading | success | empty | onboarding_hero. keyword: app-themed override (e.g. 'happy dog celebration'). primary_hex/accent_hex: DS.Palette light hex ('#' optional, e.g. '006A63'). Called for every slot of every app.

metadata_checkB

Validate apple-metadata.md (fields + character limits). No writes.

metadata_exportB

apple-metadata.md → fastlane/metadata//*.txt (validated).

If app_dir is given the ASO gate applies: export is refused until ASO is complete. primary/secondary_category = appCategories id (e.g. PHOTO_AND_VIDEO, PRODUCTIVITY) → written to the root *.txt files; deliver_metadata pushes them to ASC. Photo/portrait app default: PHOTO_AND_VIDEO+PRODUCTIVITY.

aso_check_nameA

Is the App Store name (globally unique) available — iTunes Search exact-name collision. Call BEFORE asc_create_app.

aso_find_available_nameC

Pick the first AVAILABLE App Store name from the candidates (a taken name gets the submit rejected).

aso_fetch_competitorsC

Fetch competitor apps via iTunes Search (LIVE, read-only).

aso_top_grossingA

Top-grossing apps (revenue proxy) — proven-idea hunting. genre: any App Store category name from aso.GENRES (books, business, developer_tools, education, entertainment, finance, food_drink, games, graphics_design, health, lifestyle, medical, music, navigation, news, photo_video, productivity, reference, shopping, social, sports, travel, utilities, weather) or its genre id; None = overall chart. An ignored genre filter returns ok:False, never the overall chart.

aso_search_hintsA

App Store autocomplete = REAL search demand (free, no auth). IDEA-STAGE HARD GATE.

Returns suggestions in Apple's own popularity order. 0 suggestions for a real term = no demand → REJECT the idea. expand=True appends a–z to the seed and collects the keyword universe (ASO keyword research). An endpoint error returns ok:False (NOT an empty list) — a broken endpoint must not be read as 'no competitors'.

aso_niche_scoreA

Idea go/no-go score: demand + competitor weakness + saturation penalty + monetization (0-100).

HARD GATE: 0 autocomplete suggestions = REJECT. Competitor metrics from iTunes Search top 50 (country PINNED — userRatingCount is per storefront). Saturation penalty: the score drops if the median competitor is strong. genre: any App Store category (aso.GENRES) — the category's AI density is INFORMATIONAL only (AI is an optional edge, never required nor penalized; not part of the score). verdict: GO(≥60) | MAYBE(≥40) | WEAK | REJECT(median>50k or no demand).

idea_harvestA

Phase 0 idea harvest across EVERY App Store category and storefront (not only AI/photo apps).

Sweeps top-grossing + top-free (legacy RSS) per genre × storefront (default us, gb, de, br, tr, jp, fr; genres None = all 24 charted categories), dedupes, enriches via iTunes lookup (release date, ratings, price) and returns chart_proven (top-grossing), rising_newcomers (released ≤ newcomer_months, sorted by ratings/day) and per-genre clusters (open_niche: open|some|closed|unmeasured). Read-only, free, paced (~0.3 s/request; a full default sweep takes ~1.5 min). A failed feed is listed in failed_feeds (ok:False) — never read as "no apps". exclude_terms drops the founder's own apps (name/seller match).

idea_evaluateC

Evidence bundle to rank one idea (any category): autocomplete count, niche score/verdict, two-window newcomer traction (12 + 6 months), leaders with price ladders, ai_needed (yes|optional|no heuristic + claude_assessment for Claude to set), build_complexity (low|medium|high vs the template), review_risk by genre/term, and the first available name from name_candidates. genre None = inferred from the competitors.

aso_competitor_iapA

Competitor's subscription/IAP price ladder (from the App Store product page). Input to the pricing decision.

iTunes lookup does not expose IAPs; the product page embeds them. app_id = iTunes trackId (returned by aso_fetch_competitors). FRAGILE (undocumented): on failure ok:False + prices:None — ABSENCE means 'unknown', NOT 'free'.

aso_unit_economicsB

Unit economics: credit count × AI cost vs subscription revenue → margin, break-even, warnings.

Grounds the price + credit decision in data at the idea/scaffold stage (the yearly_credits/weekly_credits passed to app_scaffold are validated here). apple_cut: Small Business 15% (default), otherwise 0.30.

aso_scaffold_outputsC

Create the outputs// skeleton (including apple-metadata.md, 32 languages).

aso_validate_metadataC

Validate outputs//02-metadata/apple-metadata.md.

aso_runC

Start the ASO stage (mandatory step): outputs skeleton + skill instructions.

aso_completeA

Validate the ASO output + mark the 'aso' stage done (opens the metadata/deliver gate).

icon_installB

Install the Claude Design app icon: the 1024×1024 master exported from B01-AppIcon.dc.html (design_export_png → design/icon.png), already uploaded + recorded (design_record_upload) → AppIcon.appiconset (alpha flattened) + .appfactory/verify/icon.json (the icon gate requires it).

icon_generateA

OPT-IN ONLY (spend → approval): fal raster DRAFT → design/icon_drafts/ as reference for the Claude Design icon board. Never installs an icon — the shipped icon comes from Claude Design (icon_install).

localize_applyB

Merge translations into the in-app String Catalog for the spec's locales.app (translations = {english_key: {locale: value}}; other locales are ignored).

pipeline_statusC

App pipeline status: which stages are done/pending, and what comes next.

pipeline_nextA

Return the next mandatory step + its instructions (driver). Refuses until the run options are confirmed (run_options → run_options_save) unless skip_options_check=true. Returns setup_required first when AppFactory is not set up yet.

pipeline_markC

Mark a stage (done/in_progress/pending).

pipeline_validateA

Run a stage's enforced gate WITHOUT modifying the manifest.

For orchestrator/subagent self-checks: does the gate pass before marking it 'done'?

orchestrator_preflightB

Pre-flight for an autonomous run: run options confirmed + config keys + fastlane session freshness + caffeinate command. Ready if blockers is empty. Returns setup_required first when AppFactory is not set up yet.

orchestrator_next_actionA

Next action for the driver loop: stage + subagent role + retry budget + instructions. done=True means the pipeline is finished (submit needs human approval). Refuses until the run options are confirmed unless skip_options_check=true; setup_required comes first.

run_optionsA

Every optional part of a run (services, monetization, trial, paywalls, onboarding quiz, mascot, languages, store locales, screenshots, preview video, CPPs, analytics, ratings, HealthKit, Sign in with Apple, GitHub issues, e2e smoke tests…) with its question, kind, choices, default and current value. Ask the user each question one at a time (or as a compact checklist if the agent supports multi-select), then call run_options_save. Call this BEFORE any other work when the user says run.

run_options_saveA

Save the user's answers ({option id: value}, every id from run_options). Validates types, choices and dependencies; services go to config.toml, the rest to app.spec.json (app_dir) or to a pending file app_scaffold applies. Records options_confirmed.

orchestrator_record_attemptB

Count a failed attempt of a stage (after a gate failure). Returns: {stage, attempts, should_retry}.

orchestrator_needs_humanB

Self-correction exhausted: write NEEDS_HUMAN.md and return its path.

screenshot_captureB

Raw capture from the booted simulator → marketing/raw//.png.

screenshot_brandA

Branded App Store screenshots via the node compositor, rendering the Claude Design store layout (run screenshot_apply_layout first; screenshot_build_all does both).

screenshot_apply_layoutC

Merge the Claude Design store layout (design/project/store_layout.json, the ST0N boards) into marketing/screenshots/config.json so the compositor renders the approved layout for every locale.

screenshot_syncD

branded → fastlane/screenshots//.

screenshot_build_allB

MANDATORY turnkey screenshot step (UI-test style, all apps): generate a sample image → build+install → localized captions from the catalog → capture 32 languages × 6 rich screens (onboarding/create/ result/gallery/paywall/settings) → brand → sync to fastlane/screenshots. sample_prompt: a sample prompt for what the app produces (fills Result/Gallery with real output).

screenshot_generate_sampleC

Generate a sample image with fal.ai → Resources/sample_headshot.jpg (enriches Result/Gallery).

screenshot_onboarding_heroesA

LEGACY, OPT-IN ONLY: fal hero images per onboarding step (onb_step0..N). Onboarding visuals are designed in Claude Design (design/screens.json boards); use this only for a legacy hero-image onboarding.

growth_build_slideshowsA

Render viral TikTok/Reels slideshows (SlideSmith pattern, free, no scheduling). CLAUDE writes the hooks/slide text; images are generated with the app's AI (fal). slideshows=[{name, slides:[{text, image_prompt? or image?, cta?}]}]. Output 1080x1920, marketing/growth//NN.png — ready to share. A step for AFTER the app is submitted.

preview_briefC

Write marketing/preview/BRIEF.md — the HyperFrames brief (destination: app-store-preview) for this app's App Preview, from app.spec.json (size, fps, duration, poster, locales and shares), and create marketing/preview/recordings//. Then record the real app (Scripts/sim_store_prep.sh, then xcrun simctl io <udid> recordVideo) and author the video with the hyperframes skill: real footage only, motion graphics frame and highlight it.

preview_checkC

Offline readiness of the App Preview set: BRIEF, real recordings per source locale, one preview per spec.preview locale (or a documented share), every file 886x1920 / <=30 fps / H.264 / 15–30 s / <=500 MB / stereo AAC or silent (ffprobe), plus the self-review status and deterministic rendering.

preview_review_sheetsA

Self-review material for every final preview (ffmpeg): a contact sheet (fps=2, 270 px, 6x5), a phone-size sheet (fps=1, 360 px, 5x3) and a 12-frame strip around the fastest transition, in marketing/preview/review//. Open them and score with preview_review_log.

preview_review_logA

Log one self-review round of a final preview (file relative to the app): scores 1–10 for hook, readability, motion, variety, brand, music; while any is under 8, the 3 worst problems with timestamps [{t, issue}]. Fix, re-render, re-review until every score is 8+ on the exact final file (MD5-matched) — preview_upload and the gate refuse otherwise.

preview_uploadA

Upload fastlane/app_previews// to the editable version's IPHONE_67 preview sets through the asc CLI (shares from spec.preview.shared resolved, poster time code from the spec, MD5-idempotent). dry_run=True (default) sends nothing; a live upload needs human approval; refuses while preview_check has problems.

cpp_build_allB

Create one CPP per Search Ads theme (create→version→localization) + return the deep-link URLs. themes=[{name, locale?}] from the theme/keyword clusters in the ASO output. The URLs feed Ad Ops. LIVE writes: human approval.

deliver_metadataC

Upload metadata to the ASC draft — DIRECT API (bypasses the fastlane 'No data' bug). ASO-gated.

deliver_screenshotsA

Upload screenshots to the ASC draft — checksum-based INCREMENTAL sync (NOT fastlane). Skips when local MD5 == ASC sourceFileChecksum; uploads only missing/changed ones → fast + reliable (fastlane was randomly dropping images). Gated on screenshots: run screenshot_build_all first.

deliver_screenshots_auditA

Read-only screenshot readiness audit: per locale and display type (iPhone 6.9" = APP_IPHONE_67, Watch = APP_WATCH_ULTRA) the ASC set holds exactly the local fastlane/screenshots files, in order, all COMPLETE, each with the local file's MD5; lists the preview sets. Run after deliver_screenshots and before submission. No writes.

deliver_subscription_review_screenshotsA

Upload the App Review screenshot of every subscription from store/review-screenshots/.png (hard paywall with real sandbox prices for the default offering, the offer paywall for offer products). Without it a subscription stays MISSING_METADATA. Idempotent by MD5. Human approval.

testflight_shipA

End-to-end TestFlight: distribution signing → archive → App Store profiles (the app and every extension in project.yml, exact bundle-id match, created right before export so Xcode's profile sweep cannot delete them) → manual-signing export → asc builds upload. Refuses unless the Maestro smoke flows passed (maestro_test; n/a when the e2e_smoke run option is off). No system keychain password (temporary keychain). Never submits to App Store review — it only uploads a TestFlight build.

signing_setup_distributionC

Create a distribution cert + install it into a temporary keychain (WWDR included). {cert_id, identity, keychain}.

signing_create_profileC

Create an IOS_APP_STORE provisioning profile + write it to the standard locations.

ai_configureC

AI provider/model selection (for now fal.ai/Flux schnell — the cheapest).

ai_deploy_proxyC

Deploy the AI backend. With app.spec.json in subscription mode this is backend_deploy (the full function set + migrations + secrets + auth); credits mode keeps the legacy ai-proxy deploy. AI keys go only to server-side secrets. LIVE side effects: human approval.

revenuecat_setupA

Idempotently set up the RC v2 project: entitlement(premium)+4 sub attach+SDK key+secret.

A human creates the RC project + links ASC + provides the v2 key; the rest is automatic. Preflight returns NEEDS_HUMAN if there is no project. env_suffix for apps sharing one Supabase (e.g. _MYAPP). LIVE RevenueCat writes: human approval.

backend_renderA

Make the scaffolded backend follow app.spec.json (offline, idempotent): prune supabase/ to the monetization mode, render functions/_shared/app.gen.ts + config.toml (Apple client id) + the CONTRACT.md quota block, resolve/fill the legal sources, and sync listing.json locales/legal URLs.

backend_deployA

Deploy the spec's Supabase backend (LIVE unless dry_run): migrations (tracked), secrets (AI_MODEL, AI_FALLBACK_MODEL, caps, REQUIRE_CONSENT, RC_PROJECT_ID from app outputs, RC_SECRET_KEY

  • FAL_KEY from config — reported by name only), auth (anonymous + Sign in with Apple + manual linking), legal build, and the function set (analyze, usage-status, delete-account, legal, rc-webhook). dry_run=true (default) returns the plan without any call; a live deploy needs human approval.

legal_renderB

Fill the legal sources (store/privacy/*.md, backend/PRIVACY.md) from the spec + config (APP_NAME, CONTROLLER, SUPPORT_EMAIL, dates, trial/plan sentences) and keep/drop the

legal_checkC

What still blocks publishing the legal pages (placeholders, unrendered blocks, missing languages).

legal_verifyB

LIVE read-only: every privacy/terms page per app language answers 200 in that language with the support email and no placeholder.

store_setupA

Idempotent App Store Connect + RevenueCat setup from app.spec.json + listing.json.

mode: plan (offline) | check (live reads, simulated writes; reports CONFLICT) | apply (live writes; human approval via appfactory approve <id>). target: capabilities | asc | rc | all. Order: App ID capabilities FIRST, then ASC (grace period, group + localizations, products + localizations, availability before prices, equalized USA prices, price overrides, per-territory intro offers for trial products and none for offer products, age rating, review contact, app info/version localizations + legal URLs, SKU check, Server Notifications V2 URL), then RevenueCat (project, app, products, entitlement, offerings/packages, targeting-rule placements; MCP plan when REST refuses). rc_apple_notification_url: the RevenueCat dashboard's Apple Server-to-Server URL (stored in app outputs).

metadata_listing_checkC

Validate store/metadata/listing.json: name/subtitle ≤30, keywords 95–100, promo ≤170, no word overlap across fields or cross-indexed storefronts, description ends with the subscription disclosure + Terms + Privacy links (Supabase legal, ?lang=), IAP display copy.

metadata_render_listingC

Sync listing.json to the spec (store locales, IAP copy slots) and fill the legal URLs.

pricing_unit_economicsB

Unit economics from the MEASURED AI cost per call (latest backend/eval/results for spec.ai.model, or explicit cost_photo/cost_text) × usage profiles up to the daily caps, per product; writes the generated blocks of store/pricing.md (decisions, unit economics, ASC/RC layout, local prices, anchor).

asc_sbp_checkB

Small Business Program proof: latest SUBSCRIPTION/SUMMARY sales report (gzip TSV) → US proceeds/price ratio (≈0.85 SBP, ≈0.70 standard). Needs a Finance-role key: asc_finance_key_id + asc_finance_key_filepath (+ asc_vendor_number); 403 → clear error.

storekit_generateA

Write Resources/Configuration.storekit from the app's app.spec.json (group, levels, free-trial intro offers, trial-less offer product, en_US). Deterministic; run after any product change.

storekit_parityA

Compare a Configuration.storekit with app.spec.json; returns every mismatch (price, period, level, intro offer, missing/extra product, group, locale). ok=true means in parity.

app_sync_specB

Re-generate AppSpec.swift, PaywallSource.swift and Configuration.storekit (and prune the String Catalogs to locales.app) after editing app.spec.json.

design_screens_skeletonA

STRUCTURAL skeleton for design/screens.json: with a design brief, the onboarding follows the brief's onboarding.flow (stubs for kinds the default funnel lacks) and carries brief_sha256; without one, the default honest funnel. Rules stay: no fake stats/reviews, spin wheel, rating or notification prompt. ADAPT EVERY SCREEN to the app and the brief — the look is authored in Claude Design, not here. write=True saves it to /design/screens.json (refuses to replace an existing file unless overwrite).

design_research_collectB

Design research: the category leaders across storefronts (iTunes Search for terms + the genre's top-grossing/top-free charts, looked up for screenshots/artwork) → downloads their App Store screenshots and icons to design/research/apps/-/ + references.json. Study material only (never uploaded).

design_research_brief_templateC

The design/research/brief.json shape (pre-filled with the reference ids): purpose, analysis, and a direction per section (palette tokens, typography, components, density, illustration, onboarding flow, paywall, screenshots analysis + concept + boards), each citing references and what it does differently.

design_research_checkB

The design_research gate: ≥6 reference apps with icon + screenshots on disk, and a valid brief (every section cited, screenshot concept citing ≥4 competitor sets, palette/type not the template defaults or another factory app's).

design_generateA

Prepare the app's Claude Design project (the factory's ONLY design source) from the design brief, app.spec.json and design/screens.json. Writes STRUCTURAL scaffolds to design/scaffold/ (every screen incl. paywall/offer, the B01-AppIcon slot, one ST board per brief screenshot board) and into design/project/ the mascot motion boards, canvas.json, store_layout.json and upload_plan.json (plan.authored = boards Claude must author in Claude Design from the brief). Refuses without valid research/brief or when screens/tokens are not derived from the brief. Returns the claude-design MCP calls; this tool never uploads.

design_record_uploadA

Record a finished Claude Design upload: SHA-256 of every file in upload_plan.json → design/project/claude_design.json. open_url = the claude.ai/design link from render_preview (never the serve_url). The design, icon and screenshots gates fail until this receipt exists and matches the files.

design_upload_statusC

Is the local Claude Design project uploaded and unchanged since (the check every design gate runs)?

design_export_pngA

Rasterize a Claude Design board with local headless Chrome (not Claude in Chrome). serve_url comes from mcp__claude-design__render_preview and is used once, never stored. Icon: B01-AppIcon, 1024×1024 → design/icon.png. Store layout check: an ST0N board at 440×956, scale=3 → 1320×2868.

mascot_blinkA

Closed-eye copies of the APPROVED pose PNGs (-blink.png next to each): iris blobs in the upper 55 %, inpainted with the surrounding color, closed-lid arcs. Default input: /design/mascot/.png. Needs the optional extra: uv sync --extra mascot. Never rig from a separate parts sheet.

mascot_assetsB

Import approved poses + blink variants into Resources/Assets.xcassets/Mascot/{,-blink}.imageset (namespaced → Image("Mascot/idle")); states without a pose borrow a fallback pose.

team_briefC

Render docs/TEAM.md, docs/team/{ios,backend,store}.md, docs/onboarding-plan.md (from design/screens.json), store/aso-research.md and docs/CHECKLIST.md from the spec. sessions: {lead, ios, backend, store} names.

github_issues_bootstrapA

Create/refresh the label set (ios, backend, store, lead, founder, next, later, other-project) on /, gh runs as the configured GitHub account. dry_run returns the commands; live: human approval. n/a (nothing runs) when the user turned off the github_issues run option (pass app_dir to read it from the spec).

github_issue_createA

Open an issue for postponed work: imperative title, a role label (+ next|later), body with what/why/done-when. Runs gh as the configured GitHub account. dry_run returns the exact command; live: human approval. n/a (nothing runs) when the user turned off the github_issues run option (pass app_dir).

playbookA

Return the AppFactory run playbook (markdown). Read it before driving the pipeline.

Prompts

Interactive templates invoked by user choice

NameDescription
setupSet up or change AppFactory: choose services and enter keys.
runRun the AppFactory pipeline end to end (idea → TestFlight) following the playbook.

Resources

Contextual data attached and managed by the client

NameDescription
playbook_resourceThe AppFactory run playbook (markdown).

TDQS

C2.7/5.0

Scored across 125 tools

Disambiguation3/5

The server covers many pipeline stages with explicit markers (MANDATORY, OPT-IN, LEGACY, LIVE) and cross-references between descriptions, which helps distinguish most tools. However, several clusters overlap: pipeline_next vs orchestrator_next_action, pipeline_status vs orchestrator_preflight, setup_set vs config_set, metadata_check vs metadata_listing_check vs aso_validate_metadata, and deliver_* vs *_sync variants, creating genuine ambiguity for an agent.

Naming Consistency4/5

Almost all tool names are snake_case with a domain prefix plus action (asc_*, aso_*, build_*, supabase_*, screenshot_*, design_*, etc.), which is highly consistent within groups. Minor deviations exist: some top-level tools lack a clear domain prefix (deliver_metadata, run_options, playbook) and a few are noun phrases (pricing_unit_economics, team_brief), but there is no camelCase or chaotic mixing.

Tool Count1/5

125 tools is an extreme mismatch for a single server. Even a complex app-factory pipeline likely could consolidate many single-step tools (especially the numerous ESC/design/screenshot/preview stages) into fewer, more purposeful operations.

Completeness4/5

The surface is extensive, covering idea/ASO research, scaffolding, design, backend, signing, TestFlight, metadata, screenshots, previews, legal, GitHub, and App Store submission. Some gaps remain (no update/delete for several managed resources, limited post-submission monitoring, minimal GitHub PR support), but for the stated pre-submission factory pipeline it is largely complete.