Use get_stack when the user describes a product or system and the agent needs to propose a coordinated set of tools — not a single pick. Each result is anchored to a layer (framework, database, auth, cache, …) and comes with a resolved version so the agent can write install commands directly.
When to use
- The user describes a product or feature ("I'm building a SaaS with billing") rather than a single-component need.
- You need mutually-compatible picks, not the best tool for one job.
- You want version numbers back so you can emit install commands.
For single-component lookups ("best ORM for TypeScript") use search_tools instead — it returns ranked options rather than a one-per-layer stack.
Input parameters
- Natural-language description of what the user is building. Example: "real-time chat app with auth and analytics".
- Optional per-layer search guidance. Prefer the structured object form —
{ sub_need_type, keyword_sentence }— for best results. Plain strings are accepted for backwards compatibility but are less precise. - Canonical layer identifier, e.g.
database,cache,queue,framework,orm,auth,payment,observability. Used to segregate candidates by role. - Comma-separated keywords describing this specific sub-need. Example: "sql, postgres, relational, ACID, transactions". The most impactful knob for per-layer precision.
- Optional global constraints applied across all layers.
- Primary programming language, e.g. "TypeScript", "Python", "Go".
- Preferred deployment style. Filters out incompatible layer picks.
- License class the project can tolerate.
- Max number of tools to return across all layers. Bounded 1–10.
use_casestringrequiredsub_needsArray<SubNeed | string>optionalsub_need_typestringrequiredkeyword_sentencestringrequiredconstraintsobjectoptionallanguagestringoptionaldeployment_model"serverless" | "self-hosted" | "managed" | "edge"optionallicense"permissive" | "copyleft" | "proprietary"optionallimitnumberoptionaldefault 5
The keyword-sentence pattern
Each sub-need carries its own short keyword_sentence that anchors the recommendation to what the user actually needs. Good sentences:
- Are 3–8 comma-separated keywords — not full English sentences.
- Mix generic category terms with specific signals (
sql, postgres, ACID). - Avoid vendor bias unless the user explicitly requested a tool.
Background: Keyword-Sentence Retrieval.
Example requests
{
"use_case": "full-stack web app with auth and payments",
"sub_needs": [
{
"sub_need_type": "framework",
"keyword_sentence": "react, full-stack, ssr, typescript, app-router"
},
{
"sub_need_type": "database",
"keyword_sentence": "sql, postgres, relational, type-safe"
},
{
"sub_need_type": "auth",
"keyword_sentence": "oauth, session, email-password, passkeys"
},
{
"sub_need_type": "payment",
"keyword_sentence": "stripe, subscriptions, webhooks, checkout"
}
],
"constraints": {
"language": "TypeScript",
"deployment_model": "serverless"
},
"limit": 4
}{
"use_case": "real-time chat application"
}{
"use_case": "data pipeline for ETL workflows",
"sub_needs": ["orchestration", "data warehouse", "transformation"],
"constraints": { "language": "Python" }
}Agent invocation
An agent calls get_stack as an MCP tool. The framework/runtime routes the call through to the ToolCairn server; you don't need to handle HTTP directly.
// Your agent's tool call
{
"tool": "get_stack",
"arguments": {
"use_case": "full-stack web app with auth and payments",
"sub_needs": [
{ "sub_need_type": "framework",
"keyword_sentence": "react, ssr, typescript" },
{ "sub_need_type": "database",
"keyword_sentence": "sql, postgres, type-safe orm" },
{ "sub_need_type": "auth",
"keyword_sentence": "oauth, session, passkeys" }
]
}
}Response
Each result carries layer, confidence, health_tier, and a resolved version object with registry metadata.
{
"use_case": "full-stack web app with auth and payments",
"tools": [
{
"name": "Next.js",
"layer": "framework",
"role": "Full-stack React framework with App Router",
"confidence": 0.94,
"version": {
"recommended": "15.1.6",
"latest": "15.1.6",
"registry": "npm",
"release_date": "2026-02-11",
"status": "stable"
},
"health_tier": "Thriving",
"rationale": "Top match on the framework layer; matches TypeScript + serverless constraints."
},
{
"name": "Prisma",
"layer": "database",
"role": "Type-safe ORM for TypeScript",
"confidence": 0.91,
"version": {
"recommended": "6.2.0",
"latest": "6.2.0",
"registry": "npm",
"release_date": "2026-01-28",
"status": "stable"
},
"health_tier": "Thriving",
"rationale": "Matches 'type-safe orm' keyword; companion edge to Next.js."
},
{
"name": "Auth.js",
"layer": "auth",
"role": "OAuth + session library for Next.js",
"confidence": 0.88,
"version": {
"recommended": "5.0.0-beta.29",
"latest": "5.0.0-beta.29",
"registry": "npm",
"release_date": "2026-03-04",
"status": "beta"
},
"health_tier": "Active",
"rationale": "Direct framework compatibility; satisfies passkeys + session keywords."
},
{
"name": "Stripe",
"layer": "payment",
"role": "Hosted payments with subscriptions + webhooks",
"confidence": 0.96,
"version": {
"recommended": "17.5.0",
"latest": "17.5.0",
"registry": "npm",
"release_date": "2026-03-20",
"status": "stable"
},
"health_tier": "Thriving"
}
],
"query_id": "q_01HW7FVX..."
}Version resolution
For every pick, ToolCairn resolves against the canonical registry for that tool (npm, PyPI, crates.io, Go modules, Maven, NuGet, and 29 others). The version object tells you:
recommended— latest stable release the graph has community-adoption signal for.latest— newest publish, which may be a pre-release.registry— which registry the package was resolved against.status— one ofstable,beta,pre-release,deprecated.
Errors
invalid_sub_need_type— thesub_need_typeis not in the canonical enum. See sub_need_type reference.no_candidates— no tools matched any layer. Usually indicates an overly narrowkeyword_sentenceor an impossible constraint.rate_limited— free tier exceeded. See Rate limits.
Related
refine_requirement— decompose a vague prompt into ready-to-usesub_needs.check_compatibility— verify two picks work together at specific versions.compare_tools— head-to-head comparison for a single layer.