Skip to content
Getting started

AI recommend + apply

Retrieve catalog matches, save a recipe and review provider setup. Optional wiring attempts are not accepted production rotation.

Why this exists

Picking the right providers is the first friction point in a new project. Stack's catalog has 39 curated providers across 13 categories — too many to hold in your head, too few to outsource to a generic LLM. stack recommend closes the gap: free-text in, ranked providers out, frozen to a reproducible Recipe that stack apply can replay.

Retrieval-first, not LLM-first. Ranking runs through a zero-dep BM25 + IDF scorer over the curated catalog. Claude Code (via MCP) or a local SLM can rewrite rationales — but the shortlist is deterministic and offline.

Quick start

Save a recommendation, review it, then authorize setup in the intended directory:

stack recommend "B2B SaaS with auth, AI, and payments" --save
# → .stack/recipes/b2b-saas-with-auth-ai-and-paymen.toml

stack apply b2b-saas-with-auth-ai-and-paymen

Two modes

Default recommendation is retrieval-only. Optional synthesis can contact the configured HTTP endpoint; a local default does not constrain overrides.

Mode When it fires What does the reasoning
Claude Code (MCP) You're in a Claude / Cursor / Windsurf session and the agent calls stack_recommend. Claude consumes Stack's retrieval output as grounded context and may write its own rationale. The MCP wrapper returns CLI text; the external agent has its own provider settings.
Standalone CLI (local SLM) You run stack recommend --synth in a terminal, no agent attached. Stack speaks OpenAI-compatible HTTP to LM Studio (:1234) or Ollama (:11434). Missing endpoint? Falls back to retrieval-only output — command still exits 0.

stack recommend

Rank providers against a free-text description. Flags compose.

Flag Type What it does
--save boolean Freeze the result as .stack/recipes/<id>.toml. The id is slugified from the query. Feed it to stack apply.
--synth boolean Call the configured HTTP endpoint for model-authored rationales. Defaults are local; endpoint overrides may be remote. Inference failure can fall back to retrieval-only output.
--json boolean CLI JSON output; the MCP wrapper carries this inside text content.
--k number Max hits to return. Default 6.
--category string Restrict to one category: Database, Deploy, Cloud, AI, Analytics, Observability, FeatureFlags, Errors, Payments, Code, Tickets, Email, Auth.

Default output

Illustrative output and scores; actual matches depend on the current catalog. Retrieval scores are not measured provider quality.

$ stack recommend "B2B SaaS with auth, AI, and payments"

┌   stack recommend
  query: B2B SaaS with auth, AI, and payments

  ● Clerk  Auth  (4.13)
    Drop-in auth + users. Secret key stored in Phantom.
    add with: stack add clerk

  ● Stripe  Payments  (3.70)
    Billing, subscriptions, tax. Restricted / test-mode secret key stored in Phantom.
    add with: stack add stripe

  ● xAI  AI  (2.90)
    Grok + tool use. Key verified on paste.
    add with: stack add xai

  ● Sentry  Errors  (2.48)
    Error + performance tracking. Attaches to an existing project and reads its DSN when available.
    add with: stack add sentry

  ● OpenAI  AI  (2.23)
    GPT, Realtime, embeddings. Key verified against /v1/models on paste.
    add with: stack add openai

  ● Anthropic  AI  (2.23)
    Claude models + MCP. Key verified against the Messages API on paste.
    add with: stack add anthropic

  Top pick per category: Auth→clerk, Payments→stripe, AI→xai, Errors→sentry.
  No matches surfaced for: Database, Deploy, Cloud, Analytics, Code, Tickets, Email.
  Apply a chosen set with: stack add clerk && stack add stripe && stack add xai (one command per service).

  Tip: rerun with `--save` to freeze as a recipe for `stack apply`.
│
└  Tell Claude or run `stack add <name>` to continue.

--save — freeze to a Recipe

$ stack recommend "B2B SaaS with auth" --save

  ● Clerk  Auth  (4.13)
  ● Sentry  Errors  (2.48)
  ● Supabase  Database  (2.16)
  ● Firebase  Database  (2.16)
  ● Turso  Database  (0.79)

  Saved recipe: b2b-saas-with-auth   (/path/to/.stack/recipes/b2b-saas-with-auth.toml)
  Apply with:  stack apply b2b-saas-with-auth

--synth — local-SLM rationales

With LM Studio or Ollama running, each hit gains a why: line authored by the model. Without either, the command can fall back to retrieval-only output. Other I/O or setup errors remain possible. Illustrative synthesis output:

$ stack recommend "analytics + error tracking for a Next.js app" --synth

  ● PostHog  Analytics  (5.01)
    Product analytics + session replay. Personal API key stored in Phantom.
    why: PostHog gives you funnels, flags, and replay for a Next.js app in one SDK.
    add with: stack add posthog

  ● Sentry  Errors  (4.77)
    Error + performance tracking. Attaches to an existing project and reads its DSN when available.
    why: Sentry captures unhandled exceptions and Web Vitals without extra glue.
    add with: stack add sentry

--json — machine-readable

This is illustrative CLI JSON, not the outer MCP text envelope. The example fields and scores are not a live acceptance receipt:

{
  "query": "B2B SaaS with auth and payments",
  "hits": [
    {
      "name": "clerk",
      "displayName": "Clerk",
      "category": "Auth",
      "authKind": "api_key",
      "secrets": ["CLERK_SECRET_KEY"],
      "blurb": "Drop-in auth + users. Secret key stored in Phantom.",
      "score": 4.125,
      "matched": ["auth"]
    },
    {
      "name": "stripe",
      "displayName": "Stripe",
      "category": "Payments",
      "authKind": "api_key",
      "secrets": ["STRIPE_SECRET_KEY"],
      "blurb": "Billing, subscriptions, tax. …",
      "score": 3.697,
      "matched": ["payments"]
    }
  ],
  "byCategory": { "Auth": [{ "name": "clerk", "score": 4.125 }], "…": [] },
  "guidance": "Top pick per category: Auth→clerk, Payments→stripe. …"
}

--k — cap the hits

$ stack recommend "postgres database" --k 3

  ● Neon  Database  (5.76)
    Serverless Postgres. Creates a project and pools the connection string.
  ● Supabase  Database  (5.49)
    Postgres + Auth + Storage. Full upstream provisioning via the Management API.
  ● Turso  Database  (4.35)
    Edge SQLite (libSQL). Creates a database in your default org.

--category — restrict to one category

$ stack recommend "serverless" --category Database

  ● Neon  Database  (5.76)
    Serverless Postgres. Creates a project and pools the connection string.
  ● Turso  Database  (2.18)
    Edge SQLite (libSQL). Creates a database in your default org.

stack apply

Replay a saved Recipe through the existing stack add pipeline, then check which declared secrets are in the Phantom vault. Setup may create or attach resources and write credentials/config; the vault check only reads names, and webhook stubs are not verified handlers.

# Illustrative replay; inspect actual setup and optional wiring results
$ stack apply b2b-saas-with-auth

  recipe   b2b-saas-with-auth
  query    B2B SaaS with auth
  providers clerk, sentry, supabase

  › stack add clerk
  › stack add sentry
  › stack add supabase

  secrets in vault 7 · missing 1 · webhooks 2
  (not in Phantom: SENTRY_AUTH_TOKEN — store with `phantom add <NAME>`)

  › stack doctor
  ✓ b2b-saas-with-auth applied.
Flag What it does
--noWire Skip the Phantom-wire layer — pure stack add replay, no vault check or webhook stubs. Provider setup and credential/config writes still occur; this flag is not a dry run.
--noRollback Skip the multi-service cleanup attempt after partial failure. Existing provider resources, credentials or partial writes may remain; this flag is not a dry run or a guarantee about upstream deletion.

What gets wired

After setup succeeds for an entry, the default flow can attempt these steps unless --noWire is set:

  • Phantom vault check — reads names from phantom list --json (never values) and lists each declared secret as in the vault or missing. It never writes to the vault; store missing values with phantom add <NAME>.
  • Webhook stubs — scaffolded verification + handler files for selected providers in the helper: stripe, clerk, supabase, github. Implement and verify handlers in the app before using them; generated comments are not signature verification.
  • Inline stack doctor — runs at the end so you can inspect available checks. It is informational and not an all-services-success gate for apply.
Inspect before replay. Existing services can be skipped, but partial provider, credential or optional wiring effects may remain. Re-running stack apply is not a universal safe-retry guarantee.

MCP tools

Both commands are exposed as MCP tools so Claude Code (and any MCP-speaking editor) can request these operations when its actual tools and project context are configured. See the full MCP integration docs for setup.

stack_recommend stack recommend …

Retrieval-only. Returns ranked providers with scores, matched terms, and per-category top picks. Pass save: true to also freeze a Recipe to disk so you can follow up with stack_apply.

Input Type Description
query req string Free-text description of the project.
k number Max results (default 6).
category string Restrict to one category.
save boolean Freeze to .stack/recipes/<id>.toml; returns the recipe id.
stack_apply stack apply …

Replay a saved Recipe. Runs stack add for each provider, then checks the Phantom vault and writes webhook stubs. The returned text can include failures; setup and cleanup are not atomic.

Input Type Description
recipe_id req string Recipe id (filename stem in .stack/recipes/).
no_wire boolean Skip the Phantom vault check and webhook stubs.

In-session example

Illustrative conversation, not a recorded customer or provider outcome:

You > Build me a SaaS — auth, payments, error tracking, Postgres.

Claude > I'll pick the providers first and freeze a recipe so you can
         replay this.
         (calls stack_recommend { query: "SaaS with auth, payments,
          error tracking, and Postgres", save: true })

         Top picks: clerk (Auth), stripe (Payments), sentry (Errors),
         neon (Database). Saved as recipe "saas-with-auth-payments-error".

         Want me to apply it now? This runs `stack add` for each and
         checks which secrets are already in Phantom.

You > Yes.

Claude > (calls stack_apply { recipe_id: "saas-with-auth-payments-error" })

         Setup report: inspect added, skipped and failed entries.
         Optional wiring counts and doctor checks need separate verification.

Recipe file format

Recipes are plain TOML under .stack/recipes/<id>.toml. Recipes can include the original query and freeform rationales. Review them before sharing; dedicated credential persistence uses Phantom.

id = "b2b-saas-with-auth"
query = "B2B SaaS with auth"
createdAt = "2026-04-19T02:22:44.810Z"
guidance = "Top pick per category: Auth→clerk, Errors→sentry, Database→supabase."

[[providers]]
name = "clerk"
rationale = "auth"

[[providers]]
name = "sentry"
rationale = "auth"

[[providers]]
name = "supabase"
rationale = "auth"

The id is the first ~40 chars of the query, slugified. The rationale starts as the matched terms from retrieval and gets may be updated when an authorized synthesis result is saved. An agent writing prose externally does not itself rewrite the stored recipe.

How retrieval works

Zero-dep BM25 + IDF scorer over the curated provider catalog, with a small table of hand-authored synonyms (db → database, billing → payments, auth → users, …) so natural-language queries map to the terms we actually index. Scoring is deterministic — same query, same ranking. The catalog itself lives in packages/core/src/catalog.ts and is the same source the providers page renders from.

FAQ

Can I use my own LLM?

Yes. Set STACK_LM_URL to any OpenAI-compatible endpoint. Stack talks plain HTTP to LM Studio (localhost:1234) and Ollama (localhost:11434) by default. An override may contact another host; verify its access and privacy requirements.

Does anything call Anthropic or OpenAI?

Default retrieval uses no model. Optional synthesis can contact a configured endpoint, while the external coding agent has its own provider settings. Absence of an SDK is not a no-network proof.

What if the SLM isn't running?

--synth silently falls back to retrieval-only output. The ranking remains retrieval-based, and --save can persist the recipe. Endpoint fallback does not rule out other I/O errors or guarantee an exit code of 0.

What now?