MCP(模型上下文协议)是一项开放标准,简化了AI模型(特别是大语言模型LLMs)与外部数据源、工具和服务之间的交互方式。MCP服务器充当这些AI模型与外部工具之间的桥梁。以下是一些主流的MCP服务器:

文件系统MCP服务器
允许大语言模型直接访问本地文件系统,进行读取、写入和创建目录等操作。
GitHub MCP服务器
将Claude连接到GitHub仓库,支持文件更新和代码搜索功能。
Slack MCP服务器
用于Slack API的MCP服务器,使Claude能够与Slack工作区进行交互。
Google Maps MCP服务器
用于Google Maps API的MCP服务器。
Docker MCP服务器
与Docker集成,用于管理容器、镜像、卷和网络。
Brave MCP服务器
使用Brave的搜索API实现网页和本地搜索功能。
PostgreSQL MCP服务器
一种MCP服务器,使大语言模型能够查看数据库结构并执行只读查询。
Google Drive MCP服务器
与Google Drive集成的MCP服务器,支持对文件进行读取和搜索。
Redis MCP服务器
提供对Redis数据库访问的MCP服务器。
Notion MCP服务器
该项目实现了针对Notion API的MCP服务器。
Stripe MCP服务器
用于与Stripe API交互的MCP服务器。
Perplexity MCP服务器
连接到Perplexity的Sonar API以实现实时搜索的MCP服务器。
MCP服务器代码示例
根据搜索结果,Model Context Protocol (MCP) 是一套允许大语言模型与外部系统交互的协议实现。以下是对您请求的各类MCP服务器的详细代码示例:
1. 文件系统MCP服务器
python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import os
import json
app = FastAPI(title="File System MCP Server")
class FileSystemRequest(BaseModel):
operation: str # read, write, mkdir, list
path: str
content: str = None
@app.post("/tool_call")
async def tool_call(request: FileSystemRequest):
"""处理文件系统操作请求"""
try:
if request.operation == "read":
if not os.path.exists(request.path):
raise HTTPException(status_code=404, detail="File not found")
with open(request.path, 'r') as f:
content = f.read()
return {"status": "success", "content": content}
elif request.operation == "write":
os.makedirs(os.path.dirname(os.path.abspath(request.path)), exist_ok=True)
with open(request.path, 'w') as f:
f.write(request.content)
return {"status": "success", "message": f"File written to {request.path}"}
elif request.operation == "mkdir":
os.makedirs(request.path, exist_ok=True)
return {"status": "success", "message": f"Directory created at {request.path}"}
elif request.operation == "list":
if not os.path.exists(request.path):
raise HTTPException(status_code=404, detail="Directory not found")
items = os.listdir(request.path)
return {"status": "success", "items": items}
else:
raise HTTPException(status_code=400, detail="Invalid operation")
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/tools")
async def get_tools():
"""返回此MCP服务器支持的工具列表"""
return {
"tools": [
{
"name": "file_system",
"description": "Access and manipulate the local file system",
"parameters": {
"operation": {"type": "string", "description": "Operation to perform (read, write, mkdir, list)"},
"path": {"type": "string", "description": "File or directory path"},
"content": {"type": "string", "description": "Content for write operations (optional)"}
}
}
]
}
这是一个基础的文件系统MCP服务器实现,允许大语言模型安全地执行基本文件操作。
2. GitHub MCP服务器
python
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
import os
from github import Github
app = FastAPI(title="GitHub MCP Server")
class GitHubRequest(BaseModel):
operation: str # get_repo, search_code, update_file
repo: str
path: str = None
content: str = None
commit_message: str = "Update via MCP"
def get_github_client():
token = os.getenv("GITHUB_TOKEN")
if not token:
raise HTTPException(status_code=401, detail="GitHub token not configured")
return Github(token)
@app.post("/tool_call")
async def tool_call(request: GitHubRequest, gh: Github = Depends(get_github_client)):
"""处理GitHub操作请求"""
try:
repo = gh.get_repo(request.repo)
if request.operation == "get_repo":
return {
"name": repo.name,
"description": repo.description,
"stars": repo.stargazers_count,
"forks": repo.forks_count
}
elif request.operation == "search_code":
results = repo.search_code(request.path) # path used as query here
return [{"path": item.path, "sha": item.sha} for item in results]
elif request.operation == "update_file":
if not request.path or not request.content:
raise HTTPException(status_code=400, detail="Path and content required for update")
contents = repo.get_contents(request.path)
repo.update_file(
request.path,
request.commit_message,
request.content,
contents.sha
)
return {"status": "success", "message": f"Updated {request.path}"}
else:
raise HTTPException(status_code=400, detail="Invalid operation")
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/tools")
async def get_tools():
"""返回此MCP服务器支持的工具列表"""
return {
"tools": [
{
"name": "github",
"description": "Interact with GitHub repositories",
"parameters": {
"operation": {"type": "string", "description": "Operation to perform (get_repo, search_code, update_file)"},
"repo": {"type": "string", "description": "Repository name (owner/repo)"},
"path": {"type": "string", "description": "File path or search query"},
"content": {"type": "string", "description": "Content for file updates"},
"commit_message": {"type": "string", "description": "Commit message for updates"}
}
}
]
}
这个GitHub MCP服务器实现了基本的仓库信息获取、代码搜索和文件更新功能,使Claude能够与GitHub仓库进行交互。
3. Slack MCP服务器
python
from fastapi import FastAPI, HTTPException, Request
from pydantic import BaseModel
import os
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
app = FastAPI(title="Slack MCP Server")
class SlackRequest(BaseModel):
operation: str # send_message, get_channels, get_messages
channel: str = None
message: str = None
limit: int = 10
def get_slack_client():
token = os.getenv("SLACK_BOT_TOKEN")
if not token:
raise HTTPException(status_code=401, detail="Slack token not configured")
return WebClient(token=token)
@app.post("/tool_call")
async def tool_call(request: SlackRequest, slack: WebClient = Depends(get_slack_client)):
"""处理Slack操作请求"""
try:
if request.operation == "send_message":
if not request.channel or not request.message:
raise HTTPException(status_code=400, detail="Channel and message required")
response = slack.chat_postMessage(
channel=request.channel,
text=request.message
)
return {"status": "success", "ts": response["ts"]}
elif request.operation == "get_channels":
response = slack.conversations_list()
return [{"id": c["id"], "name": c["name"], "is_channel": c["is_channel"]}
for c in response["channels"]]
elif request.operation == "get_messages":
if not request.channel:
raise HTTPException(status_code=400, detail="Channel required")
response = slack.conversations_history(
channel=request.channel,
limit=request.limit
)
return [{
"user": m["user"],
"text": m["text"],
"ts": m["ts"]
} for m in response["messages"]]
else:
raise HTTPException(status_code=400, detail="Invalid operation")
except SlackApiError as e:
raise HTTPException(status_code=400, detail=f"Slack API error: {e.response['error']}")
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/tools")
async def get_tools():
"""返回此MCP服务器支持的工具列表"""
return {
"tools": [
{
"name": "slack",
"description": "Interact with Slack workspace",
"parameters": {
"operation": {"type": "string", "description": "Operation to perform (send_message, get_channels, get_messages)"},
"channel": {"type": "string", "description": "Slack channel ID or name"},
"message": {"type": "string", "description": "Message content to send"},
"limit": {"type": "integer", "description": "Number of messages to retrieve (for get_messages)"}
}
}
]
}
这个Slack MCP服务器实现了与Slack工作区的基本交互功能,使AI模型能够发送消息、获取频道列表和读取消息历史。
4. Google Maps MCP服务器
python
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
import os
import googlemaps
from datetime import datetime
app = FastAPI(title="Google Maps MCP Server")
class MapsRequest(BaseModel):
operation: str # directions, geocode, places
origin: str = None
destination: str = None
address: str = None
query: str = None
location: str = None # lat,lng
def get_gmaps_client():
api_key = os.getenv("GOOGLE_MAPS_API_KEY")
if not api_key:
raise HTTPException(status_code=401, detail="Google Maps API key not configured")
return googlemaps.Client(key=api_key)
@app.post("/tool_call")
async def tool_call(request: MapsRequest, gmaps: googlemaps.Client = Depends(get_gmaps_client)):
"""处理Google Maps操作请求"""
try:
if request.operation == "directions":
if not request.origin or not request.destination:
raise HTTPException(status_code=400, detail="Origin and destination required")
now = datetime.now()
directions_result = gmaps.directions(
request.origin,
request.destination,
mode="driving",
departure_time=now
)
# 简化返回结果
return {
"status": "success",
"routes": [{
"summary": route["summary"],
"distance": route["legs"][0]["distance"]["text"],
"duration": route["legs"][0]["duration"]["text"],
"steps": [{
"html_instructions": step["html_instructions"],
"distance": step["distance"]["text"],
"duration": step["duration"]["text"]
} for step in route["legs"][0]["steps"]]
} for route in directions_result]
}
elif request.operation == "geocode":
if not request.address:
raise HTTPException(status_code=400, detail="Address required")
geocode_result = gmaps.geocode(request.address)
return {
"status": "success",
"results": [{
"formatted_address": result["formatted_address"],
"location": result["geometry"]["location"],
"types": result["types"]
} for result in geocode_result]
}
elif request.operation == "places":
if not request.query or not request.location:
raise HTTPException(status_code=400, detail="Query and location required")
places_result = gmaps.places(
query=request.query,
location=request.location,
radius=1000
)
return {
"status": "success",
"results": [{
"name": place["name"],
"formatted_address": place.get("formatted_address"),
"rating": place.get("rating"),
"geometry": place["geometry"]["location"]
} for place in places_result["results"]]
}
else:
raise HTTPException(status_code=400, detail="Invalid operation")
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/tools")
async def get_tools():
"""返回此MCP服务器支持的工具列表"""
return {
"tools": [
{
"name": "google_maps",
"description": "Access Google Maps routing, geocoding, and places data",
"parameters": {
"operation": {"type": "string", "description": "Operation to perform (directions, geocode, places)"},
"origin": {"type": "string", "description": "Starting point for directions"},
"destination": {"type": "string", "description": "Destination for directions"},
"address": {"type": "string", "description": "Address to geocode"},
"query": {"type": "string", "description": "Search query for places"},
"location": {"type": "string", "description": "Location for places search (lat,lng)"}
}
}
]
}
这个Google Maps MCP服务器提供了路线规划、地理编码和地点搜索功能,为AI模型提供地图和位置数据支持。
5. Docker MCP服务器
python
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
import docker
from typing import List, Dict, Any
app = FastAPI(title="Docker MCP Server")
class DockerRequest(BaseModel):
operation: str # list_containers, run_container, stop_container, list_images
image: str = None
command: str = None
container_id: str = None
name: str = None
environment: Dict[str, str] = None
volumes: List[str] = None
ports: Dict[str, int] = None
def get_docker_client():
try:
return docker.from_env()
except Exception as e:
raise HTTPException(status_code=500, detail=f"Could not connect to Docker: {str(e)}")
@app.post("/tool_call")
async def tool_call(request: DockerRequest, client: docker.DockerClient = Depends(get_docker_client)):
"""处理Docker操作请求"""
try:
if request.operation == "list_containers":
containers = client.containers.list(all=True)
return {
"status": "success",
"containers": [{
"id": c.id[:12],
"name": c.name,
"status": c.status,
"image": c.image.tags[0] if c.image.tags else str(c.image.id)
} for c in containers]
}
elif request.operation == "run_container":
if not request.image:
raise HTTPException(status_code=400, detail="Image name required")
container = client.containers.run(
image=request.image,
command=request.command,
name=request.name,
environment=request.environment,
volumes=request.volumes,
ports=request.ports,
detach=True
)
return {
"status": "success",
"container_id": container.id[:12],
"message": f"Container started with ID {container.id[:12]}"
}
elif request.operation == "stop_container":
if not request.container_id:
raise HTTPException(status_code=400, detail="Container ID required")
try:
container = client.containers.get(request.container_id)
container.stop()
return {
"status": "success",
"message": f"Container {request.container_id} stopped"
}
except docker.errors.NotFound:
raise HTTPException(status_code=404, detail="Container not found")
elif request.operation == "list_images":
images = client.images.list()
return {
"status": "success",
"images": [{
"id": i.id[:20],
"tags": i.tags,
"created": i.attrs['Created'],
"size": f"{i.attrs['Size'] / 1024 / 1024:.2f} MB"
} for i in images]
}
else:
raise HTTPException(status_code=400, detail="Invalid operation")
except docker.errors.APIError as e:
raise HTTPException(status_code=400, detail=f"Docker API error: {e.explanation}")
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/tools")
async def get_tools():
"""返回此MCP服务器支持的工具列表"""
return {
"tools": [
{
"name": "docker",
"description": "Manage Docker containers, images, and networks",
"parameters": {
"operation": {"type": "string", "description": "Operation to perform (list_containers, run_container, stop_container, list_images)"},
"image": {"type": "string", "description": "Docker image name"},
"command": {"type": "string", "description": "Command to run in container"},
"container_id": {"type": "string", "description": "Container ID for operations"},
"name": {"type": "string", "description": "Name for new container"},
"environment": {"type": "object", "description": "Environment variables"},
"volumes": {"type": "array", "description": "Volume mappings"},
"ports": {"type": "object", "description": "Port mappings"}
}
}
]
}
这个Docker MCP服务器实现了容器、镜像和网络的基本管理功能,使大语言模型能够与Docker环境进行交互。
6. Brave MCP服务器
python
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
import os
import requests
app = FastAPI(title="Brave Search MCP Server")
class BraveRequest(BaseModel):
operation: str # search, news
query: str
count: int = 10
country: str = "US"
language: str = "en"
def get_brave_api_key():
api_key = os.getenv("BRAVE_API_KEY")
if not api_key:
raise HTTPException(status_code=401, detail="Brave API key not configured")
return api_key
@app.post("/tool_call")
async def tool_call(request: BraveRequest, api_key: str = Depends(get_brave_api_key)):
"""处理Brave搜索操作请求"""
try:
headers = {
"Accept": "application/json",
"X-Subscription-Token": api_key
}
if request.operation == "search":
url = "https://api.search.brave.com/res/v1/web/search"
params = {
"q": request.query,
"count": request.count,
"country": request.country,
"language": request.language
}
response = requests.get(url, headers=headers, params=params)
response.raise_for_status()
data = response.json()
# 简化结果
results = []
for result in data.get("web", {}).get("results", []):
results.append({
"title": result["title"],
"url": result["url"],
"description": result["description"],
"domain": result["domain"]
})
return {"status": "success", "results": results}
elif request.operation == "news":
url = "https://api.search.brave.com/res/v1/news/search"
params = {
"q": request.query,
"count": request.count,
"country": request.country,
"language": request.language
}
response = requests.get(url, headers=headers, params=params)
response.raise_for_status()
data = response.json()
# 简化结果
results = []
for result in data.get("news", {}).get("results", []):
results.append({
"title": result["title"],
"url": result["url"],
"description": result["description"],
"source": result["source"]["name"],
"published": result["published"]
})
return {"status": "success", "results": results}
else:
raise HTTPException(status_code=400, detail="Invalid operation")
except requests.exceptions.RequestException as e:
raise HTTPException(status_code=500, detail=f"Request failed: {str(e)}")
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/tools")
async def get_tools():
"""返回此MCP服务器支持的工具列表"""
return {
"tools": [
{
"name": "brave_search",
"description": "Use Brave Search API for web and news search",
"parameters": {
"operation": {"type": "string", "description": "Operation to perform (search, news)"},
"query": {"type": "string", "description": "Search query"},
"count": {"type": "integer", "description": "Number of results to return"},
"country": {"type": "string", "description": "Country code for results"},
"language": {"type": "string", "description": "Language code for results"}
}
}
]
}
这个Brave MCP服务器实现了使用Brave搜索API进行网页和新闻搜索的功能,为AI模型提供实时搜索能力。
7. PostgreSQL MCP服务器
python
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
import os
import psycopg2
from psycopg2 import sql
from typing import List, Dict, Any
app = FastAPI(title="PostgreSQL MCP Server")
class PostgresRequest(BaseModel):
operation: str # describe, query
query: str = None
params: List[Any] = None
def get_db_connection():
conn_str = os.getenv("DATABASE_URL")
if not conn_str:
raise HTTPException(status_code=401, detail="Database connection string not configured")
try:
return psycopg2.connect(conn_str)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Database connection failed: {str(e)}")
@app.post("/tool_call")
async def tool_call(request: PostgresRequest, conn=Depends(get_db_connection)):
"""处理PostgreSQL操作请求"""
try:
if request.operation == "describe":
with conn.cursor() as cur:
# 获取所有表
cur.execute("""
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
""")
tables = [row[0] for row in cur.fetchall()]
# 获取每个表的结构
table_info = {}
for table in tables:
cur.execute(sql.SQL("""
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_name = %s
"""), [table])
columns = [{
"name": row[0],
"type": row[1],
"nullable": row[2] == "YES"
} for row in cur.fetchall()]
table_info[table] = columns
return {"status": "success", "schema": table_info}
elif request.operation == "query":
if not request.query:
raise HTTPException(status_code=400, detail="Query required")
# 确保是只读查询
if not request.query.strip().lower().startswith(("select", "explain", "with")):
raise HTTPException(status_code=403, detail="Only read-only queries are allowed")
with conn.cursor() as cur:
cur.execute(request.query, request.params or ())
columns = [desc[0] for desc in cur.description]
rows = [dict(zip(columns, row)) for row in cur.fetchall()]
return {"status": "success", "results": rows, "count": len(rows)}
else:
raise HTTPException(status_code=400, detail="Invalid operation")
except psycopg2.Error as e:
raise HTTPException(status_code=400, detail=f"Database error: {e.pgerror or str(e)}")
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
finally:
conn.close()
@app.get("/tools")
async def get_tools():
"""返回此MCP服务器支持的工具列表"""
return {
"tools": [
{
"name": "postgres",
"description": "Query PostgreSQL database with read-only access",
"parameters": {
"operation": {"type": "string", "description": "Operation to perform (describe, query)"},
"query": {"type": "string", "description": "SQL query to execute"},
"params": {"type": "array", "description": "Query parameters"}
}
}
]
}
这个PostgreSQL MCP服务器实现了数据库结构查看和只读查询功能,使大语言模型能够安全地访问数据库信息。
8. Google Drive MCP服务器
python
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
import os
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
import pickle
from typing import List, Dict, Any
app = FastAPI(title="Google Drive MCP Server")
class DriveRequest(BaseModel):
operation: str # list_files, search, get_file
query: str = None
file_id: str = None
folder_id: str = None
page_size: int = 10
def get_drive_service():
"""获取已认证的Google Drive服务客户端"""
SCOPES = ['https://www.googleapis.com/auth/drive.readonly']
creds = None
# 尝试从pickle文件加载凭证
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# 如果凭证无效,需要重新认证
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# 保存凭证以备将来使用
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('drive', 'v3', credentials=creds)
return service
@app.post("/tool_call")
async def tool_call(request: DriveRequest, service=Depends(get_drive_service)):
"""处理Google Drive操作请求"""
try:
if request.operation == "list_files":
params = {
'pageSize': request.page_size,
'fields': 'nextPageToken, files(id, name, mimeType, modifiedTime)'
}
if request.folder_id:
params['q'] = f"'{request.folder_id}' in parents and trashed=false"
results = service.files().list(**params).execute()
items = results.get('files', [])
return {
"status": "success",
"files": [{
"id": item["id"],
"name": item["name"],
"mimeType": item["mimeType"],
"modifiedTime": item["modifiedTime"]
} for item in items]
}
elif request.operation == "search":
if not request.query:
raise HTTPException(status_code=400, detail="Search query required")
query = f"({request.query}) and trashed=false"
results = service.files().list(
q=query,
pageSize=request.page_size,
fields='files(id, name, mimeType, modifiedTime)'
).execute()
items = results.get('files', [])
return {
"status": "success",
"files": [{
"id": item["id"],
"name": item["name"],
"mimeType": item["mimeType"],
"modifiedTime": item["modifiedTime"]
} for item in items]
}
elif request.operation == "get_file":
if not request.file_id:
raise HTTPException(status_code=400, detail="File ID required")
# 获取文件元数据
file = service.files().get(
fileId=request.file_id,
fields='id, name, mimeType, modifiedTime, webViewLink'
).execute()
# 对于文本文件,尝试获取内容
content = None
if file["mimeType"] == "text/plain":
request = service.files().get_media(fileId=request.file_id)
content = request.execute().decode('utf-8')
return {
"status": "success",
"file": {
"id": file["id"],
"name": file["name"],
"mimeType": file["mimeType"],
"modifiedTime": file["modifiedTime"],
"webViewLink": file["webViewLink"],
"content": content
}
}
else:
raise HTTPException(status_code=400, detail="Invalid operation")
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/tools")
async def get_tools():
"""返回此MCP服务器支持的工具列表"""
return {
"tools": [
{
"name": "google_drive",
"description": "Access Google Drive files with read-only permissions",
"parameters": {
"operation": {"type": "string", "description": "Operation to perform (list_files, search, get_file)"},
"query": {"type": "string", "description": "Search query"},
"file_id": {"type": "string", "description": "File ID for specific file operations"},
"folder_id": {"type": "string", "description": "Folder ID to list files from"},
"page_size": {"type": "integer", "description": "Number of results to return"}
}
}
]
}
这个Google Drive MCP服务器实现了文件列表、搜索和内容读取功能,使AI模型能够与Google Drive进行交互。
9. Redis MCP服务器
python
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
import os
import redis
from typing import List, Dict, Any, Optional
app = FastAPI(title="Redis MCP Server")
class RedisRequest(BaseModel):
operation: str # get, set, keys, info, hgetall
key: str = None
value: str = None
pattern: str = "*"
hash_key: str = None
def get_redis_client():
redis_url = os.getenv("REDIS_URL", "redis://localhost:6379/0")
try:
return redis.Redis.from_url(redis_url, decode_responses=True)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Redis connection failed: {str(e)}")
@app.post("/tool_call")
async def tool_call(request: RedisRequest, client: redis.Redis = Depends(get_redis_client)):
"""处理Redis操作请求"""
try:
if request.operation == "get":
if not request.key:
raise HTTPException(status_code=400, detail="Key required")
value = client.get(request.key)
if value is None:
raise HTTPException(status_code=404, detail="Key not found")
return {"status": "success", "key": request.key, "value": value}
elif request.operation == "set":
if not request.key or request.value is None:
raise HTTPException(status_code=400, detail="Key and value required")
client.set(request.key, request.value)
return {"status": "success", "message": f"Key {request.key} set successfully"}
elif request.operation == "keys":
keys = client.keys(request.pattern)
return {"status": "success", "keys": keys, "count": len(keys)}
elif request.operation == "info":
info = client.info()
# 只返回部分关键信息
safe_info = {
"server": {
"redis_version": info.get("redis_version"),
"os": info.get("os"),
"arch_bits": info.get("arch_bits")
},
"memory": {
"used_memory": info.get("used_memory"),
"used_memory_human": info.get("used_memory_human"),
"maxmemory": info.get("maxmemory"),
"maxmemory_human": info.get("maxmemory_human")
},
"clients": {
"connected_clients": info.get("connected_clients")
},
"stats": {
"total_commands_processed": info.get("total_commands_processed"),
"instantaneous_ops_per_sec": info.get("instantaneous_ops_per_sec")
}
}
return {"status": "success", "info": safe_info}
elif request.operation == "hgetall":
if not request.key:
raise HTTPException(status_code=400, detail="Key required")
value = client.hgetall(request.key)
if not value:
raise HTTPException(status_code=404, detail="Hash not found or empty")
return {"status": "success", "key": request.key, "value": value}
else:
raise HTTPException(status_code=400, detail="Invalid operation")
except redis.RedisError as e:
raise HTTPException(status_code=400, detail=f"Redis error: {str(e)}")
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/tools")
async def get_tools():
"""返回此MCP服务器支持的工具列表"""
return {
"tools": [
{
"name": "redis",
"description": "Access Redis database for key-value operations",
"parameters": {
"operation": {"type": "string", "description": "Operation to perform (get, set, keys, info, hgetall)"},
"key": {"type": "string", "description": "Redis key"},
"value": {"type": "string", "description": "Value for set operations"},
"pattern": {"type": "string", "description": "Pattern for keys search"},
"hash_key": {"type": "string", "description": "Hash key for hgetall operations"}
}
}
]
}
这个Redis MCP服务器提供了基本的Redis数据库访问功能,使大语言模型能够执行键值操作。
10. Notion MCP服务器
python
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
import os
from notion_client import Client
app = FastAPI(title="Notion MCP Server")
class NotionRequest(BaseModel):
operation: str # search, get_page, query_database
query: str = None
page_id: str = None
database_id: str = None
filter: dict = None
sorts: list = None
def get_notion_client():
token = os.getenv("NOTION_TOKEN")
if not token:
raise HTTPException(status_code=401, detail="Notion API token not configured")
return Client(auth=token)
@app.post("/tool_call")
async def tool_call(request: NotionRequest, notion: Client = Depends(get_notion_client)):
"""处理Notion操作请求"""
try:
if request.operation == "search":
if not request.query:
raise HTTPException(status_code=400, detail="Search query required")
results = notion.search(
query=request.query,
page_size=10
)
return {
"status": "success",
"results": [{
"id": item["id"],
"object": item["object"],
"title": item.get("title", [{"text": {"content": "No title"}}])[0]["text"]["content"] if item["object"] == "page" else None,
"url": item["url"],
"last_edited_time": item["last_edited_time"]
} for item in results["results"]]
}
elif request.operation == "get_page":
if not request.page_id:
raise HTTPException(status_code=400, detail="Page ID required")
page = notion.pages.retrieve(page_id=request.page_id)
# 提取基本页面信息
properties = {}
for name, prop in page["properties"].items():
if prop["type"] == "title":
properties[name] = prop["title"][0]["plain_text"] if prop["title"] else ""
elif prop["type"] == "rich_text":
properties[name] = prop["rich_text"][0]["plain_text"] if prop["rich_text"] else ""
elif prop["type"] == "number":
properties[name] = prop["number"]
# 可以添加更多属性类型处理
return {
"status": "success",
"page": {
"id": page["id"],
"url": page["url"],
"properties": properties,
"last_edited_time": page["last_edited_time"]
}
}
elif request.operation == "query_database":
if not request.database_id:
raise HTTPException(status_code=400, detail="Database ID required")
params = {"database_id": request.database_id}
if request.filter:
params["filter"] = request.filter
if request.sorts:
params["sorts"] = request.sorts
results = notion.databases.query(**params)
# 简化结果
items = []
for item in results["results"]:
properties = {}
for name, prop in item["properties"].items():
if prop["type"] == "title":
properties[name] = prop["title"][0]["plain_text"] if prop["title"] else ""
elif prop["type"] == "rich_text":
properties[name] = prop["rich_text"][0]["plain_text"] if prop["rich_text"] else ""
elif prop["type"] == "select":
properties[name] = prop["select"]["name"] if prop["select"] else None
# 可以添加更多属性类型处理
items.append({
"id": item["id"],
"properties": properties,
"url": item["url"]
})
return {"status": "success", "items": items, "total": len(items)}
else:
raise HTTPException(status_code=400, detail="Invalid operation")
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/tools")
async def get_tools():
"""返回此MCP服务器支持的工具列表"""
return {
"tools": [
{
"name": "notion",
"description": "Interact with Notion pages and databases",
"parameters": {
"operation": {"type": "string", "description": "Operation to perform (search, get_page, query_database)"},
"query": {"type": "string", "description": "Search query"},
"page_id": {"type": "string", "description": "Notion page ID"},
"database_id": {"type": "string", "description": "Notion database ID"},
"filter": {"type": "object", "description": "Query filters for databases"},
"sorts": {"type": "array", "description": "Sort criteria for database queries"}
}
}
]
}
这个Notion MCP服务器实现了与Notion API的基本交互功能,使AI模型能够搜索内容、获取页面和查询数据库。
11. Stripe MCP服务器
python
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
import os
import stripe
from typing import List, Dict, Any
app = FastAPI(title="Stripe MCP Server")
class StripeRequest(BaseModel):
operation: str # list_customers, get_customer, create_customer, list_payments
customer_id: str = None
email: str = None
name: str = None
limit: int = 10
def get_stripe_client():
stripe.api_key = os.getenv("STRIPE_SECRET_KEY")
if not stripe.api_key:
raise HTTPException(status_code=401, detail="Stripe API key not configured")
return stripe
@app.post("/tool_call")
async def tool_call(request: StripeRequest, stripe_client: stripe = Depends(get_stripe_client)):
"""处理Stripe操作请求"""
try:
if request.operation == "list_customers":
customers = stripe_client.Customer.list(limit=request.limit)
return {
"status": "success",
"customers": [{
"id": c.id,
"name": c.name,
"email": c.email,
"created": c.created
} for c in customers.data]
}
elif request.operation == "get_customer":
if not request.customer_id:
raise HTTPException(status_code=400, detail="Customer ID required")
customer = stripe_client.Customer.retrieve(request.customer_id)
return {
"status": "success",
"customer": {
"id": customer.id,
"name": customer.name,
"email": customer.email,
"description": customer.description,
"created": customer.created,
"metadata": customer.metadata
}
}
elif request.operation == "create_customer":
if not request.email:
raise HTTPException(status_code=400, detail="Email required")
customer = stripe_client.Customer.create(
email=request.email,
name=request.name
)
return {
"status": "success",
"customer": {
"id": customer.id,
"name": customer.name,
"email": customer.email
}
}
elif request.operation == "list_payments":
params = {"limit": request.limit}
if request.customer_id:
params["customer"] = request.customer_id
payments = stripe_client.PaymentIntent.list(**params)
return {
"status": "success",
"payments": [{
"id": p.id,
"amount": p.amount,
"currency": p.currency,
"status": p.status,
"customer": p.customer,
"created": p.created
} for p in payments.data]
}
else:
raise HTTPException(status_code=400, detail="Invalid operation")
except stripe.error.StripeError as e:
raise HTTPException(status_code=400, detail=f"Stripe error: {e.user_message or str(e)}")
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/tools")
async def get_tools():
"""返回此MCP服务器支持的工具列表"""
return {
"tools": [
{
"name": "stripe",
"description": "Interact with Stripe payment API",
"parameters": {
"operation": {"type": "string", "description": "Operation to perform (list_customers, get_customer, create_customer, list_payments)"},
"customer_id": {"type": "string", "description": "Stripe customer ID"},
"email": {"type": "string", "description": "Customer email address"},
"name": {"type": "string", "description": "Customer name"},
"limit": {"type": "integer", "description": "Number of results to return"}
}
}
]
}
这个Stripe MCP服务器实现了客户管理和支付操作的基本功能,使AI模型能够与Stripe支付系统进行交互。
12. Perplexity MCP服务器
python
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
import os
import requests
from typing import List, Dict, Any
app = FastAPI(title="Perplexity MCP Server")
class PerplexityRequest(BaseModel):
operation: str # search, conversation
query: str
mode: str = "concise" # concise, copilot
conversation_id: str = None
messages: List[Dict[str, str]] = None
def get_perplexity_api_key():
api_key = os.getenv("PERPLEXITY_API_KEY")
if not api_key:
raise HTTPException(status_code=401, detail="Perplexity API key not configured")
return api_key
@app.post("/tool_call")
async def tool_call(request: PerplexityRequest, api_key: str = Depends(get_perplexity_api_key)):
"""处理Perplexity操作请求"""
try:
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
if request.operation == "search":
url = "https://api.perplexity.ai/chat/completions"
payload = {
"model": "pplx-7b-online" if request.mode == "copilot" else "pplx-7b-chat",
"messages": [{"role": "user", "content": request.query}]
}
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
data = response.json()
# 提取回答和来源
answer = data["choices"][0]["message"]["content"]
# 尝试提取来源(Perplexity响应中可能包含)
sources = []
if "citations" in data:
sources = [{"title": c["title"], "url": c["url"]} for c in data["citations"]]
elif "references" in
sources = [{"title": r["title"], "url": r["url"]} for r in data["references"]]
return {
"status": "success",
"answer": answer,
"sources": sources,
"model": data["model"]
}
elif request.operation == "conversation":
url = "https://api.perplexity.ai/chat/completions"
# 构建对话消息
messages = []
if request.conversation_id:
# 在实际实现中,这里应该从数据库获取之前的对话历史
# 为简化示例,我们假设消息已提供
messages = request.messages or [{"role": "system", "content": "You are a helpful assistant."}]
else:
messages = [{"role": "system", "content": "You are a helpful assistant."}]
messages.append({"role": "user", "content": request.query})
payload = {
"model": "pplx-7b-online" if request.mode == "copilot" else "pplx-7b-chat",
"messages": messages
}
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
data = response.json()
# 提取回答
answer = data["choices"][0]["message"]["content"]
return {
"status": "success",
"answer": answer,
"conversation_id": request.conversation_id or "new_conversation",
"model": data["model"]
}
else:
raise HTTPException(status_code=400, detail="Invalid operation")
except requests.exceptions.RequestException as e:
raise HTTPException(status_code=500, detail=f"Request failed: {str(e)}")
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/tools")
async def get_tools():
"""返回此MCP服务器支持的工具列表"""
return {
"tools": [
{
"name": "perplexity",
"description": "Use Perplexity AI for real-time web search and conversational responses",
"parameters": {
"operation": {"type": "string", "description": "Operation to perform (search, conversation)"},
"query": {"type": "string", "description": "Search or conversation query"},
"mode": {"type": "string", "description": "Response mode (concise, copilot)"},
"conversation_id": {"type": "string", "description": "ID of existing conversation"},
"messages": {"type": "array", "description": "Conversation history for context"}
}
}
]
}
这个Perplexity MCP服务器实现了连接到Perplexity的Sonar API,提供实时搜索和对话功能,使AI模型能够获取最新的网络信息。
总结
以上代码示例展示了各种MCP服务器的实现,这些服务器作为Model Context Protocol的实现,使大语言模型能够与外部系统安全交互。
每个MCP服务器都遵循类似的结构:
- 实现
/tools
端点,描述可用的工具 - 实现
/tool_call
端点,处理具体的工具调用请求 - 提供适当的错误处理和安全措施
这些实现都是基础示例,实际部署时需要考虑:
- 更严格的认证和授权机制
- 请求限制和配额管理
- 详细的日志记录
- 错误处理和重试策略
- 性能优化
这些MCP服务器可以作为扩展AI能力的基础,通过文件访问、数据库连接和API集成等方式增强模型的功能。