Can Strands Decider 2B pick which Sume MCP tool to call?
Strands Decider 2B scores options you give it. Build them from Sume's tools_list, then check the pick with tools_schema and dry_run before any paid call.

Yes, as the step that chooses a tool name. Strands lists "model routing and tool selection" among the uses of Decider 2B on its launch post, and the model scores answers from a list that you provide. Sume's hosted MCP gives you that list: tools_list returns the tools that the current session can see, and tools_schema returns one tool's contract by name. The decision picks a name. It never replaces the schema read or the spend checks.
Turn tools_list into one choice question
The Hugging Face model card says that options go in as typed questions, for example --choice "question=option1,option2,option3", next to a state that gives the context. The card also warns that questions are read less than documents, so keep the option names short and make them the exact Sume tool ids.
Three steps, three owners
Keep the decision, the validation and the paid step apart. The table shows which Sume call belongs to which step.
| Step | Who decides | Sume call | Spends money? |
|---|---|---|---|
| Choose a tool name | Decider 2B | none | No |
| Read the contract | Your code | tools_schema with name | No |
| Preview the cost | Your code | dry_run=true on the paid tool | No |
| Submit | Your code, with idempotency_key | The paid tool, for example tts_create | Yes |
TOOLS = ["balance_get", "catalog_list", "generate_image", "tts_create", "music_create"]
PAID = {"generate_image", "tts_create", "music_create"}
def choice_question(question: str, options: list[str]) -> str:
return f'--choice "{question}={",".join(options)}"'
def accept(choice: str) -> str:
if choice not in TOOLS:
raise ValueError(f"not a tool in tools_list: {choice}")
return choice
print(choice_question("which tool answers the user", TOOLS))
name = accept("tts_create")
print(name, "needs a dry run first" if name in PAID else "is read-only")
Keep the option list live
Under OAuth mcp:read, the paid tools are hidden from the session, so the list that you give the model is already shorter. Build the options from the live tools_list of the session, not from a hardcoded copy, or Decider can choose a tool that the session answers with insufficient_scope.
Also reject any answer that is not in the list. A decision model scores the options that you give it, so the failure to guard against is a stale option list, not an invented tool.
Sources
Related posts
More in Developers
- Stripe allows 16 webhook endpoints; Sume takes a webhook URL per job
Stripe registers up to 16 endpoints. Sume has no registry: each job or Format run item carries its own public HTTPS webhook_url, signed with one secret.
- Stripe events arrive out of order; Sume sends only terminal job events
Stripe does not order events and says to dedupe on event ID. Sume sends only terminal job events keyed by job_id, so order rarely matters. Fetch state.
- Stripe retries webhooks for 3 days, Sume job webhooks for 4.5 minutes
Compare retry windows: Stripe live mode retries up to three days; Sume job webhooks use 10 attempts at 30s spacing. Size your poll fallback to the shorter one.
- Stripe tolerance 0 disables replay checks; Sume keeps a 300 s window
Stripe's default webhook tolerance is 5 minutes and 0 turns the check off. Sume's documented window is 300 seconds. Never set zero; reject stale timestamps.
Written by Sume