MCP工具服务器

一个支持MCP工具和科学研究的可定制异步服务器,适用于高性能计算和融合计算场景。

  • by converged-computing
  • Python
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 converged-computing/mcp-server

使用说明

mcp发球

支持MCP工具和科学的代理服务器

设计

这是一个可定制的异步服务器,可以注册和加载感兴趣的工具。端点包括功能(工具)、提示、资源。这些现在(在很大程度上)被分成模块化项目:

  • 通量mcp:Flux框架的MCP工具
  • hpc-mcp:用于更大范围的HPC和融合计算用例的HPC工具。

抽象

这里的库有以下抽象。

  • 工具:服务器工具、提示和资源
  • 用户界面:引擎(带主管理器)使用的用户界面
  • 核心:共享资产,主要是计划/步骤/配置定义和工人/中心层次结构角色
  • 路线:服务器视图与mcp无关。
  • 数据库:如何在管道中保存结果(目前我们支持sqlite和文件系统JSON)

对于上述内容,引擎、工具、ui、数据库和后端都是接口。

发展

建议在VSCode容器中打开。然后安装:

pip install --break-system-packages -e .

码头工人

构建Docker容器:

make

要运行一个虚拟示例:

docker run -p 8089:8089 -it ghcr.io/converged-computing/mcp-server:latest

然后从外部进行交互:

python3 ./examples/echo/test_echo.py

环境

可以在环境中设置以下变量。

名称 描述 默认值
MCPSERVER_PORT 如果使用http变体,则运行MCP服务器的端口 8089
MCPSERVER_HOST 运行MCP服务器的默认主机(http) 0.0.0.0
MCPSERVER_PATH 服务器终结点的默认路径 /mcp
MCPSERVER_TOKEN 用于测试的令牌 未设置

用法

启动服务器

在一个终端中启动服务器。出口 MCPSERVER_TOKEN 如果你想让某个客户端使用简单的令牌身份验证。 将令牌留给本地测试。这里有一个http的例子。

mcpserver start --transport http --port 8089

端点

除了根据以下标准提供JSON RPC的标准MCP端点外 说明书,我们提供了一组更容易访问的http端点,以便轻松访问服务器运行状况或元数据。

健康检查

# Health check
curl -s http://0.0.0.0:8089/health  | jq

列表

您可以列出工具、提示和资源。

curl -s http://0.0.0.0:8089/tools/list  | jq
curl -s http://0.0.0.0:8089/prompts/list  | jq
curl -s http://0.0.0.0:8089/resources/list  | jq

我们通过管理器的发现在服务器内部完成此操作,然后返回找到的简单JSON响应。

示例

当服务器运行时,所有这些都可以从单独的终端运行。

简单的回声

做一个简单的工具请求。

# Tool to echo back message
python3 examples/echo/test_echo.py

Docker构建

下面是一个部署服务器以构建Docker容器的示例。 我们首先需要安装以下功能 hpc-mcp:

pip install hpc-mcp --break-system-packages

使用我们需要的函数和提示启动服务器:

# In one terminal (start MCP)
mcpserver start -t http --port 8089 \
  --prompt hpc_mcp.t.build.docker.docker_build_persona_prompt \
  --tool hpc_mcp.t.build.docker.docker_build_container

# Start with a configuration file instead
mcpserver start -t http --port 8089 --config ./examples/docker-build/mcpserver.yaml

然后使用代理框架运行一些与工具交互的计划。以下是您如何手动调用它们,假设上面的第二个start方法具有自定义函数名。注意,对于docker build,您需要在带有docker或podman的系统上运行服务器。

# Generate a build prompt
python3 examples/docker-build/docker_build_prompt.py

# Build a docker container (requires mcp server to see docker)
python3 examples/docker-build/test_docker_build.py

列表

代理使用此端点发现工具。我们也可以称之为!

python3 examples/list_tools.py
python3 examples/list_prompts.py

JobSpec翻译

这是一个显示使用Flux翻译作业规范的服务器。 要使用Flux进行原型制作,请在devcontainer中打开代码。安装库并启动flux实例。

pip install -e .[all] --break-system-packages
pip install flux-mcp IPython --break-system-packages
flux start

我们需要启动服务器并添加验证函数和提示。

mcpserver start -t http --port 8089 \
  --tool flux_mcp.validate.flux_validate_jobspec \
  --prompt flux_mcp.validate.flux_validate_jobspec_persona \
  --tool flux_mcp.transformer.transform_jobspec \
  --prompt flux_mcp.transformer.transform_jobspec_persona

使用配置文件:

mcpserver start -t http --port 8089 --config ./examples/jobspec/mcpserver.yaml

我们将提供jobspec翻译功能的示例 分形 代理人在 分形试剂.

Kubernetes(种类)

此示例用于在Kind(或Kubernetes/Openshift)中工作的基本清单。请注意,我们使用默认的基本容器,并通过ConfigMap添加自定义函数。你可以采用这种方法,或者在我们的基础容器上构建,pip安装你自己的函数来使用。

我们很快就会制作一个Kubernetes操作符来创建这组东西。

安全套接层

生成密钥

mkdir -p ./certs
openssl req -x509 -newkey rsa:4096 -keyout ./certs/key.pem -out ./certs/cert.pem -sha256 -days 365 -nodes -subj '/CN=localhost'

然后启动服务器,表明您想使用它们。

mcpserver start --transport http --port 8089 --ssl-keyfile ./certs/key.pem --ssl-certfile ./certs/cert.pem

对于客户端,它的工作方式是httpx通过以下方式发现证书 环境变量例如,先在没有它们的情况下尝试测试:

python3 examples/ssl/test_ssl_client.py
📡 Connecting to https://localhost:8089/mcp...
❌ Connection failed: Client failed to connect: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1000)

现在导出envars:

export SSL_CERT_DIR=$(pwd)/certs
export SSL_CERT_FILE=$(pwd)/certs/cert.pem
📡 Connecting to https://localhost:8089/mcp...
  ⭐ Discovered tool: simple_echo

✅ Connection successful!

你会看到服务器被攻击。

完整架构

启动中心

您需要为关联的worker和资源发现安装支持:

pip install mcp-serve[hub]
pip install mcp-serve[all]

mcp服务器可以注册工作集线器,即注册到它的其他mcp服务器。要将mcpserver作为集线器启动:

# Start a hub in one terminal
mcpserver start --hub --hub-secret potato

# Start in dual mode (not recommended for production, primarily for experiments)
mcpserver start --dual --hub-secret potato

在另一个终端中,使用生成的令牌启动worker。添加一些有趣的功能。

# If it wants to write batch jobs.
pip install hpc-mcp --break-system-packages
mcpserver start --config examples/jobspec/mcpserver.yaml --join http://0.0.0.0:8000 --join-secret potato --port 7777

请注意,您还可以在环境中设置密钥。

export MCPSERVER_JOIN_SECRET=potato
mcpserver start --config examples/jobspec/mcpserver.yaml --join http://0.0.0.0:8000 --port 7777

你也可以开始一个模拟工人。默认情况下,我们为hpc、云和独立原型选择40/40/20。你可以 还要指定一个原型。

mcpserver start --config examples/jobspec/mcpserver.yaml --join http://0.0.0.0:8000 --port 7777 --mock
mcpserver start --config examples/jobspec/mcpserver.yaml --join http://0.0.0.0:8000 --port 7777 --archetype hpc

嘲笑一个中心

如果你在做实验,你可以用同样的方法来建立一个中心:

# Start as a standalone hub (recommended)
mcpserver start --hub --hub-secret potato

# Start in dual mode (not recommended for production or performance experiments
mcpserver start --dual --hub-secret potato

要模拟一个工人,请添加 --mock,可选地使用特定的原型(以下之一 hpc, cloud,或 standalone).建议使用工作者ID以使种子可重复。

mcpserver start --join http://0.0.0.0:8000 --port 7777 --worker-id 10 --mock --join-secret potato
mcpserver start --join http://0.0.0.0:8000 --port 7777 --worker-id 10 --mock hpc --join-secret potato

在另一个终端中,您可以请求导出模拟“真相”-为原型选择的提供者生成的元数据。

mcpserver start --config examples/jobspec/mcpserver.yaml --join http://0.0.0.0:8000 --port 7777 --worker-id 10

并导出“真相”元数据。

resource-ask export --output ground-truth.json

手动查询

测试对状态进行原始查询。这些是手动和本地查询。

# Get listing of workers and metadata
python3 ./examples/mcp-query.py

# Get a specific tool metadata from the worker
python3 ./examples/mcp-query.py http://localhost:7777/mcp get_status

# Call a namespaced tool on the hub (e.g., get the status)
python3 ./examples/mcp-query.py http://localhost:8000/mcp n_781e903e4f10_get_status

您可以在没有加入密码或错误的加入密码的情况下进行测试,以查看它是否失败。

资源秘书客户

这是客户端通用界面:

# Includes request, asking secretaries, selection, and dispatch
resource-ask negotiate "I need <resources, constraints>"

# Includes request and asking secretaries
resource-ask satisfy "I need <resources, constraints>"

# Includes request, asking secretaries, and selection
resource-ask select "I need <resources, constraints>"

# The same, but from a proposals file (json dict with data.proposal for each)
resource-ask select --proposals proposals.json "I need <resources, constraints>"

# Dispatch directly to a named cluster
resource-ask dispatch <cluster> "I need <resources>"

这 resource-ask 客户端,它可以支持使用本地模型来运行选择和其他算法。您还可以使用服务器端点“滚动自己的”内容,但此库已经提供了用于执行和扩展此操作的接口。

pip install resource-secretary

协商工作

当用户有请求时,它会作为提示进入集线器。我们使用提示而不是一组硬编码的策略,因为从技术上讲,它可以说任何事情。例如。,

我3小时后有一篇论文要交,我需要运行LAMMPS。为我找到至少3个节点,并尽量缩短完成时间。我的预算是X。

如果您使用的是gemini或openai,请确保安装库。

pip install -e .[gemini] --break-system-packages
pip install -e .[openai] --break-system-packages

例如,我喜欢发现垃圾邮件。我们可以安装到spack来查看响应如何变化。

git clone --depth 1 https://github.com/spack/spack /tmp/spack
export SPACK_ROOT=/tmp/spack
flux start

然后启动工人。由于我们在VSCode环境中运行,让我们问一个范围较小的任务。

# Satisfy request
resource-ask satisfy "Can you run cowsay on one node?"

# List selection algorihtms
resource-ask list select

# Negotiat (sastisfy, select, and dispatch) with a selection algorithm
resource-ask negotiate "I need to run LAMMPS with 1 node." --select agentic

您会注意到,界面建议接下来使用“选择”。上述“协商”类似于满足请求。我们执行以下操作:

[resource-ask] (client)  --> [negotiate_job] (hub) --> [secretary_ask] (workers) --> return to hub --> [client]

选择将更进一步,然后选择。

上面的方法奏效了,反应回来了!接下来,我需要研究选择算法和委托。 可能开始时,我会随机选择(这将是一个可以有效选择的接口),然后允许我实现委托。其余的笔记来自以前。

为了实现这一目标,我们:

  1. 致电mcp服务器中心 negotiate_work
  • 谈判工作将促使秘书回复:
    • 快速的是/否回答,可以排除竞争者
    • 特定于策略的指标(例如,估计的开始时间、估计的成本、性能)
    • 重要的是,该中心将评估一系列因素对工作的重要性。例如,“这项工作需要良好的网络,在X时间内完成,在N成本下,存储无关紧要。”它会提出因素和权重(重要性)以及因素的方程式,而不会告诉秘书其相对权重。中心将准备一份提示,描述需求,不仅是重要性,还将为秘书代理提供参考。例如,“评估你的网络,其中1.0是100Gbps InfiniBand,0.0是1Gbps以太网。”然后,秘书将评估他们的资源质量,并返回分数和理由/理由来评估每个变量。我们可以测试二进制(0/1)、请求特定范围和归一化分数(0到1)。然后,集线器只需要根据其方程计算返回值。这需要一个两步过程,首先是定量,然后是基于定性的调整。例如,也许一个特定的文件系统被赋予了0.5,但秘书也注意到它正在进行重建,所以中心决定惩罚它。
  1. 集线器将请求发送给子工作者(每个都是不同的集群)
  2. 每个童工都有一个秘书负责接收。
  • 秘书有关于启动时发现的集群的元数据,这些元数据不会改变(例如硬件)
  • 秘书还可以将句柄注册到详细的发现工具(例如,软件,例如, spack find lammps)
  • 秘书打电话请求队列状态等状态数据
  • 秘书还使用发现工具来寻找所选的软件。
  1. 每位秘书都会发回他们的回复——定量分数,加上定性原因。
  2. 每个秘书都有一个信任分数。它基于两件事:
  • 资源的实际发现是一个已知的真理,总是会被返回。将秘书的话与此进行比较。
  • 工作的实际表现可以根据承诺来评估。
  • 信任评分可以(以某种方式)用于未来的评估。

设计选择

以下是一些设计选择(当然可能会发生变化)。我从用这个框架重新实现我们的分形代理开始。为此,我们将有一个灵活的代理类,可以根据所选的提示更改函数,而不是将代理绑定到特定的函数(作为其代理函数上的类)。它将使用mcp函数、提示和资源。此外:

  • 此处托管的工具是库所需的内部工具。例如,我们有一个提示,允许在工具做得不好的情况下获取输出的最终状态。
  • 对于这里托管的那些,我们不直接使用mcp.tool(和相关函数),而是手动将它们添加到mcp中,以允许动态加载。
  • 更通用的工具在extral库下提供(例如flux mcp和hpc mcp)
  • 我们可以使用mcp.mount来扩展服务器以包含其他服务器,或者代理的等效服务器(我还没有测试过)。
  • 异步很烦人,但我正在使用它。这意味着调试主要是打印语句,而不是交互式的。
  • FastMCP的后端本质上是starlette,因此我们定义(并添加)了到服务器的其他路由。

全部

  • []如果它可能只是一个登录节点,我们是否应该报告利用率(例如,mock或nvidia-smi)?
  • []编写函数来比较报告的代理结果是否真实?怎么用?
  • []需要一种方法来“传递”来自工作者的错误,例如,未设置API键。
  • []我希望有一个相当于满足端点的东西,检查协商而不是调度。
  • []我还想要一个等效的“只需提交到此集群”端点。

想法:

  • mcp服务器工作器应该有一个为代理生成提示的工具。“这是对lammps、这么多节点的请求,这是我们看到的资源(调用get_status,它也将返回给调用者)。我们能支持它吗?使用你的工具来解决这个问题。然后创建的代理应该使用它生成的同一服务器中的工具来回答这个问题。代理的响应加上状态应该返回给集线器。集线器可以有加权方程来决定最终的集群。
  • TODO:询问代理我们应该消除哪些通量变量。

许可证

HPCIC DevTools根据MIT许可证的条款进行分发。 所有新的贡献都必须根据此许可证进行。

看 许可证, 版权,以及 通知 了解详情。

SPDX 许可证标识符: (MIT)

LLNL-CODE-842614