跳转到主要内容
信息征询允许你的服务器在 tool 运行时,请求 Client 向用户收集结构化输入——例如确认、补充缺失参数,或填写一个小型「表单」。

基本用法

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"

参数

request_elicitation(...) 接受一个 ElicitRequestParams,其中包含:
  • message: str:显示给用户的文本
  • requestedSchema: dict:描述期望字段的受限 JSON Schema 对象
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)
模式限制(由 Dedalus 模型上下文协议 (MCP) 强制执行):
  • 顶层的 type 必须是 "object"
  • properties 必须是非空对象
  • 属性的 type 必须是以下之一:"string""number""integer""boolean"
  • 不支持嵌套对象或数组

响应操作

Client 返回一个 ElicitResult,其中包含:
  • action: "accept" | "decline" | "cancel"
  • content: 可选映射对象(仅当 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"

示例:渐进式披露

按步骤收集复杂信息:
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"创建 {project_type.content['type']} 项目 '{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"

错误处理

Elicitation 需要一个有效的模型上下文协议 (MCP) 会话,以及一个声明支持 elicitation 能力的 Client。否则,request_elicitation(...) 会抛出 McpError(通常是 METHOD_NOT_FOUND),超时同样会抛出 McpError
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"引导功能不可用:{e}"