AgroPortal MCP服务

一个将AgroPortal/OntoPortal API作为工具暴露给LLM客户端的MCP服务器,支持本地和远程调用。

  • by maboukerfa
  • Ruby
  • 混合部署
  • 更新于
在 GitHub 查看 maboukerfa/ontoportal-mcp

使用说明

农业门户网站mcp

一 主控程序 暴露的服务器 AgroPortal/OntoPortal API作为LLM的工具 客户(克劳德桌面、克劳德代码等)。它是一个薄薄的包裹 ontologies_api_client 红宝石宝石,配以 官方 mcp 宝石之上 标准 (当地 客户)或 可流式传输HTTP/SSE (用于远程部署)。

工具

工具 说明
search_classes 对本体类/概念进行全文搜索。返回标签、URI、源本体和定义。支持限制到特定的本体,以及(可选)跨其他OntoPortal实例的联合搜索。
list_ontologies 列出门户上可用的本体,可选择通过首字母缩写或名称的不区分大小写的匹配进行筛选。返回缩写、名称和URI。支持联合。
get_class 通过本体中的URI获取单个类/概念。返回首选标签、定义、同义词、过时状态以及是否有子项。接受a language 代码(默认 en).
get_submission 获取本体提交的元数据:版本、状态、格式、日期、许可证、主页/文档、命名空间和版本IRI、自然语言、关键字、摘要和描述。默认为最新提交;通过 submission_id 对于特定版本。
list_submissions 列出本体提交及其元数据。通过A ontology 该本体的完整版本历史(最新优先)的缩写,或者省略它以获取门户上每个本体的最新提交——这是同时跨多个本体收集元数据的最快方法。支持a limit 对于门户范围的列表。
get_metrics 获取提交的大小/结构指标:类、个体和属性计数以及层次结构统计数据(最大深度、最大/平均子计数)。默认为最新提交。(对于SKOS词汇表,概念算作个体。)

更多工具(例如。 search_ontologies、映射、注释)可以添加到 lib/agroportal_mcp/tools/ 并注册于 TOOLS (lib/agroportal_mcp.rb).

需求

  • Ruby≥2.7(该项目由Homebrew Ruby在 /usr/local/opt/ruby/bin/ruby).
  • 结账 ontologies_api_ruby_client 作为兄弟目录( Gemfile 通过引用它 path: '../ontologies_api_ruby_client').
  • AgroPortalneneneba API密钥(从AgroPortal帐户页面创建一个密钥)。

安装

export PATH="/usr/local/opt/ruby/bin:$PATH"
cd ontologies_api_mcp
bundle install

配置

服务器从环境中读取其连接设置:

变量 必填 默认 备注
AGROPORTAL_API_KEY 是 - 您的API密钥。
AGROPORTAL_REST_URL 没有 https://data.agroportal.eu 指向另一个OntoPortal API以针对不同的门户。
AGROPORTAL_FEDERATED_PORTALS no -- 启用 federate 选项。空间分隔 name url apikey 三元组,逗号分隔: "ecoportal https://data.ecoportal.lifewatch.eu KEY1, biodivportal https://data.biodivportal.gfbio.dev KEY2".
AGROPORTAL_MCP_BEARER_TOKEN 否 -- HTTP传输。设置后,每个请求都必须发送 Authorization: Bearer <token>;unset表示没有身份验证(启动时会记录警告)。
AGROPORTAL_MCP_STATELESS 没有 false 仅限HTTP传输。 true 使每个请求自包含(无会话/无服务器→客户端SSE流)更易于水平扩展。
AGROPORTAL_MCP_REQUIRE_USER_APIKEY 没有 false 仅限HTTP传输。 true 拒绝没有 X-Agroportal-User-Apikey header(多租户)。当 false,此类请求可追溯到 AGROPORTAL_API_KEY.

烟雾测试

您可以手动驱动stdio协议:

export AGROPORTAL_API_KEY=your_key
printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
  '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_classes","arguments":{"query":"wheat","pagesize":3}}}' \
  | /usr/local/opt/ruby/bin/ruby bin/agroportal_mcp

向MCP客户端注册

克劳德代码(CLI)

claude mcp add agroportal \
  --env AGROPORTAL_API_KEY=your_key \
  -- /usr/local/opt/ruby/bin/ruby \
     /Users/maboukerfa/code/agroportal/ontologies_api_mcp/bin/agroportal_mcp

克劳德桌面(claude_desktop_config.json)

{
  "mcpServers": {
    "agroportal": {
      "command": "/usr/local/opt/ruby/bin/ruby",
      "args": [
        "/Users/maboukerfa/code/agroportal/ontologies_api_mcp/bin/agroportal_mcp"
      ],
      "env": {
        "AGROPORTAL_API_KEY": "your_key",
        "AGROPORTAL_REST_URL": "https://data.agroportal.eu"
      }
    }
  }
}

入口引脚 BUNDLE_GEMFILE 对于这个项目,因此可以从 任何工作目录。

远程部署(流式HTTP/SSE)

要为远程客户端提供相同的工具,请运行MCP 可流式传输的HTTP 运输而不是stdio。它使用SSE(text/event-stream)用于流媒体播放 服务器响应,并取代了弃用的独立HTTP+SSE传输。 config.ru 将服务器安装为Rack应用程序;安装 http 群组 (bundle install 默认情况下执行此操作)并在Puma下运行:

export AGROPORTAL_API_KEY=your_key
export AGROPORTAL_MCP_BEARER_TOKEN=$(openssl rand -hex 32)   # recommended
bundle exec puma config.ru -p 9292

端点在根路径上为JSON-RPC提供服务。烟雾测试握手(下降 这 Authorization 如果未设置令牌,则返回header):

# 1) initialize — capture the Mcp-Session-Id from the response headers
curl -sN -i -X POST http://127.0.0.1:9292/ \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H "Authorization: Bearer $AGROPORTAL_MCP_BEARER_TOKEN" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}'

# 2) tools/list — reuse the session id from step 1 (response streams back as SSE)
curl -sN -X POST http://127.0.0.1:9292/ \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H "Authorization: Bearer $AGROPORTAL_MCP_BEARER_TOKEN" \
  -H 'Mcp-Session-Id: <id-from-step-1>' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

操作说明:

  • 在前面终止TLS。 在反向代理(nginx/Caddy)后面运行它或加载 处理HTTPS的平衡器——承载令牌与传输一样安全。
  • 不要在未经验证的情况下暴露它。 随着 AGROPORTAL_MCP_BEARER_TOKEN 取消设置 端点已打开(并在启动时发出警告)。设置它,或用 验证代理。
  • 并发性。 在默认状态模式下,每个连接的客户端都持有 长期存在的SSE流开放,这束缚了Puma线程;尺寸 --threads (或 集 AGROPORTAL_MCP_STATELESS=true)以匹配预期的并发性。对于许多人 并发SSE流, 猎鹰 (基于光纤的)可扩展性更好,服务内容相同 config.ru --添加 gem 'falcon' 到 :http 组,然后 bundle exec falcon serve -b http://0.0.0.0:9292.

使用Claude代码注册远程服务器:

claude mcp add --transport http agroportal https://your-host.example/ \
  --header "Authorization: Bearer your_token"

多租户:每个用户API密钥

托管一个共享实例,让每个用户使用自己的AgroPortal进行身份验证 钥匙。服务器使用自己的 AGROPORTAL_API_KEY 作为基础凭证和 将每个呼叫者的密钥转发为 userapikey,因此API属性请求- 权限、速率限制、私有本体——对该用户。

export AGROPORTAL_API_KEY=server_app_key          # must be allowed to use userapikey (see below)
export AGROPORTAL_MCP_REQUIRE_USER_APIKEY=true     # reject requests with no user key
export AGROPORTAL_MCP_STATELESS=true               # recommended for multi-tenant
bundle exec puma config.ru -p 9292

每个用户在 X-Agroportal-User-Apikey 头球

claude mcp add --transport http agroportal https://mcp.agroportal.eu/ \
  --header "X-Agroportal-User-Apikey: <their_personal_key>"

密钥根据请求读取,并由客户端转发 user_apikey 中间件,生产 Authorization: apikey token=<server>&userapikey=<user>. Thread#[] 是光纤本地的,因此请求在Puma和Falcon下保持隔离。

要求和注意事项:

  • 服务器的 AGROPORTAL_API_KEY 必须被允许使用 userapikey 一 admin/app帐户,而不是普通的用户密钥。(你运行AgroPortal,所以你可以 薄荷1;确认您的API荣誉 userapikey 为它)
  • HTTPS是强制性的 --用户在每次请求时都会发送他们的个人密钥。
  • 关闭客户端缓存 (默认设置)。共享缓存可以为一个 用户的结果,包括私有本体,传递给另一个用户。
  • 没有 AGROPORTAL_MCP_REQUIRE_USER_APIKEY,省略标头的请求 回退到服务器密钥;将其设置为拒绝这些。
  • 可选 AGROPORTAL_MCP_BEARER_TOKEN 门是独立的,可以 在顶部分层,以实现部署范围内的秘密。

布局

bin/agroportal_mcp                     # executable stdio entrypoint (local clients)
config.ru                              # Rack entrypoint: Streamable HTTP / SSE (remote)
lib/agroportal_mcp.rb                  # build_server + run (stdio) / http_transport (SSE)
lib/agroportal_mcp/middleware.rb       # Rack middlewares: bearer gate + per-user apikey
lib/agroportal_mcp/client_setup.rb     # env -> LinkedData::Client config (+ Rails.cache shim)
lib/agroportal_mcp/tools/              # one file per MCP tool
  search_classes.rb