该系统由两个主要组件构成:
通信流程如下:
本指南将帮助您设置并运行MCP服务器和Google ADK代理系统,包括添加新的工具到系统中。
pip install google-adk)设置MCP服务器和Google ADK代理:
# 在项目的根目录下运行此命令以设置MCP服务器和Google ADK代理
./scripts/setup.sh
gcloud auth application-default login
配置环境变量:
# 服务器配置
PORT=9000
BASE_DIR=./data
# 仓库访问令牌,允许MCP服务器访问私有仓库
GITHUB_ACCESS_TOKEN=your_github_token_here
GITLAB_ACCESS_TOKEN=your_gitlab_token_here
# 可选配置
REPO_DIR=./repos
MAX_EVENT_LISTENERS=100
GOOGLE_CLOUD_PROJECT="your-google-project-id"
GOOGLE_CLOUD_LOCATION="us-central1"
GOOGLE_GENAI_USE_VERTEXAI="True"
MCP_SERVER_URL=http://localhost:9000
运行MCP服务器:
# 在项目的根目录下运行此命令以启动MCP服务器和Google ADK代理
./scripts/run-mcp.sh
运行Google ADK代理:
# 在此仓库的根目录下运行此命令以启动Google ADK代理
# 将以web模式启动
./scripts/run-agent.sh web
# 将以终端模式启动
./scripts/run-agent.sh run
打开web界面并选择mcp_agent:
http://localhost:8000mcp_agent测试现有工具:
要在Kubernetes中运行Google ADK代理,请按照以下步骤操作:
docker build -t mcp-agent:latest -f mcp_agent/Dockerfile .
# 构建并标记镜像
gcloud builds submit \
--tag $GOOGLE_CLOUD_LOCATION-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/mcp-agent-repo/mcp-agent:latest \
--project=$GOOGLE_CLOUD_PROJECT \
.
# 验证镜像是否已推送
gcloud artifacts docker images list \
$GOOGLE_CLOUD_LOCATION-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/mcp-agent-repo \
--project=$GOOGLE_CLOUD_PROJECT \
--format=json
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-agent
spec:
replicas: 1
selector:
matchLabels:
app: mcp-agent
template:
metadata:
labels:
app: mcp-agent
spec:
serviceAccount: mcp-agent-sa
containers:
- name: mcp-agent
imagePullPolicy: Always
image: us-central1-docker.pkg.dev/your-gar-registry/mcp-agent-repo/mcp-agent:latest
resources:
limits:
memory: "512Mi"
cpu: "500m"
ephemeral-storage: "1Gi"
requests:
memory: "256Mi"
cpu: "250m"
ephemeral-storage: "512Mi"
ports:
- containerPort: 8000
env:
- name: PORT
value: "8000"
- name: GOOGLE_CLOUD_PROJECT
value: "your-google-project-id"
- name: GOOGLE_CLOUD_LOCATION
value: "us-central1"
- name: GOOGLE_GENAI_USE_VERTEXAI
value: "True"
# 使用服务名称或外部访问方法来访问MCP服务器
- name: MCP_SERVER_URL
value: "http://mcp-server-service:9000"
volumeMounts:
- name: credentials
mountPath: "/app/credentials"
readOnly: true
volumes:
- name: credentials
secret:
secretName: mcp-agent-credentials
---
apiVersion: v1
kind: Service
metadata:
name: mcp-agent
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8000
selector:
app: mcp-agent
本逐步指南将引导您完成向MCP服务器添加新工具的整个过程,并使其对Google ADK代理可用。下面的指南将以图像生成工具为例进行说明。
让我们在MCP服务器上添加一个图像生成工具。我们将逐步介绍所有必要的更改。
首先,让我们将核心图像生成功能添加到MCP服务器。将其添加到mcp/app.ts中的app.ts文件:
// 1. 添加图像生成操作的新类型
type ImageGenerationOptions = {
prompt: string;
width?: number;
height?: number;
style?: string;
format?: 'png' | 'jpeg' | 'webp';
negativePrompt?: string;
};
// 2. 添加图像生成工具的实现
const imageGenerationTool = async (options: ImageGenerationOptions): Promise<{success: boolean; data?: any; error?: string}> => {
try {
// 验证参数
if (!options.prompt) {
return { success: false, error: '图像提示是必需的' };
}
// 为缺失选项设置默认值
const width = options.width || 512;
const height = options.height || 512;
const format = options.format || 'png';
const style = options.style || 'photorealistic';
console.log(`正在为提示:“${options.prompt}”生成图像,风格:${style},尺寸:${width}x${height}`);
// 在这个示例中,我们只是模拟图像生成
// 在实际实现中,您可能会调用Stable Diffusion或DALL-E之类的API
const mockImageData = {
prompt: options.prompt,
imageUrl: `https://example.com/generated_images/${Date.now()}.${format}`,
width,
height,
style,
format,
generatedAt: new Date().toISOString()
};
// 在实际实现中,您可能会存储图像文件
// 为了模拟目的,写入元数据文件
const metadataPath = validatePath(`images/metadata_${Date.now()}.json`);
const dir = path.dirname(metadataPath);
await fs.mkdir(dir, { recursive: true });
await fs.writeFile(metadataPath, JSON.stringify(mockImageData, null, 2), 'utf-8');
return {
success: true,
data: mockImageData
};
} catch (error: any) {
console.error('图像生成错误:', error);
return {
success: false,
error: error.message || '图像生成过程中出现未知错误'
};
}
};
在MCP服务器上添加此处理函数以处理来自Google ADK代理的请求:
// 添加到处理函数部分
async function handleImageGenerationTool(parameters: any, sessionId: string) {
// 验证必需参数
if (!parameters.prompt) {
return {
success: false,
error: '缺少必需参数:prompt'
};
}
// 创建图像生成工具的选项对象
const options: ImageGenerationOptions = {
prompt: parameters.prompt,
width: parameters.width || 512,
height: parameters.height || 512,
style: parameters.style || 'photorealistic',
format: parameters.format || 'png',
negativePrompt: parameters.negativePrompt
};
return await imageGenerationTool(options);
}
现在,在/api/adk-webhook路由处理器中的switch语句中添加一个新的case:
// 在app.post('/api/adk-webhook', ...)中找到switch语句
switch (toolName) {
case 'file_system':
result = await handleFileSystemTool(parameters, mcpSessionId);
break;
case 'api_call':
result = await handleApiTool(parameters, mcpSessionId);
break;
case 'session_data':
result = await handleSessionDataTool(parameters, mcpSessionId);
break;
case 'weather':
result = await handleWeatherTool(parameters, mcpSessionId);
break;
// 为图像生成添加新的case
case 'image_generation':
result = await handleImageGenerationTool(parameters, mcpSessionId);
break;
default:
result = {
success: false,
error: `未知工具名:${toolName}`
};
}
为直接访问图像生成工具添加专用端点:
// 将此路由添加到app
app.post('/api/session/:sessionId/image', async (req, res) => {
const { sessionId } = req.params;
const session = getSessionAndUpdate(sessionId);
if (!session) {
return res.status(404).json({
success: false,
error: '未找到会话'
});
}
const options: ImageGenerationOptions = req.body;
if (!options.prompt) {
return res.status(400).json({
success: false,
error: '图像提示是必需的'
});
}
const result = await imageGenerationTool(options);
if (result.success) {
// 通过SSE客户端发送事件
emitEvent(sessionId, 'image-generation', {
imageUrl: result.data.imageUrl,
prompt: options.prompt,
timestamp: new Date().toISOString()
});
res.status(200).json(result);
} else {
res.status(400).json(result);
}
});
在/api/help端点的API文档中添加新的工具:
// 在helpDocs对象中找到endpoints数组
endpoints: [
// 添加这些新条目
{
path: "/api/session/{sessionId}/image",
method: "POST",
description: "根据文本提示生成图像",
parameters: [
{
name: "sessionId",
in: "path",
required: true,
description: "会话标识符"
}
],
requestBodyExample: {
prompt: "美丽的日落山景",
width: 512,
height: 512,
style: "photorealistic",
format: "png",
negativePrompt: "模糊,低质量"
},
responseExample: {
success: true,
data: {
prompt: "美丽的日落山景",
imageUrl: "https://example.com/generated_images/1717451623456.png",
width: 512,
height: 512,
style: "photorealistic",
format: "png",
generatedAt: "2025-06-03T12:00:00.000Z"
}
},
curlExample: `curl -X POST ${baseUrl}/api/session/{sessionId}/image \\
-H "Content-Type: application/json" \\
-d '{"prompt": "美丽的日落山景", "style": "photorealistic"}'`
},
// 为image_generation工具添加Google ADK webhook文档
{
path: "/api/adk-webhook",
method: "POST",
description: "Google ADK图像生成的webhook",
requestBodyExample: {
session_id: "google-adk-session-123",
tool_name: "image_generation",
parameters: {
prompt: "美丽的日落山景",
width: 512,
height: 512,
style: "photorealistic"
},
request_id: "request-123"
},
responseExample: {
success: true,
data: {
prompt: "美丽的日落山景",
imageUrl: "https://example.com/generated_images/1717451623456.png",
width: 512,
height: 512,
style: "photorealistic",
format: "png",
generatedAt: "2025-06-03T12:00:00.000Z"
},
mcp_session_id: "550e8400-e29b-41d4-a716-446655440000",
request_id: "request-123"
},
notes: "此端点由Google ADK代理用于生成图像。"
}
],
现在让我们在Google ADK代理中添加图像生成工具,它位于mcp_agent。
首先,在mcp_agent/mcp_toolkit.py文件中添加一个新方法以与图像生成工具交互:
# 在mcp_toolkit.py中的MCPToolkit类中添加此方法
def generate_image(self, prompt: str, width: int = 512, height: int = 512,
style: str = "photorealistic", format: str = "png",
negative_prompt: str = None) -> Dict:
"""使用MCP服务器从文本提示生成图像"""
params = {
"prompt": prompt,
"width": width,
"height": height,
"style": style,
"format": format
}
if negative_prompt:
params["negativePrompt"] = negative_prompt
return self.execute_tool("image_generation", params)
在tools.py中创建一个新的工具函数,该函数将暴露给ADK代理:
# 将此添加到tools.py文件
def mcp_generate_image(prompt: str, style: str = "photorealistic", width: int = 512, height: int = 512) -> dict:
"""根据文本提示生成图像。
参数:
prompt: 要生成的图像的文字描述
style: 图像的风格(例如,photorealistic,卡通,草图)
width: 输出图像的宽度(像素)
height: 输出图像的高度(像素)
返回:
dict: 包含状态('success' 或 'error')以及图像信息或错误消息的字典
"""
try:
result = mcp_toolkit.generate_image(
prompt=prompt,
style=style,
width=width,
height=height
)
if result.get("success"):
image_data = result.get("data", {})
return {
"status": "success",
"image_url": image_data.get("imageUrl"),
"message": f"为提示:'{prompt}'生成了{style}风格的图像。"
}
else:
return {
"status": "error",
"error_message": result.get("error", "生成图像时出现未知错误")
}
except Exception as e:
logger.error(f"mcp_generate_image中的错误:{str(e)}")
return {
"status": "error",
"error_message": f"异常:{str(e)}"
}
更新agent.py文件以包含新工具:
# 在agent.py中添加导入
from .tools import (
mcp_read_file,
mcp_write_file,
mcp_list_files,
mcp_delete_file,
mcp_get_weather,
mcp_call_api,
mcp_store_data,
mcp_store_number,
mcp_store_boolean,
mcp_retrieve_data,
mcp_generate_image # 添加此导入
)
# 更新代理定义
agent = Agent(
name="mcp_agent",
model="gemini-2.0-flash",
description="能够处理天气、时间和与模型控制协议服务器交互的代理",
instruction="""我可以通过与MCP服务器的集成帮助您完成各种任务。
我可以:
- 获取不同城市的当前时间
- 查看地点的天气状况
- 读取、写入、列出和删除文件
- 调用外部服务的API
- 在会话中存储