Token导航 LogoToken导航TokenDH.com
MCP Agent SDK logo
AI代理stdio官方级别未说明来源级核验

MCP Agent SDK

MCP Server

用于以编程方式执行AI代理任务的Python SDK,支持自动验证和人机交互控制。

工具数

0

提示词数

0

GitHub Stars

0

资源数

0
AI代理Python任务自动化

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

ihopenot

提供方

ihopenot

最后核验

2026/5/17 20:22

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

pip install mcp-agent-sdk

详细介绍

MCP代理SDK

英语| 中文

用于以编程方式执行AI代理任务的Python SDK 自动验证人在循环 控制。

特性

  • 代理执行 --启动 codebuddy CLI代理作为受管子流程
  • 自动验证 --使用自定义函数验证任务结果;验证失败会触发自动重试
  • 循环中的人类 --代理人可以致电 Block 发出需要人为干预的任务信号
  • 生命周期挂钩 --拦截和控制代理行为 PreToolUse, PostToolUse, Stop 以及其他钩事件
  • 工具权限控制 --通过以下方式在运行时批准或拒绝工具调用 can_use_tool 带有可选输入修改的回调
  • 结构化流媒体 --接收键入的事件(AssistantMessage, SystemMessage, AgentResult)via AsyncIterator[StreamEvent]
  • 错误诊断 --进程崩溃会引发stderr捕获和退出代码的特定异常
  • 并发代理 --同时运行多个代理,每个代理由一个唯一的运行ID跟踪
  • 超时支持 --设置每次运行超时,自动阻止超时代理

安装

pip install mcp-agent-sdk

或者从源代码安装:

git clone 
cd MCPAgentSDK
pip install -e .

先决条件

  • Python≥3.10
  • codebuddy CLI已安装并可用于 PATH

快速开始

import asyncio
from mcp_agent_sdk import (
    MCPAgentSDK, AgentRunConfig, AgentResult,
    AssistantMessage, SystemMessage, TextBlock,
    AgentStartupError, AgentProcessError,
)

async def main():
    sdk = MCPAgentSDK()
    await sdk.init()

    config = AgentRunConfig(
        prompt="Create a file called hello.txt containing 'Hello, World!'",
    )

    try:
        async for event in sdk.run_agent(config):
            if isinstance(event, AgentResult):
                print(f"Done: {event.status} — {event.message}")
            elif isinstance(event, AssistantMessage):
                for block in event.content:
                    if isinstance(block, TextBlock):
                        print(f"[assistant] {block.text}")
            elif isinstance(event, SystemMessage):
                print(f"[system:{event.subtype}] {event.data}")
    except AgentStartupError as e:
        print(f"Startup failed: {e} (stderr={e.stderr}, exit_code={e.exit_code})")
    except AgentProcessError as e:
        print(f"Process crashed: {e} (stderr={e.stderr}, exit_code={e.exit_code})")

    await sdk.shutdown()

asyncio.run(main())

API 参考

MCPAgentSDK

运行代理的主要入口点。

sdk = MCPAgentSDK()
await sdk.init(host="127.0.0.1", port=0)  # port=0 auto-selects
属性类型描述
portintMCP服务器绑定到的实际端口
mcp_server_urlstrMCP端点的完整URL
方法说明
init(host, port)启动内部MCP服务器
shutdown()停止服务器并清理资源
run_agent(config)运行代理;回报 AsyncIterator[StreamEvent]

AgentRunConfig

单个代理运行的配置数据类。

@dataclass
class AgentRunConfig:
    prompt: str                                                   # Task description
    validate_fn: Callable[[str], tuple[bool, str]] | None = None  # Custom validator
    on_complete: Callable[[str], None] | None = None              # Success callback
    on_block: Callable[[str], None] | None = None                 # Block callback
    max_retries: int = 3                                          # Validation retry limit
    model: str | None = None                                      # LLM model override
    permission_mode: str = "bypassPermissions"                    # CLI permission mode
    cwd: str | None = None                                        # Working directory
    allowed_tools: list[str] | None = None                        # Restrict agent tools
    mcp_servers: dict[str, Any] = field(default_factory=dict)     # Extra MCP servers to inject
    cli_path: str = "codebuddy"                                   # CLI executable name or path
    extra_args: dict[str, str | None] = field(default_factory=dict)  # Extra CLI flags
    timeout: float | None = None                                  # Timeout in seconds
    hooks: dict[HookEvent, list[HookMatcher]] | None = None       # Lifecycle hooks
    can_use_tool: CanUseTool | None = None                         # Tool permission callback

流事件类型

run_agent() 产量 StreamEvent 子类。使用 isinstance 处理每种类型:

AssistantMessage

LLM响应包含键入的内容块。

@dataclass
class AssistantMessage(StreamEvent):
    content: list[ContentBlock]   # TextBlock, ThinkingBlock, ToolUseBlock, ToolResultBlock
    session_id: str = ""

SystemMessage

系统事件(初始化、成本等)。

@dataclass
class SystemMessage(StreamEvent):
    subtype: str = ""             # "init", "cost", "error", etc.
    data: dict[str, Any] = {}

ResultMessage

会话结束元数据(内部消耗,未产生)。

@dataclass
class ResultMessage(StreamEvent):
    session_id: str = ""
    cost_usd: float = 0.0
    duration_ms: int = 0
    is_error: bool = False
    num_turns: int = 0

AgentResult

代理运行的最终结果。

@dataclass
class AgentResult(StreamEvent):
    status: str = ""              # "completed" | "blocked"
    message: str = ""             # Result description
    session_id: str = ""
    agent_run_id: str = ""
    exit_code: int | None = None
    stderr_output: str = ""

内容块类型

内部内容块 AssistantMessage.content:

类型字段描述
TextBlocktext: str纯文本响应
ThinkingBlockthinking: strLLM内部推理
ToolUseBlocktool_use_id, name, input代理请求工具调用
ToolResultBlocktool_use_id, output, is_error工具执行结果

错误类型

流程失败会引发特定的异常,而不是产生错误事件:

异常何时属性
CLINotFoundErrorcodebuddy 不在PATH中--
AgentStartupError在产生输出之前,流程崩溃stderr, exit_code
AgentProcessError进程退出而不调用Complete/Blockstderr, stdout_tail, exit_code
AgentExecutionError逻辑错误(身份验证失败、API错误)errors, subtype

全部继承自 MCPAgentSDKError (继承自 Exception).

使用模式

自动重试验证

提供a validate_fn 以自动验证结果。如果验证失败,代理将收到反馈并重试最多 max_retries 时间。

def validate(result: str) -> tuple[bool, str]:
    if "success" in result.lower():
        return (True, "")
    return (False, "Result must indicate success. Please fix and try again.")

config = AgentRunConfig(
    prompt="Create and test a hello-world script",
    validate_fn=validate,
    max_retries=3,
)

回调

使用 on_completeon_block 跑步结束时的副作用:

config = AgentRunConfig(
    prompt="Deploy the staging environment",
    on_complete=lambda result: notify_slack(f"✅ Deploy done: {result}"),
    on_block=lambda reason: page_oncall(f"🚧 Deploy blocked: {reason}"),
)

超时

设置最大持续时间。如果代理超过限制,则会自动阻止:

config = AgentRunConfig(
    prompt="Run the full test suite",
    timeout=120.0,  # 2 minutes
)

错误处理

包裹 run_agent() 在try/except中捕获进程失败:

from mcp_agent_sdk import AgentStartupError, AgentProcessError

try:
    async for event in sdk.run_agent(config):
        if isinstance(event, AgentResult):
            print(f"Result: {event.status}")
except AgentStartupError as e:
    print(f"CLI crashed on startup: {e}")
    print(f"stderr: {e.stderr}")
    print(f"exit code: {e.exit_code}")
except AgentProcessError as e:
    print(f"Agent died without completing: {e}")
    print(f"last output: {e.stdout_tail}")

并发代理

并行启动多个代理——每个代理都有自己的独立运行上下文:

async def run_all():
    sdk = MCPAgentSDK()
    await sdk.init()

    configs = [
        AgentRunConfig(prompt="Lint the codebase"),
        AgentRunConfig(prompt="Run unit tests"),
    ]

    async def _run(cfg):
        try:
            async for event in sdk.run_agent(cfg):
                if isinstance(event, AgentResult):
                    print(event.status)
        except (AgentStartupError, AgentProcessError) as e:
            print(f"Error: {e}")

    await asyncio.gather(*[_run(c) for c in configs])
    await sdk.shutdown()

自定义MCP服务器

通过以下方式将其他MCP服务器传递给代理子流程 mcp_servers。它们与内置 agent-controller 服务器(不能被覆盖)。

config = AgentRunConfig(
    prompt="Query our internal knowledge base and summarize results",
    mcp_servers={
        "knowledge-base": {
            "type": "http",
            "url": "http://localhost:9090/mcp",
        },
        "search-engine": {
            "command": "npx",
            "args": ["-y", "@anthropic/search-mcp-server"],
        },
    },
)

代理将可以访问所有配置的MCP服务器以及SDK内部的工具 agent-controller (完整/块工具)。

生命周期挂钩

使用钩子在关键生命周期点拦截和控制代理行为。钩子是异步回调,可以允许、阻止或修改代理操作。

支持的活动: PreToolUse, PostToolUse, UserPromptSubmit, Stop, SubagentStop, PreCompact

from mcp_agent_sdk import HookMatcher

async def block_dangerous_commands(hook_input, tool_use_id, context):
    """Block dangerous Bash commands before they execute."""
    input_data = hook_input.get("input", {})
    command = input_data.get("command", "")
    if any(d in command for d in ["rm -rf", "mkfs", "dd if="]):
        return {
            "continue_": False,
            "decision": "block",
            "reason": f"Blocked dangerous command: {command}",
        }
    return {"continue_": True}

config = AgentRunConfig(
    prompt="Clean up temp files in the current directory",
    hooks={
        "PreToolUse": [
            HookMatcher(
                matcher="Bash",           # Only intercept Bash tool calls
                hooks=[block_dangerous_commands],
            )
        ],
    },
)

挂钩回拨签名

async def my_hook(
    hook_input: Any,            # Input data from CLI (tool name, args, etc.)
    tool_use_id: str | None,    # Tool use ID if applicable
    context: HookContext,       # {"signal": None}
) -> HookJSONOutput:
    return {"continue_": True}  # Allow the action

钩子返回值

字段类型描述
continue_bool是否继续执行(True)或阻止它(False)
suppressOutputbool是否抑制工具的输出
stopReasonstr停止原因(当 continue_=False)
decisionstr决策类型,例如。 "block"
reasonstr人类可读的决策原因

所有字段都是可选的。使用 continue_ (带尾随下划线)以避免Python关键字冲突——SDK将其映射到 continue 在协议中。

HookMatcher

@dataclass
class HookMatcher:
    matcher: str | None = None    # Tool name pattern to match (None = match all)
    hooks: list[HookCallback]     # List of async hook callbacks
    timeout: float | None = None  # Timeout for hook execution (seconds)

工具权限控制

使用 can_use_tool 在运行时以编程方式批准或拒绝工具调用。当CLI发送权限请求(需要 permission_mode 成为别的东西 "bypassPermissions").

from mcp_agent_sdk import (
    CanUseToolOptions, PermissionResultAllow, PermissionResultDeny,
)

ALLOWED_TOOLS = {"Read", "Glob", "Grep"}

async def my_permission_handler(
    tool_name: str,
    input_data: dict,
    options: CanUseToolOptions,
) -> PermissionResultAllow | PermissionResultDeny:
    if tool_name in ALLOWED_TOOLS:
        return PermissionResultAllow()
    return PermissionResultDeny(
        message=f"Tool '{tool_name}' is not in the allow-list",
    )

config = AgentRunConfig(
    prompt="Read and summarize pyproject.toml",
    can_use_tool=my_permission_handler,
    permission_mode="default",  # Required — bypass mode skips permission checks
)

要点:

  • can_use_tool=None (默认)使用 default_deny_can_use_tool,它拒绝所有工具调用,防止代理挂起未答复的权限请求。
  • PermissionResultAllow(updated_input={...}) 可以在执行之前修改工具的输入参数。
  • PermissionResultDeny(message="...", interrupt=True) 可以完全停止执行。
  • 钩子(PreToolUse)先跑;如果钩子挡住了工具, can_use_tool 从未被召唤。
  • 回调异常被捕获并自动转换为拒绝响应。

权限类型

类型字段描述
CanUseToolOptionstool_use_id, agent_id传递给回调的上下文
PermissionResultAllowbehavior="allow", updated_input允许工具调用,可选择修改输入
PermissionResultDenybehavior="deny", message, interrupt拒绝工具调用并说明理由

运作原理

Your Code ──► MCPAgentSDK.run_agent(config)
                │
                ├─ Start MCP HTTP server (JSON-RPC 2.0)
                ├─ Register RunContext with unique agent_run_id
                ├─ Inject system prompt with Complete/Block tool instructions
                ├─ Launch codebuddy subprocess with MCP config
                ├─ Send hooks config via stdin control protocol (if configured)
                ├─ Start async stderr reader (deque buffer, last 100 lines)
                │
                │   ┌─────────────────────────────────────┐
                │   │  codebuddy agent runs task           │
                │   │  ├─ calls Complete(result) ──────────┼──► validate_fn() ──► retry or complete
                │   │  ├─ calls Block(reason)   ──────────┼──► on_block callback
                │   │  ├─ triggers hook event   ──────────┼──► hook callback ──► allow/block
                │   │  ├─ requests tool permission ────────┼──► can_use_tool() ──► allow/deny
                │   │  └─ crashes without calling either ──┼──► raise AgentProcessError(stderr)
                │   └─────────────────────────────────────┘
                │
                └─ Yield StreamEvent stream ──► your async for loop

发展

# Install dev dependencies
pip install -e ".[dev]"

# Run unit tests
pytest

# Run end-to-end tests (requires codebuddy in PATH)
pytest -m e2e

许可证

许可证 了解详情。

目录标签

目录标签

AI代理Python任务自动化本地部署人机交互验证机制PythonSDK

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

none

工具数量(toolCount,工具数)

0

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdionone部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP