Agent MCP(模型上下文协议)的核心作用是为AI应用连接外部工具和数据源提供一套标准化的“万能接口”。

MCP核心功能:

可以把它理解为Agent与外界的“通用翻译器”和“统一调度员”,具体体现在:

  • 打破数据孤岛,让AI“耳聪目明”:AI模型通常无法直接访问实时数据或你的私有业务数据。MCP服务器通过标准化的“资源”和“工具”,让AI能安全地读取数据库、调用API、操作本地文件。例如,让一个客服Agent可以实时查询你的库存数据库

  • 告别“手写代码”的麻烦:在没有MCP时,每接入一个外部系统(如数据库、邮件服务),开发者都需要编写大量定制化代码。MCP让Agent能自动发现(list_tools)和调用(call_tool服务器提供的功能,当服务更新时,也无需修改Agent代码

  • 让Agent既能“想”,也能“做”:大模型(LLM)负责思考和规划,而Agent则通过MCP去“执行”。Agent可以将复杂任务拆解,然后通过MCP调用不同的工具来完成(如发送邮件、操作Excel、生成报表)

  • 保障企业级安全与合规:MCP在设计上内置了用户授权和同意的概念,所有工具调用和数据访问都需要明确的用户授权,这对于处理敏感数据的企业应用至关重要

MCP对接类型服务:

MCP 本质上是一个标准化的协议层,只要某服务能被 Python/Node.js 调用,就可以封装成 MCP 工具给 Agent 使用

API接口

代码:email-marketing-agent.zip

REST/GraphQL 

import json
import sys
import urllib.request
import urllib.parse
from typing import Any

BASE_URL = "http://localhost:8081"


def send_request(method: str, path: str, params: dict | None = None) -> dict:
    url = f"{BASE_URL}{path}"
    if params:
        query = urllib.parse.urlencode(params)
        url = f"{url}?{query}"
    req = urllib.request.Request(url, method=method)
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            data = resp.read().decode("utf-8")
            return json.loads(data) if data else {}
    except Exception as e:
        return {"error": str(e)}


def handle_list_tools() -> dict:
    return {
        "tools": [
            {
                "name": "get_week_trend",
                "description": "获取测试报告周趋势数据",
                "inputSchema": {"type": "object", "properties": {}},
            },
            {
                "name": "get_today_pass_rate",
                "description": "获取今日测试通过率",
                "inputSchema": {"type": "object", "properties": {}},
            },
            {
                "name": "get_report_status",
                "description": "获取指定测试用例和报告的状态",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "testcaseId": {"type": "string", "description": "测试用例ID"},
                        "reportName": {"type": "string", "description": "报告名称"},
                    },
                    "required": ["testcaseId", "reportName"],
                },
            },
            {
                "name": "get_report_stats",
                "description": "获取测试报告统计数据",
                "inputSchema": {"type": "object", "properties": {}},
            },
            {
                "name": "search_reports",
                "description": "搜索测试报告",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "keyword": {"type": "string", "description": "搜索关键词"},
                    },
                },
            },
            {
                "name": "play_video",
                "description": "获取测试用例视频回放地址",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "testcaseId": {"type": "string", "description": "测试用例ID"},
                    },
                    "required": ["testcaseId"],
                },
            },
            {
                "name": "business_model",
                "description": "获取业务模块",
                "inputSchema": {"type": "object", "properties": {}},
            },            
        ]
    }


def handle_call_tool(name: str, arguments: dict) -> dict:
    if name == "get_week_trend":
        result = send_request("GET", "/api/reports/weekTrend")
    elif name == "get_today_pass_rate":
        result = send_request("GET", "/api/reports/todayPassRate")
    elif name == "get_report_status":
        tc = arguments.get("testcaseId")
        rn = arguments.get("reportName")
        result = send_request("GET", f"/api/reports/status/{tc}/{rn}")
    elif name == "get_report_stats":
        result = send_request("GET", "/api/reports/stats")
    elif name == "search_reports":
        kw = arguments.get("keyword")
        result = send_request("GET", "/api/reports/search", {"keyword": kw} if kw else None)
    elif name == "play_video":
        tc = arguments.get("testcaseId")
        result = send_request("GET", f"/api/reports/playVideo/{tc}")
    elif name == "business_model":
        result = send_request("GET", "/api/scenarios/business-modules")
    else:
        result = {"error": f"Unknown tool: {name}"}
    return {"content": [{"type": "text", "text": json.dumps(result, ensure_ascii=False)}]}


def main():
    while True:
        line = sys.stdin.readline()
        if not line:
            break
        try:
            msg = json.loads(line)
        except json.JSONDecodeError:
            continue
        method = msg.get("method")
        msg_id = msg.get("id")
        resp: dict[str, Any] = {"jsonrpc": "2.0", "id": msg_id}
        if method == "initialize":
            resp["result"] = {
                "protocolVersion": "2024-11-05",
                "capabilities": {"tools": {}},
                "serverInfo": {"name": "test-report-mcp", "version": "0.1.0"},
            }
        elif method == "tools/list":
            resp["result"] = handle_list_tools()
        elif method == "tools/call":
            params = msg.get("params", {})
            resp["result"] = handle_call_tool(params.get("name"), params.get("arguments", {}))
        else:
            resp["error"] = {"code": -32601, "message": f"Method not found: {method}"}
        sys.stdout.write(json.dumps(resp, ensure_ascii=False) + "\n")
        sys.stdout.flush()


if __name__ == "__main__":
    main()
View Code

image

 

数据库

- PostgreSQL、MySQL、SQLite、MongoDB
- 让 Agent 直接查询数据库、分析表结构
- 常见项目: @modelcontextprotocol/server-postgres 、 @modelcontextprotocol/server-sqlite

 

"""
数据库 MCP Server Demo
支持 SQLite/MySQL/PostgreSQL,让 Agent 能查询数据库
配置: DB_TYPE=sqlite, DB_PATH=./demo.db
      DB_TYPE=mysql, DB_HOST=..., DB_USER=..., DB_PASS=..., DB_NAME=...
"""
import json
import sys
import os
import sqlite3
from typing import Any

# 默认数据库连接配置(硬编码,避免环境变量传递问题)
DEFAULT_CONFIG = {
    "DB_TYPE": "mysql",
    "DB_HOST": "192.168.6.59",
    "DB_PORT": "3306",
    "DB_NAME": "metersphere",
    "DB_USER": "readonly_user",
    "DB_PASS": "",
    "DB_SSL_DISABLED": "true",
}


def get_env(key: str) -> str:
    """优先读取环境变量,否则使用默认配置"""
    return os.environ.get(key, DEFAULT_CONFIG.get(key, ""))


def get_connection():
    db_type = get_env("DB_TYPE")
    if db_type == "sqlite":
        return sqlite3.connect(get_env("DB_PATH") or "demo.db")
    elif db_type == "mysql":
        import pymysql
        return pymysql.connect(
            host=get_env("DB_HOST") or "localhost",
            port=int(get_env("DB_PORT") or "3306"),
            user=get_env("DB_USER") or "root",
            password=get_env("DB_PASS") or "",
            database=get_env("DB_NAME") or "",
            charset="utf8mb4",
            ssl_disabled=get_env("DB_SSL_DISABLED").lower() == "true",
        )
    elif db_type == "postgres":
        import psycopg2
        return psycopg2.connect(
            host=get_env("DB_HOST") or "localhost",
            port=get_env("DB_PORT") or "5432",
            user=get_env("DB_USER") or "postgres",
            password=get_env("DB_PASS") or "",
            database=get_env("DB_NAME") or "",
        )
    else:
        raise ValueError(f"Unsupported DB_TYPE: {db_type}")


def _serialize_row(row: tuple) -> list:
    """处理 datetime 等不可 JSON 序列化的类型"""
    result = []
    for item in row:
        if hasattr(item, "isoformat"):
            result.append(item.isoformat())
        else:
            result.append(item)
    return result


def execute_query(sql: str) -> dict:
    conn = get_connection()
    try:
        cur = conn.cursor()
        cur.execute(sql)
        upper_sql = sql.strip().upper()
        if upper_sql.startswith("SELECT") or upper_sql.startswith("PRAGMA") or upper_sql.startswith("SHOW"):
            columns = [desc[0] for desc in cur.description] if cur.description else []
            rows = cur.fetchall()
            return {"columns": columns, "rows": [_serialize_row(r) for r in rows], "count": len(rows)}
        else:
            conn.commit()
            return {"affected_rows": cur.rowcount}
    except Exception as e:
        return {"error": str(e)}
    finally:
        conn.close()


def list_tables() -> dict:
    db_type = os.environ.get("DB_TYPE", "sqlite")
    if db_type == "sqlite":
        return execute_query("SELECT name FROM sqlite_master WHERE type='table'")
    elif db_type == "mysql":
        return execute_query("SHOW TABLES")
    elif db_type == "postgres":
        return execute_query("SELECT tablename FROM pg_tables WHERE schemaname='public'")
    return {"error": "Unsupported DB type"}


def describe_table(table_name: str) -> dict:
    db_type = os.environ.get("DB_TYPE", "sqlite")
    if db_type == "sqlite":
        return execute_query(f"PRAGMA table_info({table_name})")
    elif db_type == "mysql":
        return execute_query(f"DESCRIBE {table_name}")
    elif db_type == "postgres":
        return execute_query(
            f"SELECT column_name, data_type FROM information_schema.columns WHERE table_name='{table_name}'"
        )
    return {"error": "Unsupported DB type"}


def handle_list_tools() -> dict:
    return {
        "tools": [
            {
                "name": "list_tables",
                "description": "列出数据库中所有表",
                "inputSchema": {"type": "object", "properties": {}},
            },
            {
                "name": "describe_table",
                "description": "查看表结构",
                "inputSchema": {
                    "type": "object",
                    "properties": {"table": {"type": "string", "description": "表名"}},
                    "required": ["table"],
                },
            },
            {
                "name": "execute_query",
                "description": "执行 SQL 查询(仅支持 SELECT)",
                "inputSchema": {
                    "type": "object",
                    "properties": {"sql": {"type": "string", "description": "SQL 语句"}},
                    "required": ["sql"],
                },
            },
        ]
    }


def handle_call_tool(name: str, arguments: dict) -> dict:
    if name == "list_tables":
        result = list_tables()
    elif name == "describe_table":
        result = describe_table(arguments.get("table", ""))
    elif name == "execute_query":
        result = execute_query(arguments.get("sql", ""))
    else:
        result = {"error": f"Unknown tool: {name}"}
    return {"content": [{"type": "text", "text": json.dumps(result, ensure_ascii=False)}]}


def main():
    while True:
        line = sys.stdin.readline()
        if not line:
            break
        try:
            msg = json.loads(line)
        except json.JSONDecodeError:
            continue
        method = msg.get("method")
        msg_id = msg.get("id")
        resp: dict[str, Any] = {"jsonrpc": "2.0", "id": msg_id}
        if method == "initialize":
            resp["result"] = {
                "protocolVersion": "2024-11-05",
                "capabilities": {"tools": {}},
                "serverInfo": {"name": "database-mcp", "version": "0.1.0"},
            }
        elif method == "tools/list":
            resp["result"] = handle_list_tools()
        elif method == "tools/call":
            params = msg.get("params", {})
            resp["result"] = handle_call_tool(params.get("name"), params.get("arguments", {}))
        else:
            resp["error"] = {"code": -32601, "message": f"Method not found: {method}"}
        sys.stdout.write(json.dumps(resp, ensure_ascii=False) + "\n")
        sys.stdout.flush()


if __name__ == "__main__":
    main()
View Code

 

image

文件系统

- 读写本地文件、目录浏览、文件搜索
- Agent 可以直接操作你电脑上的文件
- 常见项目: @modelcontextprotocol/server-filesystem

 

开发工具

- Git — 查看提交记录、分支管理、创建 PR
- GitHub/GitLab — 管理 Issue、PR、代码审查
- 常见项目: @modelcontextprotocol/server-github

 

"""
Git/GitHub MCP Server Demo
让 Agent 能查看提交记录、分支、创建 PR
配置: GITHUB_TOKEN=your_token, REPO_PATH=./
"""
import json
import sys
import os
import subprocess
import urllib.request
from typing import Any

REPO_PATH = os.environ.get("REPO_PATH", ".")
GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN", "")


def run_git(args: list[str]) -> dict:
    try:
        result = subprocess.run(
            ["git"] + args,
            cwd=REPO_PATH,
            capture_output=True,
            text=True,
            timeout=30,
        )
        if result.returncode != 0:
            return {"error": result.stderr.strip()}
        return {"output": result.stdout.strip()}
    except Exception as e:
        return {"error": str(e)}


def github_api(method: str, endpoint: str, data: dict = None) -> dict:
    if not GITHUB_TOKEN:
        return {"error": "GITHUB_TOKEN not set"}
    url = f"https://api.github.com{endpoint}"
    headers = {
        "Authorization": f"Bearer {GITHUB_TOKEN}",
        "Accept": "application/vnd.github+json",
    }
    body = json.dumps(data).encode() if data else None
    req = urllib.request.Request(url, data=body, method=method, headers=headers)
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            return json.loads(resp.read().decode("utf-8"))
    except Exception as e:
        return {"error": str(e)}


def handle_list_tools() -> dict:
    return {
        "tools": [
            {
                "name": "git_log",
                "description": "查看 Git 提交记录",
                "inputSchema": {
                    "type": "object",
                    "properties": {"count": {"type": "integer", "default": 10}},
                },
            },
            {
                "name": "git_branch",
                "description": "查看/创建分支",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "action": {"type": "string", "enum": ["list", "create"], "default": "list"},
                        "name": {"type": "string", "description": "分支名(create 时必填)"},
                    },
                },
            },
            {
                "name": "git_status",
                "description": "查看工作区状态",
                "inputSchema": {"type": "object", "properties": {}},
            },
            {
                "name": "github_create_pr",
                "description": "在 GitHub 上创建 Pull Request",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "repo": {"type": "string", "description": "owner/repo 格式"},
                        "title": {"type": "string"},
                        "head": {"type": "string", "description": "源分支"},
                        "base": {"type": "string", "description": "目标分支"},
                        "body": {"type": "string", "description": "PR 描述"},
                    },
                    "required": ["repo", "title", "head", "base"],
                },
            },
            {
                "name": "github_list_issues",
                "description": "列出 GitHub Issues",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "repo": {"type": "string", "description": "owner/repo 格式"},
                        "state": {"type": "string", "enum": ["open", "closed", "all"], "default": "open"},
                    },
                    "required": ["repo"],
                },
            },
        ]
    }


def handle_call_tool(name: str, arguments: dict) -> dict:
    if name == "git_log":
        count = arguments.get("count", 10)
        result = run_git(["log", f"-{count}", "--oneline"])
    elif name == "git_branch":
        action = arguments.get("action", "list")
        if action == "list":
            result = run_git(["branch", "-a"])
        else:
            result = run_git(["branch", arguments.get("name", "")])
    elif name == "git_status":
        result = run_git(["status", "--short"])
    elif name == "github_create_pr":
        result = github_api("POST", f"/repos/{arguments['repo']}/pulls", {
            "title": arguments["title"],
            "head": arguments["head"],
            "base": arguments["base"],
            "body": arguments.get("body", ""),
        })
    elif name == "github_list_issues":
        state = arguments.get("state", "open")
        result = github_api("GET", f"/repos/{arguments['repo']}/issues?state={state}")
    else:
        result = {"error": f"Unknown tool: {name}"}
    return {"content": [{"type": "text", "text": json.dumps(result, ensure_ascii=False)}]}


def main():
    while True:
        line = sys.stdin.readline()
        if not line:
            break
        try:
            msg = json.loads(line)
        except json.JSONDecodeError:
            continue
        method = msg.get("method")
        msg_id = msg.get("id")
        resp: dict[str, Any] = {"jsonrpc": "2.0", "id": msg_id}
        if method == "initialize":
            resp["result"] = {
                "protocolVersion": "2024-11-05",
                "capabilities": {"tools": {}},
                "serverInfo": {"name": "git-mcp", "version": "0.1.0"},
            }
        elif method == "tools/list":
            resp["result"] = handle_list_tools()
        elif method == "tools/call":
            params = msg.get("params", {})
            resp["result"] = handle_call_tool(params.get("name"), params.get("arguments", {}))
        else:
            resp["error"] = {"code": -32601, "message": f"Method not found: {method}"}
        sys.stdout.write(json.dumps(resp, ensure_ascii=False) + "\n")
        sys.stdout.flush()


if __name__ == "__main__":
    main()
View Code

 

搜索引擎

- Google、Brave Search、Bing
- 让 Agent 具备实时联网搜索能力
- 常见项目: @modelcontextprotocol/server-brave-search

 

redis/缓存/消息队列

- Redis、RabbitMQ、Kafka
- 查看队列状态、管理缓存

 

"""
Redis/缓存 MCP Server Demo
让 Agent 能操作 Redis 缓存
依赖: pip install redis
配置: REDIS_HOST=localhost, REDIS_PORT=6379, REDIS_PASSWORD=, REDIS_DB=0
"""
import json
import sys
import os
from typing import Any

REDIS_HOST = os.environ.get("REDIS_HOST", "localhost")
REDIS_PORT = int(os.environ.get("REDIS_PORT", "6379"))
REDIS_PASSWORD = os.environ.get("REDIS_PASSWORD", "")
REDIS_DB = int(os.environ.get("REDIS_DB", "0"))


def get_redis():
    try:
        import redis
        return redis.Redis(
            host=REDIS_HOST,
            port=REDIS_PORT,
            password=REDIS_PASSWORD or None,
            db=REDIS_DB,
            decode_responses=True,
        )
    except ImportError:
        raise RuntimeError("redis not installed. Run: pip install redis")


def redis_get(key: str) -> dict:
    try:
        r = get_redis()
        value = r.get(key)
        ttl = r.ttl(key)
        return {"key": key, "value": value, "ttl": ttl}
    except Exception as e:
        return {"error": str(e)}


def redis_set(key: str, value: str, ttl: int = 0) -> dict:
    try:
        r = get_redis()
        if ttl > 0:
            r.setex(key, ttl, value)
        else:
            r.set(key, value)
        return {"key": key, "set": True}
    except Exception as e:
        return {"error": str(e)}


def redis_delete(key: str) -> dict:
    try:
        r = get_redis()
        deleted = r.delete(key)
        return {"key": key, "deleted": deleted}
    except Exception as e:
        return {"error": str(e)}


def redis_list_keys(pattern: str = "*") -> dict:
    try:
        r = get_redis()
        keys = list(r.scan_iter(pattern, count=100))
        return {"pattern": pattern, "keys": keys[:100]}
    except Exception as e:
        return {"error": str(e)}


def redis_info() -> dict:
    try:
        r = get_redis()
        info = r.info()
        return {
            "used_memory_human": info.get("used_memory_human"),
            "connected_clients": info.get("connected_clients"),
            "total_keys": r.dbsize(),
            "db": REDIS_DB,
        }
    except Exception as e:
        return {"error": str(e)}


def handle_list_tools() -> dict:
    return {
        "tools": [
            {
                "name": "redis_get",
                "description": "获取 Redis 键值",
                "inputSchema": {
                    "type": "object",
                    "properties": {"key": {"type": "string"}},
                    "required": ["key"],
                },
            },
            {
                "name": "redis_set",
                "description": "设置 Redis 键值",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "key": {"type": "string"},
                        "value": {"type": "string"},
                        "ttl": {"type": "integer", "description": "过期时间(秒),0 表示永不过期"},
                    },
                    "required": ["key", "value"],
                },
            },
            {
                "name": "redis_delete",
                "description": "删除 Redis 键",
                "inputSchema": {
                    "type": "object",
                    "properties": {"key": {"type": "string"}},
                    "required": ["key"],
                },
            },
            {
                "name": "redis_list_keys",
                "description": "列出 Redis 键(支持通配符)",
                "inputSchema": {
                    "type": "object",
                    "properties": {"pattern": {"type": "string", "default": "*"}},
                },
            },
            {
                "name": "redis_info",
                "description": "查看 Redis 状态信息",
                "inputSchema": {"type": "object", "properties": {}},
            },
        ]
    }


def handle_call_tool(name: str, arguments: dict) -> dict:
    if name == "redis_get":
        result = redis_get(arguments.get("key", ""))
    elif name == "redis_set":
        result = redis_set(arguments.get("key", ""), arguments.get("value", ""), arguments.get("ttl", 0))
    elif name == "redis_delete":
        result = redis_delete(arguments.get("key", ""))
    elif name == "redis_list_keys":
        result = redis_list_keys(arguments.get("pattern", "*"))
    elif name == "redis_info":
        result = redis_info()
    else:
        result = {"error": f"Unknown tool: {name}"}
    return {"content": [{"type": "text", "text": json.dumps(result, ensure_ascii=False)}]}


def main():
    while True:
        line = sys.stdin.readline()
        if not line:
            break
        try:
            msg = json.loads(line)
        except json.JSONDecodeError:
            continue
        method = msg.get("method")
        msg_id = msg.get("id")
        resp: dict[str, Any] = {"jsonrpc": "2.0", "id": msg_id}
        if method == "initialize":
            resp["result"] = {
                "protocolVersion": "2024-11-05",
                "capabilities": {"tools": {}},
                "serverInfo": {"name": "redis-mcp", "version": "0.1.0"},
            }
        elif method == "tools/list":
            resp["result"] = handle_list_tools()
        elif method == "tools/call":
            params = msg.get("params", {})
            resp["result"] = handle_call_tool(params.get("name"), params.get("arguments", {}))
        else:
            resp["error"] = {"code": -32601, "message": f"Method not found: {method}"}
        sys.stdout.write(json.dumps(resp, ensure_ascii=False) + "\n")
        sys.stdout.flush()


if __name__ == "__main__":
    main()
View Code

 

云服务

- AWS、Azure、Google Cloud
- 管理云资源、查看日志、部署服务
- 常见项目: @modelcontextprotocol/server-aws

 

"""
云服务 MCP Server Demo (AWS)
让 Agent 能管理 AWS 资源(EC2/S3/Lambda)
依赖: pip install boto3
配置:
  AWS_ACCESS_KEY_ID=your_key
  AWS_SECRET_ACCESS_KEY=your_secret
  AWS_REGION=us-east-1
"""
import json
import sys
import os
from typing import Any


def get_aws_client(service: str):
    try:
        import boto3
        return boto3.client(
            service,
            region_name=os.environ.get("AWS_REGION", "us-east-1"),
            aws_access_key_id=os.environ.get("AWS_ACCESS_KEY_ID", ""),
            aws_secret_access_key=os.environ.get("AWS_SECRET_ACCESS_KEY", ""),
        )
    except ImportError:
        raise RuntimeError("boto3 not installed. Run: pip install boto3")


def ec2_list_instances() -> dict:
    try:
        client = get_aws_client("ec2")
        resp = client.describe_instances()
        instances = []
        for reservation in resp.get("Reservations", []):
            for inst in reservation.get("Instances", []):
                name = ""
                for tag in inst.get("Tags", []):
                    if tag["Key"] == "Name":
                        name = tag["Value"]
                instances.append({
                    "id": inst["InstanceId"],
                    "name": name,
                    "state": inst["State"]["Name"],
                    "type": inst["InstanceType"],
                })
        return {"instances": instances}
    except Exception as e:
        return {"error": str(e)}


def s3_list_buckets() -> dict:
    try:
        client = get_aws_client("s3")
        resp = client.list_buckets()
        buckets = [{"name": b["Name"], "created": b["CreationDate"].isoformat()} for b in resp.get("Buckets", [])]
        return {"buckets": buckets}
    except Exception as e:
        return {"error": str(e)}


def s3_list_objects(bucket: str, prefix: str = "") -> dict:
    try:
        client = get_aws_client("s3")
        resp = client.list_objects_v2(Bucket=bucket, Prefix=prefix, MaxKeys=100)
        objects = []
        for obj in resp.get("Contents", []):
            objects.append({
                "key": obj["Key"],
                "size": obj["Size"],
                "last_modified": obj["LastModified"].isoformat(),
            })
        return {"bucket": bucket, "objects": objects, "count": len(objects)}
    except Exception as e:
        return {"error": str(e)}


def lambda_list_functions() -> dict:
    try:
        client = get_aws_client("lambda")
        resp = client.list_functions()
        functions = []
        for fn in resp.get("Functions", []):
            functions.append({
                "name": fn["FunctionName"],
                "runtime": fn["Runtime"],
                "last_modified": fn["LastModified"],
                "memory": fn["MemorySize"],
            })
        return {"functions": functions}
    except Exception as e:
        return {"error": str(e)}


def handle_list_tools() -> dict:
    return {
        "tools": [
            {
                "name": "ec2_list_instances",
                "description": "列出 AWS EC2 实例",
                "inputSchema": {"type": "object", "properties": {}},
            },
            {
                "name": "s3_list_buckets",
                "description": "列出 AWS S3 存储桶",
                "inputSchema": {"type": "object", "properties": {}},
            },
            {
                "name": "s3_list_objects",
                "description": "列出 S3 存储桶中的对象",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "bucket": {"type": "string"},
                        "prefix": {"type": "string", "default": ""},
                    },
                    "required": ["bucket"],
                },
            },
            {
                "name": "lambda_list_functions",
                "description": "列出 AWS Lambda 函数",
                "inputSchema": {"type": "object", "properties": {}},
            },
        ]
    }


def handle_call_tool(name: str, arguments: dict) -> dict:
    if name == "ec2_list_instances":
        result = ec2_list_instances()
    elif name == "s3_list_buckets":
        result = s3_list_buckets()
    elif name == "s3_list_objects":
        result = s3_list_objects(arguments.get("bucket", ""), arguments.get("prefix", ""))
    elif name == "lambda_list_functions":
        result = lambda_list_functions()
    else:
        result = {"error": f"Unknown tool: {name}"}
    return {"content": [{"type": "text", "text": json.dumps(result, ensure_ascii=False)}]}


def main():
    while True:
        line = sys.stdin.readline()
        if not line:
            break
        try:
            msg = json.loads(line)
        except json.JSONDecodeError:
            continue
        method = msg.get("method")
        msg_id = msg.get("id")
        resp: dict[str, Any] = {"jsonrpc": "2.0", "id": msg_id}
        if method == "initialize":
            resp["result"] = {
                "protocolVersion": "2024-11-05",
                "capabilities": {"tools": {}},
                "serverInfo": {"name": "cloud-aws-mcp", "version": "0.1.0"},
            }
        elif method == "tools/list":
            resp["result"] = handle_list_tools()
        elif method == "tools/call":
            params = msg.get("params", {})
            resp["result"] = handle_call_tool(params.get("name"), params.get("arguments", {}))
        else:
            resp["error"] = {"code": -32601, "message": f"Method not found: {method}"}
        sys.stdout.write(json.dumps(resp, ensure_ascii=False) + "\n")
        sys.stdout.flush()


if __name__ == "__main__":
    main()
View Code

 

监控(Prometheus)

- Prometheus、Grafana、Datadog
- 查询指标数据、告警状态

 

"""
监控系统 MCP Server Demo (Prometheus)
让 Agent 能查询 Prometheus 指标和告警
配置: PROMETHEUS_URL=http://localhost:9090
"""
import json
import sys
import os
import urllib.request
import urllib.parse
from typing import Any

PROMETHEUS_URL = os.environ.get("PROMETHEUS_URL", "http://localhost:9090")


def prometheus_query(query: str) -> dict:
    """执行 PromQL 即时查询"""
    url = f"{PROMETHEUS_URL}/api/v1/query?{urllib.parse.urlencode({'query': query})}"
    try:
        with urllib.request.urlopen(url, timeout=15) as resp:
            data = json.loads(resp.read().decode("utf-8"))
            if data.get("status") == "success":
                results = []
                for item in data.get("data", {}).get("result", []):
                    results.append({
                        "metric": item.get("metric", {}),
                        "value": item.get("value", [None, None])[1] if item.get("value") else None,
                    })
                return {"query": query, "results": results}
            return {"error": data.get("error", "Unknown error")}
    except Exception as e:
        return {"error": str(e)}


def prometheus_query_range(query: str, start: str, end: str, step: str = "60s") -> dict:
    """执行 PromQL 范围查询"""
    params = urllib.parse.urlencode({"query": query, "start": start, "end": end, "step": step})
    url = f"{PROMETHEUS_URL}/api/v1/query_range?{params}"
    try:
        with urllib.request.urlopen(url, timeout=30) as resp:
            data = json.loads(resp.read().decode("utf-8"))
            if data.get("status") == "success":
                results = []
                for item in data.get("data", {}).get("result", []):
                    results.append({
                        "metric": item.get("metric", {}),
                        "values": item.get("values", []),
                    })
                return {"query": query, "results": results}
            return {"error": data.get("error", "Unknown error")}
    except Exception as e:
        return {"error": str(e)}


def prometheus_alerts() -> dict:
    """获取当前告警"""
    url = f"{PROMETHEUS_URL}/api/v1/alerts"
    try:
        with urllib.request.urlopen(url, timeout=15) as resp:
            data = json.loads(resp.read().decode("utf-8"))
            alerts = []
            for alert in data.get("data", {}).get("alerts", []):
                alerts.append({
                    "name": alert.get("labels", {}).get("alertname"),
                    "state": alert.get("state"),
                    "severity": alert.get("labels", {}).get("severity"),
                    "summary": alert.get("annotations", {}).get("summary"),
                    "active_at": alert.get("activeAt"),
                })
            return {"alerts": alerts, "count": len(alerts)}
    except Exception as e:
        return {"error": str(e)}


def prometheus_targets() -> dict:
    """获取监控目标状态"""
    url = f"{PROMETHEUS_URL}/api/v1/targets"
    try:
        with urllib.request.urlopen(url, timeout=15) as resp:
            data = json.loads(resp.read().decode("utf-8"))
            targets = []
            for target in data.get("data", {}).get("activeTargets", []):
                targets.append({
                    "job": target.get("labels", {}).get("job"),
                    "instance": target.get("labels", {}).get("instance"),
                    "health": target.get("health"),
                    "last_error": target.get("lastError"),
                })
            return {"targets": targets, "count": len(targets)}
    except Exception as e:
        return {"error": str(e)}


def handle_list_tools() -> dict:
    return {
        "tools": [
            {
                "name": "prometheus_query",
                "description": "执行 PromQL 即时查询",
                "inputSchema": {
                    "type": "object",
                    "properties": {"query": {"type": "string", "description": "PromQL 表达式"}},
                    "required": ["query"],
                },
            },
            {
                "name": "prometheus_query_range",
                "description": "执行 PromQL 范围查询",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "query": {"type": "string"},
                        "start": {"type": "string", "description": "开始时间 (Unix timestamp)"},
                        "end": {"type": "string", "description": "结束时间 (Unix timestamp)"},
                        "step": {"type": "string", "default": "60s"},
                    },
                    "required": ["query", "start", "end"],
                },
            },
            {
                "name": "prometheus_alerts",
                "description": "获取当前活跃告警",
                "inputSchema": {"type": "object", "properties": {}},
            },
            {
                "name": "prometheus_targets",
                "description": "获取监控目标状态",
                "inputSchema": {"type": "object", "properties": {}},
            },
        ]
    }


def handle_call_tool(name: str, arguments: dict) -> dict:
    if name == "prometheus_query":
        result = prometheus_query(arguments.get("query", ""))
    elif name == "prometheus_query_range":
        result = prometheus_query_range(
            arguments.get("query", ""),
            arguments.get("start", ""),
            arguments.get("end", ""),
            arguments.get("step", "60s"),
        )
    elif name == "prometheus_alerts":
        result = prometheus_alerts()
    elif name == "prometheus_targets":
        result = prometheus_targets()
    else:
        result = {"error": f"Unknown tool: {name}"}
    return {"content": [{"type": "text", "text": json.dumps(result, ensure_ascii=False)}]}


def main():
    while True:
        line = sys.stdin.readline()
        if not line:
            break
        try:
            msg = json.loads(line)
        except json.JSONDecodeError:
            continue
        method = msg.get("method")
        msg_id = msg.get("id")
        resp: dict[str, Any] = {"jsonrpc": "2.0", "id": msg_id}
        if method == "initialize":
            resp["result"] = {
                "protocolVersion": "2024-11-05",
                "capabilities": {"tools": {}},
                "serverInfo": {"name": "prometheus-mcp", "version": "0.1.0"},
            }
        elif method == "tools/list":
            resp["result"] = handle_list_tools()
        elif method == "tools/call":
            params = msg.get("params", {})
            resp["result"] = handle_call_tool(params.get("name"), params.get("arguments", {}))
        else:
            resp["error"] = {"code": -32601, "message": f"Method not found: {method}"}
        sys.stdout.write(json.dumps(resp, ensure_ascii=False) + "\n")
        sys.stdout.flush()


if __name__ == "__main__":
    main()
View Code

 

AI模型

- OpenAI、Stability AI、本地模型
- 图片生成、语音合成、文本嵌入

"""
AI 模型服务 MCP Server Demo
让 Agent 能调用多种 AI 能力:文本生成、语音合成、文本嵌入
配置:
  AI_API_KEY=your_api_key
  AI_BASE_URL=https://api.openai.com/v1
  AI_MODEL=gpt-4o
  TTS_MODEL=tts-1
  TTS_VOICE=alloy
"""
import json
import sys
import os
import urllib.request
from typing import Any

API_KEY = os.environ.get("AI_API_KEY", "")
BASE_URL = os.environ.get("AI_BASE_URL", "https://api.openai.com/v1")
CHAT_MODEL = os.environ.get("AI_MODEL", "gpt-4o")
TTS_MODEL = os.environ.get("TTS_MODEL", "tts-1")
TTS_VOICE = os.environ.get("TTS_VOICE", "alloy")


def chat_completion(messages: list[dict], model: str = None, temperature: float = 0.7) -> dict:
    if not API_KEY:
        return {"error": "AI_API_KEY not set"}
    payload = {
        "model": model or CHAT_MODEL,
        "messages": messages,
        "temperature": temperature,
    }
    data = json.dumps(payload).encode("utf-8")
    req = urllib.request.Request(
        f"{BASE_URL}/chat/completions",
        data=data,
        method="POST",
        headers={
            "Content-Type": "application/json",
            "Authorization": f"Bearer {API_KEY}",
        },
    )
    try:
        with urllib.request.urlopen(req, timeout=60) as resp:
            result = json.loads(resp.read().decode("utf-8"))
            return {
                "content": result["choices"][0]["message"]["content"],
                "model": result.get("model"),
                "usage": result.get("usage"),
            }
    except Exception as e:
        return {"error": str(e)}


def text_to_speech(text: str, voice: str = None, output_file: str = "output.mp3") -> dict:
    if not API_KEY:
        return {"error": "AI_API_KEY not set"}
    payload = {
        "model": TTS_MODEL,
        "input": text,
        "voice": voice or TTS_VOICE,
        "format": "mp3",
    }
    data = json.dumps(payload).encode("utf-8")
    req = urllib.request.Request(
        f"{BASE_URL}/audio/speech",
        data=data,
        method="POST",
        headers={
            "Content-Type": "application/json",
            "Authorization": f"Bearer {API_KEY}",
        },
    )
    try:
        with urllib.request.urlopen(req, timeout=60) as resp:
            audio_data = resp.read()
            with open(output_file, "wb") as f:
                f.write(audio_data)
            return {"file": output_file, "size_bytes": len(audio_data), "text": text[:200]}
    except Exception as e:
        return {"error": str(e)}


def text_embedding(text: str, model: str = "text-embedding-3-small") -> dict:
    if not API_KEY:
        return {"error": "AI_API_KEY not set"}
    payload = json.dumps({"model": model, "input": text}).encode("utf-8")
    req = urllib.request.Request(
        f"{BASE_URL}/embeddings",
        data=payload,
        method="POST",
        headers={
            "Content-Type": "application/json",
            "Authorization": f"Bearer {API_KEY}",
        },
    )
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            result = json.loads(resp.read().decode("utf-8"))
            embedding = result["data"][0]["embedding"]
            return {"model": result.get("model"), "dimensions": len(embedding), "preview": embedding[:10]}
    except Exception as e:
        return {"error": str(e)}


def handle_list_tools() -> dict:
    return {
        "tools": [
            {
                "name": "chat_completion",
                "description": "调用大语言模型进行对话生成",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "messages": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "role": {"type": "string", "enum": ["system", "user", "assistant"]},
                                    "content": {"type": "string"},
                                },
                            },
                            "description": "对话消息列表",
                        },
                        "model": {"type": "string", "description": f"默认 {CHAT_MODEL}"},
                        "temperature": {"type": "number", "default": 0.7},
                    },
                    "required": ["messages"],
                },
            },
            {
                "name": "text_to_speech",
                "description": "将文本转换为语音",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "text": {"type": "string", "description": "要转换的文本"},
                        "voice": {"type": "string", "description": "语音角色"},
                        "output_file": {"type": "string", "default": "output.mp3"},
                    },
                    "required": ["text"],
                },
            },
            {
                "name": "text_embedding",
                "description": "生成文本的向量嵌入",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "text": {"type": "string"},
                        "model": {"type": "string", "default": "text-embedding-3-small"},
                    },
                    "required": ["text"],
                },
            },
        ]
    }


def handle_call_tool(name: str, arguments: dict) -> dict:
    if name == "chat_completion":
        result = chat_completion(
            arguments.get("messages", []),
            arguments.get("model"),
            arguments.get("temperature", 0.7),
        )
    elif name == "text_to_speech":
        result = text_to_speech(
            arguments.get("text", ""),
            arguments.get("voice"),
            arguments.get("output_file", "output.mp3"),
        )
    elif name == "text_embedding":
        result = text_embedding(arguments.get("text", ""), arguments.get("model", "text-embedding-3-small"))
    else:
        result = {"error": f"Unknown tool: {name}"}
    return {"content": [{"type": "text", "text": json.dumps(result, ensure_ascii=False)}]}


def main():
    while True:
        line = sys.stdin.readline()
        if not line:
            break
        try:
            msg = json.loads(line)
        except json.JSONDecodeError:
            continue
        method = msg.get("method")
        msg_id = msg.get("id")
        resp: dict[str, Any] = {"jsonrpc": "2.0", "id": msg_id}
        if method == "initialize":
            resp["result"] = {
                "protocolVersion": "2024-11-05",
                "capabilities": {"tools": {}},
                "serverInfo": {"name": "ai-model-mcp", "version": "0.1.0"},
            }
        elif method == "tools/list":
            resp["result"] = handle_list_tools()
        elif method == "tools/call":
            params = msg.get("params", {})
            resp["result"] = handle_call_tool(params.get("name"), params.get("arguments", {}))
        else:
            resp["error"] = {"code": -32601, "message": f"Method not found: {method}"}
        sys.stdout.write(json.dumps(resp, ensure_ascii=False) + "\n")
        sys.stdout.flush()


if __name__ == "__main__":
    main()
View Code

 

posted on 2026-07-17 14:41  colorfulworld  阅读(8)  评论(0)    收藏  举报