跳转到内容

创建 MCP Tools

创建自定义 MCP tools,以通过外部集成、自定义逻辑和数据访问来扩展你的数字员工能力。

  1. 定义 WIT Interface

    wit/tool.wit
    package greentic:my-tool;
    interface tool {
    record input {
    query: string,
    options: option<string>,
    }
    record output {
    success: bool,
    data: option<string>,
    error: option<string>,
    }
    execute: func(input: input) -> output;
    }
    world my-tool {
    export tool;
    }
  2. 使用 Rust 实现

    src/lib.rs
    use wit_bindgen::generate;
    generate!({
    world: "my-tool",
    path: "wit",
    });
    struct MyTool;
    impl tool::Guest for MyTool {
    fn execute(input: tool::Input) -> tool::Output {
    // Your tool logic here
    let result = process_query(&input.query);
    tool::Output {
    success: true,
    data: Some(result),
    error: None,
    }
    }
    }
    fn process_query(query: &str) -> String {
    format!("Processed: {}", query)
    }
    export!(MyTool);
  3. 构建 WASM Component

    Terminal window
    cargo build --target wasm32-wasip2 --release
  4. 创建 Tool Manifest

    tool.yaml
    name: my_tool
    version: "1.0.0"
    description: My custom MCP tool
    parameters:
    - name: query
    type: string
    description: The query to process
    required: true
    - name: options
    type: string
    description: Optional configuration
    required: false
    returns:
    type: object
    properties:
    success:
    type: boolean
    data:
    type: string
    error:
    type: string
    capabilities:
    - network:outbound
  5. 注册 Tool

    greentic.demo.yaml
    mcp:
    tools:
    - name: my_tool
    component: "tools/my-tool.wasm"
    manifest: "tools/my-tool.yaml"
impl tool::Guest for HttpTool {
fn execute(input: tool::Input) -> tool::Output {
let url = &input.url;
let method = input.method.unwrap_or("GET".to_string());
match http_request(&method, url, input.body.as_deref()) {
Ok(response) => tool::Output {
success: true,
data: Some(response),
error: None,
},
Err(e) => tool::Output {
success: false,
data: None,
error: Some(e.to_string()),
},
}
}
}
impl tool::Guest for DbTool {
fn execute(input: tool::Input) -> tool::Output {
// Get connection string from secrets
let conn_str = get_secret("database_url")?;
// Execute query (pseudo-code)
let results = db_query(&conn_str, &input.query)?;
tool::Output {
success: true,
data: Some(serde_json::to_string(&results)?),
error: None,
}
}
}
impl tool::Guest for EmailTool {
fn execute(input: tool::Input) -> tool::Output {
let api_key = get_secret("sendgrid_api_key")?;
let result = send_email(
&api_key,
&input.to,
&input.subject,
&input.body,
);
match result {
Ok(_) => tool::Output {
success: true,
data: Some("Email sent".to_string()),
error: None,
},
Err(e) => tool::Output {
success: false,
data: None,
error: Some(e.to_string()),
},
}
}
}
- id: call_tool
type: mcp-tool
config:
tool: "my_tool"
parameters:
query: "{{user_query}}"
output: tool_result
- id: agent
type: llm
config:
model: "gpt-4"
system_prompt: |
You are an assistant with access to tools.
Use tools when needed to help the user.
tools:
- my_tool
- http_request
- send_email
tool_choice: "auto"
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_execute() {
let input = tool::Input {
query: "test".to_string(),
options: None,
};
let output = MyTool::execute(input);
assert!(output.success);
assert!(output.data.is_some());
}
}
Terminal window
# Test with sample input
echo '{"query": "test"}' | greentic-mcp test ./my-tool.wasm
  1. 处理所有错误 - 永远不要 panic,始终在 output 中返回错误
  2. 验证输入 - 在处理前检查参数
  3. 使用 secrets - 不要硬编码凭证
  4. 添加日志 - 便于调试
  5. 充分编写文档 - 在 manifest 中提供清晰描述
  6. 测试边界情况 - 处理空输入、大数据量等情况