合并 MCP 服务器
该 MCP(模型上下文协议)服务器提供 Merge API 与任何支持 MCP 协议的 LLM 提供程序(例如,Claude for Desktop)之间的集成,允许您使用自然语言与 Merge 数据进行交互。
✨ 特点
- 使用自然语言查询合并 API 实体
- 获取有关合并数据模型及其字段的信息
- 通过对话界面创建和更新实体
- 支持多种合并 API 类别(HRIS、ATS 等)
📦安装
先决条件
- 合并 API 密钥和帐户令牌
- Python 3.10 或更高版本
- 紫外线
使用独立安装程序安装uv
:
# On macOS and Linux.
curl -LsSf https://astral.sh/uv/install.sh | sh
# On Windows.
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
或者通过 pip:
# With pip.
pip install uv
# With pipx.
pipx install uv
🔌 MCP 设置
这是一个示例配置文件,您可以用它来设置合并 MCP。
{
"mcpServers": {
"merge-mcp-server": {
"command": "uvx",
"args": ["merge-mcp"],
"env": {
"MERGE_API_KEY": "your_api_key",
"MERGE_ACCOUNT_TOKEN": "your_account_token"
}
}
}
}
注意:如果“uvx”命令不起作用,请尝试绝对路径(即/Users/username/.local/bin/uvx)
Claude Desktop 配置示例
- 确保你已经安装了
uvx
- 从官方网站下载Claude Desktop
- 下载后,打开应用程序并按照说明设置您的帐户
- 前往**“设置”→“开发者”→“编辑配置”** 。这将在文本编辑器中打开一个名为
claude_desktop_config.json
的文件。 - 复制上面的 MCP 服务器设置 JSON 并将其粘贴到文本编辑器中
- 将
your_api_key
和your_account_token
替换为你实际的合并 API 密钥和关联账户令牌。你还需要将uvx
替换为配置文件中命令的绝对路径(例如/Users/username/.local/bin/uvx
)。你可以在终端中运行which uvx
来获取绝对路径。 - 保存配置文件
- 重启 Claude Desktop 即可查看您的工具。工具可能需要一分钟才能显示。
Python 客户端配置示例
- 设置您的环境
# Create project directory
mkdir mcp-client
cd mcp-client
# Create virtual environment
python -m venv .venv
# Activate virtual environment
# On Windows:
.venv\Scripts\activate
# On Unix or MacOS:
source .venv/bin/activate
# Install required packages
pip install mcp uv anthropic python-dotenv
# Create our main file
touch client.py
- 设置您的 API 密钥
# Add your ANTHROPIC_API_KEY and MERGE_API_KEY to .env
echo "ANTHROPIC_API_KEY=<your Anthropic key here>" >> .env
echo "MERGE_API_KEY=<your Merge key here>" >> .env
# Add .env file to .gitignore
echo ".env" >> .gitignore
- 创建
client.py
文件,添加以下代码
import os
import asyncio
from typing import Optional
from contextlib import AsyncExitStack
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from anthropic import Anthropic
from dotenv import load_dotenv
load_dotenv() # load environment variables from .env
class MCPClient:
def __init__(self):
# Initialize session and client objects
self.session: Optional[ClientSession] = None
self.exit_stack = AsyncExitStack()
self.anthropic = Anthropic()
# Methods will go here
- 向 MCPClient 类添加
connect_to_server
函数
async def connect_to_server(self, linked_account_token: str):
"""Connect to an MCP server
Args:
linked_account_token: The token for the associated Linked Account
"""
server_params = StdioServerParameters(
command="uvx",
args=["merge-mcp"],
env={
"MERGE_API_KEY": os.getenv("MERGE_API_KEY"),
"MERGE_ACCOUNT_TOKEN": linked_account_token
}
)
stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
self.stdio, self.write = stdio_transport
self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))
await self.session.initialize()
# List available tools
response = await self.session.list_tools()
tools = response.tools
print("\nConnected to server with tools:", [tool.name for tool in tools])
- 向 MCPClient 类添加
process_query
函数
async def process_query(self, query: str) -> str:
"""Process a query using Claude and available tools"""
messages = [
{
"role": "user",
"content": query
}
]
response = await self.session.list_tools()
available_tools = [{
"name": tool.name,
"description": tool.description,
"input_schema": tool.inputSchema
} for tool in response.tools]
# Initial Claude API call
response = self.anthropic.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1000,
messages=messages,
tools=available_tools
)
# Process response and handle tool calls
final_text = []
assistant_message_content = []
for content in response.content:
if content.type == 'text':
final_text.append(content.text)
assistant_message_content.append(content)
elif content.type == 'tool_use':
tool_name = content.name
tool_args = content.input
# Get confirmation for tool call execution
confirmation = input(f"Do you want to call tool '{tool_name}' with arguments {tool_args}? (y/n): ").strip().lower()
if confirmation.startswith('y'):
result = await self.session.call_tool(tool_name, tool_args)
final_text.append(f"[Calling tool {tool_name} with args {tool_args}]")
assistant_message_content.append(content)
messages.append({
"role": "assistant",
"content": assistant_message_content
})
messages.append({
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": content.id,
"content": result.content
}
]
})
# Get next response from Claude
response = self.anthropic.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1000,
messages=messages,
tools=available_tools
)
final_text.append(response.content[0].text)
else:
final_text.append(f"[Skipped calling tool {tool_name} with args {tool_args}]")
return "\n".join(final_text)
- 向 MCPClient 类添加
chat_loop
函数
async def chat_loop(self):
"""Run an interactive chat loop"""
print("\nMCP Client Started!")
print("Type your queries or 'quit' to exit.")
while True:
try:
query = input("\nQuery: ").strip()
if query.lower() == 'quit':
break
response = await self.process_query(query)
print("\n" + response)
except Exception as e:
print(f"\nError: {str(e)}")
- 向 MCPClient 类添加
cleanup
函数
async def cleanup(self):
"""Clean up resources"""
await self.exit_stack.aclose()
- 在
client.py
文件中添加一个main
函数作为主入口点
async def main():
client = MCPClient()
try:
await client.connect_to_server("<your Linked Account token here>")
await client.chat_loop()
finally:
await client.cleanup()
if __name__ == "__main__":
import sys
asyncio.run(main())
- 运行客户端
🔍 范围
范围决定了 MCP 服务器上启用哪些工具,并用于控制对 Merge API 各个部分的访问。如果未指定范围,则所有可用的范围均会启用。
启动服务器时,您可以指定要启用的范围。这可以通过传递带有范围列表的--scopes
标志来实现。
{
"mcpServers": {
"merge-mcp-server": {
"command": "uvx",
"args": [
"merge-mcp",
"--scopes",
"ats.Job:read",
"ats.Candidate",
"ats.Application:write"
],
"env": {
"MERGE_API_KEY": "your_api_key",
"MERGE_ACCOUNT_TOKEN": "your_account_token"
}
}
}
}
范围格式
Merge MCP 服务器中的范围遵循基于 Merge API 类别和通用模型名称的特定格式。每个范围的格式如下:
<category>.<CommonModel>:<permission>
在哪里:
<category>
是合并 API 类别(例如hris
、 ats
、 accounting
)<CommonModel>
是合并通用模型的名称(例如, Employee
、 Candidate
、 Account
)<permission>
是read
或write
(可选 - 如果未指定,则授予所有权限)
有效范围的示例:
hris.Employee:read
- 允许从 HRIS 类别读取员工数据ats.Candidate:write
- 允许在 ATS 类别中创建或更新候选人数据accounting.Account
- 允许对会计类别中的帐户数据进行所有操作
您可以组合多个范围来授予不同的权限。
关于范围可用性的重要说明
可用的范围取决于您的合并 API 帐户配置以及关联帐户可以访问的模型。范围必须与关联帐户中已启用的范围进行交叉引用:
- 类别不匹配:如果您指定的类别范围与您的关联帐户不匹配(例如,使用带有 HRIS 关联帐户的
ats.Job
),则不会返回该范围的任何工具。 - 权限不匹配:如果您请求的权限未为您的链接帐户启用(例如,在仅启用读取访问权限时使用
hris.Employee:write
),则不会返回需要该权限的工具。 - 验证:服务器将自动验证您请求的范围是否与您的链接帐户中可用的范围一致,并且仅为有效的、授权的范围启用工具。
范围通常对应于 Merge API 中的不同模型或实体类型,它们控制对这些实体的读取和写入访问。
🚀 可用工具
合并 MCP 服务器提供对各种合并 API 端点��访问,这些端点以工具形式提供。可用的工具取决于您的合并 API 类别(HRIS、ATS 等)以及您启用的范围。
工具是根据您的合并 API 模式动态生成的,并包括以下操作:
- 检索实体详细信息
- 列出实体
- 创建新实体
- 更新现有实体
- 更多内容取决于您的具体合并 API 配置
**注意:**目前不支持下载工具。这是一个已知限制,将在后续版本中解决。
🔑 环境变量
Merge MCP 服务器使用以下环境变量:
MERGE_API_KEY
:您的合并 API 密钥MERGE_ACCOUNT_TOKEN
:您的合并关联账户令牌MERGE_TENANT
(可选):合并 API 租户。有效值为US
、 EU
和APAC
。默认为US
。