关于 Ghostfolio MCP
Ghostfolio MCP 是连接 Ghostfolio 投资组合平台的 Python MCP 服务,面向需要通过 AI Agent 查询或管理投资数据的用户。它同时支持读写操作,并可配置只读模式、工具筛选和访问限制。
主要功能
- 01查询持仓、表现、股息与收益
- 02管理账户、交易和余额
- 03获取市场数据并查找证券代码
- 04导入交易并导出组合数据
- 05只读模式与按标签筛选工具
适用场景
- 01汇总并分析投资组合表现
- 02跟踪账户交易、余额和股息
- 03批量导入历史交易记录
MCP 相关
它向 MCP 客户端提供 Ghostfolio 投资组合、账户、交易、基准、观察列表及市场数据相关工具,并支持读取和写入操作。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx ghostfolio-mcpGHOSTFOLIO_URLGhostfolio base URL (e.g., https://domain.tld:3333)GHOSTFOLIO_TOKEN密钥Ghostfolio API token for authenticationGHOSTFOLIO_VERIFY_SSLVerify SSL certificates (true/false)GHOSTFOLIO_TIMEOUTRequest timeout in secondsREAD_ONLY_MODEEnable read-only mode to restrict write operationsGHOSTFOLIO_DISABLED_TAGSComma-separated list of tags to disable tools forLOG_LEVELLogging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)RATE_LIMIT_ENABLEDEnable rate limitingRATE_LIMIT_MAX_REQUESTSMaximum requests per rate limit windowRATE_LIMIT_WINDOW_MINUTESRate limit window in minutesTOOL_SEARCH_ENABLEDEnable FastMCP tool search transformTOOL_SEARCH_STRATEGYTool search strategy (bm25 or regex)TOOL_SEARCH_MAX_RESULTSMaximum tool search results returned by search_toolsMCP_HTTP_PORTPort for HTTP server (default: 8000)MCP_TRANSPORTMCP transport type: stdio, sse, or http (alias: streamable-http)本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
38收录的工具列表 · 更新于 4 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| account_id | string | 是 | 要获取余额的账户 ID |
详细介绍
Ghostfolio MCP 服务是一个基于 Python 的模型上下文协议(MCP)服务,旨在为 Ghostfolio 投资组合管理和金融数据提供高级、可编程的访问方式。它提供现代化 API,可通过 Ghostfolio 的全面功能查询、分析和管理你的投资组合。该服务支持读写操作,具备强大的安全功能,适用于与自动化工具、金融仪表板和自定义投资组合管理应用程序集成。
✨ 功能
核心功能
- 使用灵活的时间范围查询投资组合表现、持仓和头寸
- 获取全面的投资数据,包括股息、回报和资产配置
- 访问详细的市场数据、资产简介和历史价格信息
- 监控投资组合指标、基准和表现对比
- 跟踪多个账户中的订单、交易和账户余额
- 搜索和查找金融代码、股票、ETF 及其他资产
- 获取用户信息、设置和账户详情
管理操作
- 创建和管理使用不同货币和平台的投资账户
- 创建、删除和管理单笔交易及活动
- 从其他平台导入交易和历史数据
- 配置只读模式,以限制所有写入操作,实现安全监控
- 支持批量导入交易和管理投资组合数据
- 监控系统运行状况和平台可用性
高级功能
- 速率限制和 API 安全功能
- 实时投资组合监控和表现跟踪
- 全面的日志记录和审计跟踪
- 支持 SSL/TLS 和可配置超时
- 可通过自定义中间件和基于标签的工具筛选进行扩展
- 为大型工具目录提供可选的工具搜索转换功能
- HTTP 传输支持 Bearer 令牌或 OIDC/OAuth 身份验证
🚀 安装
前提条件
- Python 3.11 至 3.15
- 可访问 Ghostfolio 实例
- 有效的 Ghostfolio API 令牌
从 PyPI 快速安装
最简单的入门方式是从 PyPI 安装:
# Using UV (recommended)
uvx ghostfolio-mcp
# Or using pip
pip install ghostfolio-mcp
运行服务前,请记得为你的 Ghostfolio 实例配置环境变量:
# Create environment configuration
export GHOSTFOLIO_URL=https://domain.tld:3333
export GHOSTFOLIO_TOKEN=your-ghostfolio-token
更多详情,请访问:https://pypi.org/project/ghostfolio-mcp/
从源代码安装
- 克隆仓库:
git clone https://github.com/mhajder/ghostfolio-mcp.git
cd ghostfolio-mcp
- 安装依赖项:
# Using UV (recommended)
uv sync
# Or using pip
pip install -e .
- 配置环境变量:
cp .env.example .env
# Edit .env with your Ghostfolio URL and token
- 运行服务:
# Using UV (recommended)
uv run ghostfolio-mcp
# Or using the installed command directly
ghostfolio-mcp
开发环境设置
使用其他工具进行开发:
# Clone and install with development dependencies
git clone https://github.com/mhajder/ghostfolio-mcp.git
cd ghostfolio-mcp
uv sync --group dev
# Run tests
uv run pytest
# Run with coverage
uv run pytest --cov=src/
# Run linting and formatting
uv run ruff check .
uv run ruff format .
# Run type checking
uv run ty check .
# Setup prek hooks
uv run prek install
🔧 配置
环境变量
空值或仅包含空白字符的值会被视为未设置,并使用默认值。
布尔设置接受 true/false、1/0、yes/no 和 on/off(不区分大小写)。
任何其他值都会导致服务在启动时停止,因此拼写错误不会在无提示的情况下关闭只读模式或 TLS 验证。
# Ghostfolio Connection Details
GHOSTFOLIO_URL=https://domain.tld:3333
GHOSTFOLIO_TOKEN=your-ghostfolio-token
# SSL Configuration
GHOSTFOLIO_VERIFY_SSL=true
GHOSTFOLIO_TIMEOUT=30
# Read-Only Mode
# Set READ_ONLY_MODE true to disable all write operations (put, post, delete)
READ_ONLY_MODE=false
# Disabled Tags
# Comma-separated list of tags to disable tools for (empty by default)
# Example: GHOSTFOLIO_DISABLED_TAGS=portfolio,symbol
GHOSTFOLIO_DISABLED_TAGS=
# Logging Configuration
LOG_LEVEL=INFO
# Rate Limiting (requests per minute)
# Set RATE_LIMIT_ENABLED true to enable rate limiting
RATE_LIMIT_ENABLED=false
RATE_LIMIT_MAX_REQUESTS=60
RATE_LIMIT_WINDOW_MINUTES=1
# Tool Search Transform (Optional)
# Set TOOL_SEARCH_ENABLED true to replace full tool listings with search_tools + call_tool
TOOL_SEARCH_ENABLED=false
# Search strategy: bm25 (natural language) or regex (pattern match)
TOOL_SEARCH_STRATEGY=bm25
# Maximum number of tools returned by search_tools
TOOL_SEARCH_MAX_RESULTS=5
# Sentry Error Tracking (Optional)
# Set SENTRY_DSN to enable error tracking and performance monitoring
# SENTRY_DSN=https://[email protected]/6789
# Optional Sentry configuration
# SENTRY_TRACES_SAMPLE_RATE=1.0
# SENTRY_SEND_DEFAULT_PII=false
# SENTRY_ENVIRONMENT=production
# SENTRY_RELEASE=1.2.3
# SENTRY_PROFILE_SESSION_SAMPLE_RATE=1.0
# SENTRY_PROFILE_LIFECYCLE=trace
# SENTRY_ENABLE_LOGS=true
# MCP Transport Configuration
# Transport type: 'stdio' (default), 'sse' (Server-Sent Events), or 'http' (HTTP Streamable)
# 'streamable-http' is accepted as an alias for 'http'. Any other value stops
# the server at startup.
MCP_TRANSPORT=stdio
# HTTP Transport Settings (used when MCP_TRANSPORT=sse or MCP_TRANSPORT=http)
# Host to bind the HTTP server (default: 127.0.0.1)
# MCP_HTTP_HOST=127.0.0.1
# Port to bind the HTTP server (default: 8000)
# MCP_HTTP_PORT=8000
# Optional bearer token for authentication (leave empty for no auth)
# MCP_HTTP_BEARER_TOKEN=
# OIDC / OAuth Authentication (optional, for remote hosting)
# Set all four to enable; takes precedence over MCP_HTTP_BEARER_TOKEN
# OIDC_CONFIG_URL=https://id.example.com/.well-known/openid-configuration
# OIDC_CLIENT_ID=
# OIDC_CLIENT_SECRET=
# OIDC_BASE_URL=https://ghostfolio-mcp.example.com
# Optional OIDC settings
# OIDC_REDIRECT_PATH=/auth/callback
# OIDC_REQUIRED_SCOPES=
# OIDC_ALLOWED_REDIRECT_URIS=
# OIDC_VERIFY_ID_TOKEN=false
# OIDC_FORWARD_RESOURCE=false
Sentry 错误跟踪与监控(可选)
服务可选择使用 Sentry 进行错误跟踪、性能监控和调试。Sentry 集成完全可选,仅在完成配置后才会初始化。
安装
如需启用 Sentry 监控,请安装可选依赖项:
# Using UV (recommended)
uv sync --extra sentry
配置
在 .env 文件中设置 SENTRY_DSN 环境变量以启用 Sentry:
# Required: Sentry DSN for your project
SENTRY_DSN=https://[email protected]/6789
# Optional: Performance monitoring sample rate (0.0-1.0, default: 1.0)
SENTRY_TRACES_SAMPLE_RATE=1.0
# Optional: Include personally identifiable information (default: false).
# When true, tool inputs and outputs (portfolio data) are sent to Sentry.
SENTRY_SEND_DEFAULT_PII=false
# Optional: Environment name (e.g., "production", "staging")
SENTRY_ENVIRONMENT=production
# Optional: Release version (auto-detected from package if not set)
SENTRY_RELEASE=1.2.2
# Optional: Profiling - continuous profiling sample rate (0.0-1.0, default: 1.0)
SENTRY_PROFILE_SESSION_SAMPLE_RATE=1.0
# Optional: Profiling - lifecycle mode for profiling (default: "trace")
# Options: "all", "continuation", "trace"
SENTRY_PROFILE_LIFECYCLE=trace
# Optional: Enable log capture as breadcrumbs and events (default: true)
SENTRY_ENABLE_LOGS=true
功能
启用后,Sentry 会自动捕获:
- 异常与错误:所有未处理的异常及其完整上下文
- 性能指标:请求/响应时间和跟踪信息
- MCP 集成:MCP 服务活动和交互的详细信息
- 日志与面包屑:用于调试的应用程序日志和事件轨迹
- 上下文数据:环境、客户端信息和请求参数
获取 Sentry DSN
- 在 sentry.io 创建免费账户
- 创建一个新的 Python 项目
- 从项目设置中复制 DSN
- 将其设置在
.env文件中
禁用 Sentry
Sentry 完全可选。如果未设置 SENTRY_DSN,服务将正常运行,不会集成 Sentry,也不会收集任何监控数据。
🧰 可用工具
账户管理工具
get_accounts:获取投资组合中的所有账户,包括账户类型和余额get_account_balances:获取指定账户的余额create_account:在投资组合中创建新账户delete_account:从投资组合中删除现有账户(破坏性操作)get_account_details:获取指定账户的详细信息update_account:更新现有账户的设置或详细信息transfer_account_balance:在两个账户之间转移现金余额create_account_balance:为账户余额历史记录中的指定日期设置余额(默认为今天)delete_account_balance:从账户余额历史记录中删除单条记录
投资组合与交易管理工具
get_portfolio_performance:获取投资组合表现数据,包括回报、基准和表现指标get_portfolio_holdings:获取投资组合的持仓和头寸,包括配置和资产明细get_portfolio_details:获取全面的投资组合详情,包括账户、头寸和摘要get_position:从数据源获取指定代码的头寸详情get_investments:按时间段分组获取投资数据,显示现金流和投入金额get_dividends:按时间段分组获取股息数据,显示股息支付和收益率get_orders:获取投资组合中的所有活动/订单,可按账户筛选create_activity:在投资组合中创建一笔新交易/活动(BUY、SELL、DIVIDEND、INTEREST、FEE 等),可选择添加标签update_activity:更新现有活动/交易及其标签;未传入的字段将保留当前值delete_activity:按 ID 删除单条活动/交易(破坏性操作)
基准工具
get_benchmarks:获取所有已配置的基准get_benchmark_performance:从指定日期开始,将投资组合表现与基准代码进行比较
自选列表工具
get_watchlist:获取用户自选列表中的所有项目add_to_watchlist:将一个代码添加到用户的自选列表remove_from_watchlist:从用户的自选列表中移除一个代码
汇率工具
get_exchange_rate:获取特定日期指定货币代码的汇率
数据导出工具
export_portfolio:以 JSON 格式导出投资组合活动/交易数据
市场数据和代码工具
get_market_data_for_asset:获取特定资产的市场数据add_market_data_points:为资产添加一个或多个市场数据点(通常使用MANUAL数据源 — Ghostfolio 会拒绝写入自动获取的数据源)get_symbol_data:从数据源获取特定资产的代码数据get_historical_data:获取特定代码在特定日期的历史数据lookup_symbols:使用查询字符串搜索代码get_asset_profile:获取特定代码的资产简介信息upsert_asset_profile:创建或更新资产简介,包括可选的countries和sectors配置(具有幂等性;可容忍 Ghostfolio 在创建步骤中返回 HTTP 500,并以随后执行的 PATCH 作为事实来源)delete_asset_profile:删除资产简介(破坏性操作;根据后端规则,可能会删除关联的活动和市场数据)
数据导入工具
import_transactions:将交易导入投资组合(批量导入操作)get_dividends_for_import:获取特定代码的历史股息数据,并将其格式化以供导入
系统和平台工具
get_health:获取 Ghostfolio 后端服务的系统健康状态get_platforms:获取可用于账户跟踪的平台列表(经纪商、交易所等)
用户管理工具
get_user_info:获取用户信息和设置
🔒 安全与防护功能
只读模式
服务器支持只读模式,可禁用所有写入操作,以便安全地进行监控:
READ_ONLY_MODE=true
启用后,此模式会阻止对投资组合数据进行任何修改,同时仍允许完整读取所有信息。
基于标签的工具筛选
你可以通过设置禁用标签来停用特定类别的工具:
GHOSTFOLIO_DISABLED_TAGS=portfolio,symbol,import
可用标签包括:
account- 账户管理工具(创建、删除、更新和获取账户)portfolio- 投资组合分析和表现工具symbol- 代码查询和数据工具import- 数据导入工具asset- 资产简介工具user- 用户信息工具system- 系统健康和平台信息工具activities- 活动/交易管理工具(创建、更新和删除活动)watchlist- 自选列表管理工具exchange-rate- 货币汇率工具export- 数据导出工具benchmark- 基准工具
速率限制
服务器支持速率限制,以控制 API 使用并防止滥用。启用后,服务器会使用滑动窗口算法,按客户端限制请求数量。
在 .env 文件中设置以下环境变量即可启用速率限制:
RATE_LIMIT_ENABLED=true
RATE_LIMIT_MAX_REQUESTS=60 # Maximum requests allowed per window
RATE_LIMIT_WINDOW_MINUTES=1 # Window size in minutes
如果将 RATE_LIMIT_ENABLED 设置为 true,服务器将启用速率限制中间件。根据你的环境按需调整 RATE_LIMIT_MAX_REQUESTS 和 RATE_LIMIT_WINDOW_MINUTES。启用速率限制时,两者都必须至少为 1;禁用时,服务器不会读取这两个变量。
面向大型工具集的工具搜索
启用 FastMCP 工具搜索后,可缩小包含大量工具的服务所需的提示词长度。
启用后,list_tools 会返回两个合成工具:
search_tools:查找匹配的工具并返回其完整架构call_tool:按名称执行已发现的任意工具
通过以下方式启用:
TOOL_SEARCH_ENABLED=true
TOOL_SEARCH_STRATEGY=bm25 # bm25 or regex
TOOL_SEARCH_MAX_RESULTS=8 # optional, default is 5
bm25 支持自然语言查询,而 regex 使用正则表达式
pattern 输入进行确定性匹配。启用工具搜索时,使用任何其他
策略,或将 TOOL_SEARCH_MAX_RESULTS 设为低于 1 的值,都会导致服务在启动时停止;
关闭工具搜索时,不会读取这些设置。
工具搜索遵循现有的可见性控制(只读模式和 已禁用的标签)。
SSL/TLS 配置
该服务支持 SSL 证书验证和自定义超时设置:
GHOSTFOLIO_VERIFY_SSL=true # Enable SSL certificate verification
GHOSTFOLIO_TIMEOUT=30 # Connection timeout in seconds
传输配置
该服务支持多种传输协议,以适应不同的部署场景:
STDIO 传输(默认)
默认传输使用标准输入/输出进行通信。这适用于本地使用,以及与通过 stdin/stdout 通信的工具集成:
MCP_TRANSPORT=stdio
HTTP SSE 传输(服务器发送事件)
对于基于网络的部署,可以使用带服务器发送事件的 HTTP。这样便可通过 HTTP 访问 MCP 服务,并进行实时流式传输:
MCP_TRANSPORT=sse
MCP_HTTP_HOST=127.0.0.1 # Localhost
MCP_HTTP_PORT=8000 # Port to listen on
MCP_HTTP_BEARER_TOKEN=your-secret-token # Optional authentication token
使用带有 bearer token 的 SSE 传输时,客户端必须在请求中包含该令牌:
curl -H "Authorization: Bearer your-secret-token" http://localhost:8000/sse
HTTP Streamable 传输
HTTP Streamable 传输通过 HTTP 提供基于请求/响应的通信与流式传输。这适用于 Web 集成,以及需要 HTTP 端点的工具:
MCP_TRANSPORT=http
MCP_HTTP_HOST=127.0.0.1 # Localhost
MCP_HTTP_PORT=8000 # Port to listen on
MCP_HTTP_BEARER_TOKEN=your-secret-token # Optional authentication token
使用带有 bearer token 的 streamable 传输时:
curl -H "Authorization: Bearer your-secret-token" \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
http://localhost:8000/mcp
注意:HTTP 传输要求使用正确的 JSON-RPC 格式,并包含 jsonrpc 和 id 字段。对于某些操作,服务还可能要求先初始化会话。
健康检查端点
两种 HTTP 传输(sse 和 http)都提供 GET /health,当服务正在处理请求时,该端点会返回 200 ok。
它不需要 bearer token 或 OIDC 登录,也不会联系 Ghostfolio,因此 Ghostfolio 服务中断不会导致 MCP 服务被标记为不健康。Docker 镜像的 HEALTHCHECK 使用此端点:
curl http://localhost:8000/health
OIDC / OAuth 身份验证(可选)
对于机器间客户端,静态 bearer token 已足够,但许多 MCP 客户端只能通过带动态客户端注册的 OAuth 进行身份验证。对于这些客户端,服务可以使用 FastMCP 的 OIDCProxy,在现有 OIDC 身份提供方(Authentik、Keycloak、PocketID、Auth0、Entra ID、……)前充当 OAuth 接口。客户端向此服务注册并进行身份验证;服务则代理上游流程。客户端不会接触到任何 Ghostfolio 凭据。
此功能仅适用于 sse 和 http 传输。
注册客户端
在身份提供方上创建一个机密客户端(客户端 ID + 密钥),并将重定向 URI 设置为 OIDC_BASE_URL + OIDC_REDIRECT_PATH,例如 https://ghostfolio-mcp.example.com/auth/callback。
配置
MCP_TRANSPORT=http
MCP_HTTP_HOST=0.0.0.0
MCP_HTTP_PORT=8000
# All four are required to enable OIDC
OIDC_CONFIG_URL=https://id.example.com/.well-known/openid-configuration
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret
# Public URL where this server is reachable, used to build its OAuth endpoints.
# Must be HTTPS (except on localhost), as required for an OAuth issuer.
OIDC_BASE_URL=https://ghostfolio-mcp.example.com
OIDC 完全是可选项。留空这些设置会保持现有行为;如果只配置了部分设置,系统会发出警告并忽略,而不会仅启用一部分。配置 OIDC 后,它的优先级高于 MCP_HTTP_BEARER_TOKEN。
可选设置:
# Callback path registered on the identity provider (default: /auth/callback)
OIDC_REDIRECT_PATH=/auth/callback
# Comma-separated scopes required on presented tokens
OIDC_REQUIRED_SCOPES=openid,profile
# Comma-separated allowed client redirect URI patterns (wildcards accepted)
OIDC_ALLOWED_REDIRECT_URIS=https://example.com/*
# Verify the id_token instead of the access token (default: false)
OIDC_VERIFY_ID_TOKEN=false
# Forward the RFC 8707 'resource' indicator upstream (default: false)
OIDC_FORWARD_RESOURCE=false
OIDC_ALLOWED_REDIRECT_URIS 用于限制哪些客户端可以完成此流程。留空时,会接受客户端注册的任何重定向 URI,因此请将其设置为预期使用的主机,例如 https://example.com/*。
如果你的身份提供商颁发的是不透明(非 JWT)访问令牌,请设置 OIDC_VERIFY_ID_TOKEN=true;此时会改为验证 id_token。
OIDC_FORWARD_RESOURCE 默认关闭,因为不支持 RFC 8707 资源指示符的身份提供商会以 invalid_request 拒绝授权请求,导致用户在同意后立即无法登录。只有在你的提供商支持资源指示符时才启用此选项。无论是否启用,令牌受众绑定都不受影响。
持久化 OAuth 状态
客户端注册信息和加密令牌会存储在磁盘上的 FastMCP 数据目录中。如果该目录不是持久化的,每次重启后,所有客户端都必须重新注册并进行身份验证。Docker 镜像会设置 FASTMCP_HOME=/data,因此请在此处挂载卷:
docker run -v ghostfolio-mcp-data:/data --env-file .env ghcr.io/mhajder/ghostfolio-mcp:latest
在反向代理后运行
OIDC_BASE_URL 必须是外部可访问的 HTTPS URL,且代理必须原样转发 Host 标头,否则此服务发布的 OAuth 元数据会指向错误的主机。
📊 数据源
Ghostfolio 支持多个用于市场数据和交易品种的数据源:
- YAHOO - Yahoo Finance 数据源
- COINGECKO - 用于加密货币数据的 CoinGecko
- MANUAL - 手动输入的数据
- 以及 Ghostfolio 实例中配置的其他数据源
使用需要指定数据源参数的工具时,请根据资产类型指定合适的数据源。
🐳 使用 Docker
GitHub Packages 提供了 Docker 镜像,便于部署。该镜像会在端口 8000(/mcp)上运行
HTTP Streamable 传输。
docker pull ghcr.io/mhajder/ghostfolio-mcp:latest
启用 OIDC 身份验证后,请在 /data 上挂载卷,以便 OAuth 客户端注册信息在容器重建后仍然保留。
Open WebUI
Open WebUI 0.6.31 及更高版本可直接连接到该镜像;单独的 MCPO
镜像(ghcr.io/mhajder/ghostfolio-mcpo)已不再发布。在 Open WebUI 中,
前往 管理设置 > 集成 > 外部工具服务器,添加一个类型为 MCP(Streamable HTTP) 的连接,
URL 设置为 http://<host>:8000/mcp,并将 Bearer 身份验证设置为你的
MCP_HTTP_BEARER_TOKEN。
如果启用了 OIDC 身份验证,它
的优先级更高,且不接受 Bearer 令牌。请使用
OIDC_BASE_URL + /mcp 作为 URL,并选择 OAuth 2.1 身份验证;Open
WebUI 会将自身注册为客户端,因此,如果设置了 OIDC_ALLOWED_REDIRECT_URIS,
请将 Open WebUI 的 URL 加入其中。
🤝 贡献
欢迎贡献。请参阅 CONTRIBUTING.md,了解开发环境设置、检查和提交消息格式;报告错误和提出功能请求时,请使用问题模板。
发现安全问题?请按照 SECURITY.md 中的说明私下报告。
📜 许可证
GNU Affero 通用公共许可证 v3.0 或更高版本 - 详情请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。