使用说明
数字广告远程MCP
数字广告MCP服务器的远程部署包装器。目前支持:
- 谷歌广告MCP →
/googleads/mcp - 谷歌分析MCP →
/analytics/mcp - Facebook广告MCP →
/facebookads/mcp - TikTok广告MCP →
/tiktok/mcp
特性
- HTTP JSON-RPC传输:基于云原生HTTP的MCP服务器
- 无状态架构:无会话存储,可扩展到零
- API密钥验证:通过API密钥验证客户端
- 按请求凭据:用户提供自己的平台特定凭据(例如,Google Ads开发者令牌)
- 多云就绪:部署到任何容器平台
- 自动更新:使用git子模块跟踪上游变化
建筑
此存储库封装了数字广告MCP服务器(例如 google-ads-mcp)作为git子模块并添加:
- 远程服务器传输(HTTP JSON-RPC)
- 身份验证层(API密钥)
- 凭证注入(按请求平台凭证)
- 容器部署配置
本地开发
# Clone with submodule
git clone --recurse-submodules <your-repo-url>
cd digital-ads-remote-mcp
# Build Docker image
docker build -t digital-ads-remote-mcp .
# Run locally for testing
docker run -p 8080:8080 \
-e ALLOWED_API_KEYS="test-key-1,test-key-2" \
-e GOOGLE_APPLICATION_CREDENTIALS="/path/to/credentials.json" \
-v /path/to/credentials.json:/path/to/credentials.json:ro \
digital-ads-remote-mcp
部署
谷歌云运行
# Build and push to Google Container Registry
gcloud builds submit --tag gcr.io/PROJECT_ID/digital-ads-remote-mcp
# Deploy to Cloud Run
gcloud run deploy digital-ads-remote-mcp \
--image=gcr.io/PROJECT_ID/digital-ads-remote-mcp \
--platform=managed \
--region=us-central1 \
--allow-unauthenticated \
--set-env-vars=ALLOWED_API_KEYS="key1,key2"
AWS Fargate
# Build and push to ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com
docker build -t digital-ads-remote-mcp .
docker tag digital-ads-remote-mcp:latest ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/digital-ads-remote-mcp:latest
docker push ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/digital-ads-remote-mcp:latest
# Deploy via AWS CLI (ensure task definition and service exist)
aws ecs update-service \
--cluster your-cluster \
--service digital-ads-remote-mcp \
--force-new-deployment
Azure容器应用
# Build and push to Azure Container Registry
az acr build --registry YOUR_ACR_NAME --image digital-ads-remote-mcp:latest .
# Deploy to Azure Container Apps
az containerapp create \
--name digital-ads-remote-mcp \
--resource-group YOUR_RESOURCE_GROUP \
--environment YOUR_CONTAINER_APP_ENV \
--image YOUR_ACR_NAME.azurecr.io/digital-ads-remote-mcp:latest \
--target-port 8080 \
--ingress external \
--env-vars ALLOWED_API_KEYS="key1,key2"
加密设置
环境变量可以使用带有secp256k1的ECIES(椭圆曲线集成加密方案)进行加密。
生成密钥对
# Install eciespy (uses coincurve under the hood)
pip install eciespy
# Generate a new key pair
python3 -c "
from coincurve import PrivateKey
import secrets
sk = PrivateKey(secrets.token_bytes(32))
print(f'Private key (keep secret): {sk.secret.hex()}')
print(f'Public key (for clients): {sk.public_key.format(False).hex()}')
"
# Derive public key from an existing hex private key
python3 -c "
from coincurve import PrivateKey
private_key_hex = 'YOUR_PRIVATE_KEY_HEX'
sk = PrivateKey(bytes.fromhex(private_key_hex))
print(sk.public_key.format(False).hex())
"
加密值(客户端)
# Encrypt a string
python3 -c "
import ecies
import base64
import sys
public_key = 'YOUR_PUBLIC_KEY_HEX'
plaintext = sys.argv[1]
ciphertext = ecies.encrypt(public_key, plaintext.encode())
print(base64.urlsafe_b64encode(ciphertext).decode().rstrip('='))
" "your-secret-value"
# Encrypt a file
python3 -c "
import ecies
import base64
import sys
public_key = 'YOUR_PUBLIC_KEY_HEX'
with open(sys.argv[1], 'rb') as f:
content = f.read()
ciphertext = ecies.encrypt(public_key, content)
print(base64.urlsafe_b64encode(ciphertext).decode().rstrip('='))
" credentials.json
客户端配置
环境变量通过带有类型前缀的查询参数传递:
| 前缀 | 描述 | 示例 |
|---|---|---|
PLAIN_ |
明文值 | ?PLAIN_FOO=bar → FOO=bar |
FILE_ |
写入临时文件的内容 | ?FILE_CREDS={} → CREDS=/tmp/xxx.json |
ENC_ |
加密值(base64url) | ?ENC_TOKEN=abc... → TOKEN=decrypted |
ENCFILE_ |
将内容加密到临时文件 | ?ENCFILE_CREDS=abc... → CREDS=/tmp/xxx.json |
MCP客户端配置
{
"mcpServers": {
"google-ads": {
"url": "https://your-service-url/googleads/mcp?api_key=your-api-key&ENC_GOOGLE_ADS_DEVELOPER_TOKEN=abc123...&PLAIN_GOOGLE_ADS_LOGIN_CUSTOMER_ID=1234567890",
"transport": "http"
},
"google-analytics": {
"url": "https://your-service-url/analytics/mcp?api_key=your-api-key&ENCFILE_GOOGLE_APPLICATION_CREDENTIALS=xyz789...",
"transport": "http"
},
"facebook-ads": {
"url": "https://your-service-url/facebookads/mcp?api_key=your-api-key&ENC_FB_ACCESS_TOKEN=abc123...",
"transport": "http"
},
"tiktok-ads": {
"url": "https://your-service-url/tiktok/mcp?api_key=your-api-key&ENC_TIKTOK_APP_ID=...&ENC_TIKTOK_SECRET=...&ENC_TIKTOK_ACCESS_TOKEN=...",
"transport": "http"
}
}
}
必需参数
谷歌广告MCP (/googleads/mcp):
GOOGLE_ADS_DEVELOPER_TOKEN:您的Google Ads API开发者代币GOOGLE_ADS_LOGIN_CUSTOMER_ID:(可选)经理客户IDGOOGLE_APPLICATION_CREDENTIALS:(可选)服务帐户JSON路径(使用FILE_或ENCFILE_前缀)
谷歌分析MCP (/analytics/mcp):
GOOGLE_APPLICATION_CREDENTIALS:服务帐户JSON路径(使用FILE_或ENCFILE_前缀)GOOGLE_PROJECT_ID:谷歌云项目IDANALYTICS_PROPERTY_ID:(可选)默认GA4属性ID
Facebook广告MCP (/facebookads/mcp):
FB_ACCESS_TOKEN:Facebook用户访问令牌ads_read许可(必填)
TikTok广告MCP (/tiktok/mcp):
-
TIKTOK_APP_ID:TikTok for Business应用程序ID(必填) -
TIKTOK_SECRET:TikTok for Business应用程序机密(必填) -
TIKTOK_ACCESS_TOKEN:来自TikTok OAuth流的长期访问令牌(必需) -
TIKTOK_ADVERTISER_ID:(可选)存储在后端配置中(使用PLAIN_前缀)。注意:当前的读取工具仍然需要显式advertiser_id每次调用的参数,因此这还不能作为自动默认值。 -
TIKTOK_SANDBOX:(可选)true以沙箱API为目标(使用PLAIN_前缀)只读服务器。生成URL
./generate-url.sh tiktok(提示 三个凭证,ECIES对其进行加密)。
保持最新
MCP服务器作为git子模块包含在内。要更新,请执行以下操作:
# Update all submodules to latest version
git submodule update --remote
# Commit the updates
git add google-ads-mcp google-analytics-mcp facebook-ads-mcp tiktok-ads-mcp
git commit -m "Update MCP submodules to latest"
# Redeploy to your platform
环境变量
服务器端环境变量:
ALLOWED_API_KEYS:以逗号分隔的有效API密钥列表ECIES_PRIVATE_KEY:用于解密的十六进制编码的secp256k1私钥ENC_*和ENCFILE_*参数
安全考虑
- API密钥:存储在平台的秘密管理器中,定期轮换
- 开发者代币:从不在服务器端存储,按请求传递
- 仅限HTTPS:确保您的平台强制使用HTTPS
- 服务账号:使用最低权限访问Google Ads API
- 跨域资源共享:配置
allow_origins生产中
运输
服务器说话 MCP流式HTTP 运输在 POST /{service}/mcp.
会话状态通过以下方式跟踪 Mcp-Session-Id 响应/请求标头:
- 第一个请求(
initialize)发送时没有会话标头。Env注射 查询参数(PLAIN_*,FILE_*,ENC_*,ENCFILE_*)在这里阅读和 配置生成的stdio子进程。 - 服务器返回一个
Mcp-Session-Id头球所有后续请求 该会议必须包括它。 DELETE /{service}/mcp使用header关闭会话。
响应返回为 text/event-stream;决赛将带来
JSON-RPC响应。仅通知请求返回 202 Accepted.
测试
# Health check
curl https://your-service-url/health
# Initialize (captures the Mcp-Session-Id from response headers)
SID=$(curl -sD - -o /dev/null \
-X POST "https://your-service-url/googleads/mcp?api_key=your-api-key&PLAIN_GOOGLE_ADS_DEVELOPER_TOKEN=your-dev-token" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}' \
| awk 'tolower($1)=="mcp-session-id:"{print $2}' | tr -d '\r')
# Subsequent calls reuse the session id via the header
curl -X POST "https://your-service-url/googleads/mcp?api_key=your-api-key" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SID" \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'
curl -X POST "https://your-service-url/googleads/mcp?api_key=your-api-key" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SID" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
# Close the session
curl -X DELETE "https://your-service-url/googleads/mcp?api_key=your-api-key" \
-H "Mcp-Session-Id: $SID"
故障排除
- 401未经授权:检查
api_key查询参数匹配ALLOWED_API_KEYS - 400无效参数:检查加密/解密-确保
ECIES_PRIVATE_KEY已设置 - 500内部错误:检查容器日志中的MCP或API错误
许可证
Apache 2.0/MIT(与上游MCP服务器相同: 谷歌广告mcp, 谷歌分析mcp, 脸书广告mcp, tiktok广告mcp)