Skip to main content
Elicitation lets your server ask the client to collect structured input from the user while a tool is running—confirmations, missing parameters, or a small “form”.

Basic usage

from dedalus_mcp import get_context, tool, types

@tool(description="Deploy to environment")
async def deploy(env: str) -> str:
    ctx = get_context()
    server = ctx.server
    if server is None:
        raise RuntimeError("No active server in context")

    result = await server.request_elicitation(
        types.ElicitRequestParams(
            message=f"Deploy to {env}?",
            requestedSchema={
                "type": "object",
                "properties": {
                    "confirm": {"type": "boolean"},
                },
                "required": ["confirm"],
            },
        )
    )

    if result.action == "accept" and result.content and result.content.get("confirm"):
        return f"Deployed to {env}"

    return "Deployment cancelled"

Parameters

request_elicitation(...) takes an ElicitRequestParams with:
  • message: str: text shown to the user
  • requestedSchema: dict: a restricted JSON Schema object describing the expected fields
params = types.ElicitRequestParams(
    message="Enter configuration",
    requestedSchema={
        "type": "object",
        "properties": {
            "name": {"type": "string"},
            "replicas": {"type": "integer"},
            "dry_run": {"type": "boolean"},
        },
        "required": ["name"],
    },
)
result = await ctx.server.request_elicitation(params)
Schema limitations (enforced by Dedalus MCP):
  • top-level type must be "object"
  • properties must be a non-empty object
  • property type must be one of: "string", "number", "integer", "boolean"
  • nested objects/arrays are not supported

Response actions

The client returns an ElicitResult with:
  • action: "accept" | "decline" | "cancel"
  • content: optional mapping (present when action == "accept")
result = await ctx.server.request_elicitation(params)

match result.action:
    case "accept":
        data = result.content or {}
        return f"Got: {data}"
    case "decline":
        return "User declined"
    case "cancel":
        return "User cancelled"

Example: Progressive disclosure

Collect complex information step-by-step:
from dedalus_mcp import get_context, tool, types

@tool(description="Create new project")
async def create_project() -> str:
    ctx = get_context()
    server = ctx.server
    if server is None:
        raise RuntimeError("No active server in context")

    name = await server.request_elicitation(
        types.ElicitRequestParams(
            message="Project name:",
            requestedSchema={
                "type": "object",
                "properties": {"name": {"type": "string"}},
                "required": ["name"],
            },
        )
    )
    if name.action != "accept" or not name.content:
        return "Cancelled"

    project_type = await server.request_elicitation(
        types.ElicitRequestParams(
            message="Project type (web/api/cli):",
            requestedSchema={
                "type": "object",
                "properties": {"type": {"type": "string"}},
                "required": ["type"],
            },
        )
    )
    if project_type.action != "accept" or not project_type.content:
        return "Cancelled"

    confirm = await server.request_elicitation(
        types.ElicitRequestParams(
            message=f"Create {project_type.content['type']} project '{name.content['name']}'?",
            requestedSchema={
                "type": "object",
                "properties": {"confirm": {"type": "boolean"}},
                "required": ["confirm"],
            },
        )
    )

    if confirm.action == "accept" and confirm.content and confirm.content.get("confirm"):
        return f"Created {name.content['name']}"
    return "Cancelled"

Error handling

Elicitation requires an active MCP session and a client that advertises the elicitation capability. If not, request_elicitation(...) raises McpError (typically METHOD_NOT_FOUND), and timeouts raise McpError as well.
from mcp.shared.exceptions import McpError
from dedalus_mcp import types

try:
    result = await ctx.server.request_elicitation(params)
except McpError as e:
    return f"Elicitation unavailable: {e}"