动物园MCP服务器

一个基于FastMCP和Google Cloud Run的安全模型上下文协议(MCP)服务器,用于查询动物园动物信息。

  • by Vinipallakki
  • 本地部署
  • 更新于
在 GitHub 查看 Vinipallakki/simple_mcp_server

使用说明

Zoo-MCP服务器在云端运行

此项目显示了如何构建和部署 安全模型上下文协议 服务器使用 FastMCP 上 谷歌云运行。它包括按物种查询动物园动物和获取单个动物详细信息的工具。服务器设置为需要身份验证,因此只有授权的客户端才能调用其工具。


🚀 你将学到什么

  • 如何使用FastMCP构建简单的MCP服务器
  • 如何将其容器化并部署到Cloud Run
  • 保护服务端点,只允许经过身份验证的请求
  • 将客户端(例如Gemini CLI)连接到远程MCP服务器

📋 项目结构


.
├── Dockerfile
├── pyproject.toml
├── server.py
└── README.md

  • server.py --带有动物查找工具的Python MCP服务器代码
  • Dockerfile --将应用程序容器化
  • pyproject.toml --依赖关系和项目配置
  • README.md --此文件

🔧 先决条件

  • Google Cloud帐户
  • 启用计费的Google Cloud项目
  • gcloud SDK已安装并配置
  • (可选)如果您想从CLI进行测试,请使用Gemini CLI

⚙️ 安装指南

下面是设置和部署MCP服务器的高级步骤。

1.启用所需的API

gcloud services enable \
  run.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com

2.初始化Python项目

mkdir zoo-mcp-server && cd zoo-mcp-server

# Create project config (assuming using `uv` for project scaffolding)
uv init --description "Zoo MCP server on Cloud Run" --bare --python 3.13

添加 fastmcp 作为一种依赖。例如,在 pyproject.toml:

[project]
name = "zoo-mcp-server"
version = "0.1.0"
description = "Zoo MCP Server example"
requires-python = ">=3.13"

[dependencies]
fastmcp = "2.11.1"

3.编写服务器代码(server.py)

下面是一个简化的例子:

import asyncio
import logging
import os
from typing import List, Dict, Any

from fastmcp import FastMCP

logger = logging.getLogger(__name__)
logging.basicConfig(
    format="[%(levelname)s]: %(message)s",
    level=logging.INFO
)

mcp = FastMCP("Zoo Animal MCP Server")

# In-memory data store
ZOO_ANIMALS = [
    {"species": "lion", "name": "Leo", "age": 7, "enclosure": "The Big Cat Plains", "trail": "Savannah Heights"},
    {"species": "penguin", "name": "Waddles", "age": 2, "enclosure": "The Arctic Exhibit", "trail": "Polar Path"},
    # … add more animals …
]

@mcp.tool()
def get_animals_by_species(species: str) -> List[Dict[str, Any]]:
    logger.info(f">>> Tool: 'get_animals_by_species' called for '{species}'")
    return [animal for animal in ZOO_ANIMALS if animal["species"].lower() == species.lower()]

@mcp.tool()
def get_animal_details(name: str) -> Dict[str, Any]:
    logger.info(f">>> Tool: 'get_animal_details' called for '{name}'")
    for animal in ZOO_ANIMALS:
        if animal["name"].lower() == name.lower():
            return animal
    return {}

if __name__ == "__main__":
    port = int(os.getenv("PORT", 8080))
    logger.info(f"Starting MCP server on port {port}")
    asyncio.run(
        mcp.run_async(
            transport="http",
            host="0.0.0.0",
            port=port,
        )
    )

4.码头化

创建 Dockerfile:

# Use official Python image
FROM python:3.13-slim

# Copy uv tool (if using uv scaffolding)
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

# Copy project
COPY . /app
WORKDIR /app

# Ensure logs appear promptly
ENV PYTHONUNBUFFERED=1

# Install dependencies
RUN uv sync

# Expose port
EXPOSE $PORT

# Command to run the server
CMD ["uv", "run", "server.py"]

5.部署到云端运行

gcloud run deploy zoo-mcp-server \
  --no-allow-unauthenticated \
  --region=<YOUR_REGION> \
  --source=. \
  --labels=env=prod,project=zoo-mcp
  • 国旗 --no-allow-unauthenticated 确保只有经过身份验证的请求才能调用MCP服务器。
  • 请确保选择您喜欢的地区。

🔐 设置访问权限和客户端

部署后,您将希望允许您的用户(或服务帐户)调用服务:

gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
  --member=user:$(gcloud config get-value account) \
  --role='roles/run.invoker'

您还可以检索 ID_TOKEN 与客户一起使用:

export ID_TOKEN=$(gcloud auth print-identity-token)

配置Gemini CLI(或其他MCP客户端)

在您的客户端配置中(例如。 ~/.gemini/settings.json),添加:

{
  "mcpServers": {
    "zoo-remote": {
      "httpUrl": "https://<YOUR_CLOUD_RUN_SERVICE_URL>/mcp/",
      "headers": {
        "Authorization": "Bearer <YOUR_ID_TOKEN>"
      }
    }
  },
  "selectedAuthType": "cloud-shell",
  "hasSeenIdeIntegrationNudge": true
}

🧰 日志和调试

  • 要查看工具调用是否正常工作,请执行以下操作:

    gcloud run services logs read zoo-mcp-server --region=<YOUR_REGION> --limit=10
    
  • 一个常见问题: 身份验证错误 --确保你的客户的不记名代币是有效的。如果ID令牌超时,请重新获取。


🧼 清理

如果你想避免持续收费:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

或手动删除:

  • Cloud Run服务
  • 存储容器映像的工件注册表存储库

📌 参考文献


快乐建筑! 🎉 如果你需要帮助来调整你自己的用例(不同的工具、数据源、地区等),我可以帮你调整一下。