Skip to content
gentic.news — AI News Intelligence Platform
Connecting to the Living Graph…

Listen to today's AI briefing

Daily podcast — 5 min, AI-narrated summary of top stories

Screenshot of a terminal window showing a user interacting with a Claude Code tool that pauses mid-execution to ask…
Open SourceScore: 67

How to Build Claude Code Tools That Ask Users Questions Mid-Execution

Datasette Agent 0.2a0's `context.ask_user()` lets tools pause for user input mid-execution. Claude Code users can adopt this pattern for safer, more interactive tool workflows.

·3d ago·3 min read··5 views·AI-Generated·Report error
Share:
Source: simonwillison.netvia simon_willison, devto_claudecodeCorroborated
How do I build Claude Code tools that ask users questions mid-execution?

Use `context.ask_user()` in your tools to pause execution for user input. Supports yes/no, `options=[...]` for multiple-choice, and `free_text=True` for open answers. Questions survive server restarts. Call before side effects.

TL;DR

Datasette Agent 0.2a0 lets tools pause and ask yes/no, multiple-choice, or free-text questions mid-execution — a pattern you can replicate in Claude Code.

Key Takeaways

  • Datasette Agent 0.2a0's context.ask_user() lets tools pause for user input mid-execution.
  • Claude Code users can adopt this pattern for safer, more interactive tool workflows.

What Changed

When Claude Can't Ask: Building Interactive Tools for the ...

Datasette Agent 0.2a0 introduces a deceptively simple but powerful capability: tools can now ask users questions mid-execution and wait for an answer before continuing.

This isn't just a UI trick. The agent's turn suspends while waiting. The question renders as a form in the chat UI and persists to an internal database — so even if the server restarts, the conversation picks up where it left off.

Here's the API:

async def my_tool(context: ToolContext):
    # Ask before doing anything with side effects
    confirm = await context.ask_user(
        "Delete all records from the users table?",
        options=["Yes, delete", "No, cancel"]
    )
    if confirm == "Yes, delete":
        # Now it's safe to proceed
        ...

Three question types are supported:

  • Yes/no: default behavior with a simple question string
  • Multiple choice: pass options=["Option A", "Option B"]
  • Free text: pass free_text=True

What It Means For You

If you build custom tools for Claude Code (or any agentic workflow), this pattern solves a critical problem: confirmation without context loss.

Previously, you had two bad options:

  1. Ask upfront for all permissions (annoying, inflexible)
  2. Let the tool execute and only confirm after (risky, defeats the purpose)

ask_user() splits the difference. The tool starts, gathers context, then asks a precise question. If the user says no, the tool can adjust its approach without restarting from scratch.

For Claude Code users, this is especially relevant if you're building custom MCP servers or tool integrations. Imagine:

  • A deployment tool that asks "Deploy to production?" only after building a diff
  • A database tool that asks "This query will affect 10k rows. Continue?"
  • A file management tool that asks "Overwrite existing file?" with the diff shown

Try It Now

To use this pattern in your own Claude Code tools (via MCP or the Tools API):

  1. Declare a context parameter in your tool function signature
  2. Call await context.ask_user(...) before any side effects
  3. Handle the response to decide next steps

Example MCP tool stub:

@mcp.tool()
async def deploy_service(version: str, context: ToolContext) -> str:
    """Deploy a service version to production."""
    # Gather info first
    diff = await get_diff(version)
    
    # Ask for confirmation
    confirm = await context.ask_user(
        f"Deploy version {version} to production?\n\nDiff:\n{diff[:500]}",
        options=["Deploy", "Cancel", "Show full diff first"]
    )
    
    if confirm == "Deploy":
        result = await run_deploy(version)
        return f"Deployed {version}: {result}"
    elif confirm == "Show full diff first":
        # Could ask another question or return info
        return "Showing full diff in next message..."
    else:
        return "Deployment cancelled."

The key rule: call ask_user() before performing side effects. The tool re-executes from the top with stored answers replayed, so any side effect before the question would run twice.


Source: simonwillison.net

Source: gentic.news · · author= · citation.json

AI-assisted reporting. Generated by gentic.news from multiple verified sources, fact-checked against the Living Graph of 4,300+ entities. Edited by Ala SMITH.

Following this story?

Get a weekly digest with AI predictions, trends, and analysis — free.

AI Analysis

Claude Code users should immediately adopt this pattern in any custom tools they build for MCP servers or internal workflows. The `ask_user()` pattern solves the fundamental tension between autonomy and safety in agentic code assistants. For your own tools, add a `context` parameter and use `ask_user()` for any operation that could have irreversible consequences — database writes, file deletions, deployments, API calls that cost money. This makes your tools safer without sacrificing the fluid, conversational flow that makes Claude Code powerful. Don't overuse it, though. Only ask when the tool has enough context to make the question precise. Asking "Can I proceed?" at the start of every tool defeats the purpose. The power is in asking the *right* question at the *right* moment — after gathering context but before acting.
Compare side-by-side
Claude Code vs Datasette Agent 0.2a0

Mentioned in this article

Enjoyed this article?
Share:

AI Toolslive

Five one-click lenses on this article. Cached for 24h.

Pick a tool above to generate an instant lens on this article.

Related Articles

From the lab

The framework underneath this story

Every article on this site sits on top of one engine and one framework — both built by the lab.

More in Open Source

View all