Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Sage Server

БесплатноНе проверен

A Model Context Protocol (MCP) server for interacting with the Sage Grande Testbed, enabling users to query sensor data, submit jobs, and manage Sage nodes thro

GitHubEmbed

Описание

A Model Context Protocol (MCP) server for interacting with the Sage Grande Testbed, enabling users to query sensor data, submit jobs, and manage Sage nodes through natural language.

README

A Model Context Protocol server for the Sage Grande Testbed — cyberinfrastructure for AI@Edge. It exposes ~30 MCP tools, resources, and prompts for querying sensor data, submitting edge-computing jobs, discovering plugins, and browsing Sage documentation from any MCP-compatible client (Claude Desktop, Cursor, custom agents, etc.).

Built on FastMCP 2.10+ and the MCP SDK 1.12+; supports stdio, sse, and streamable-http transports.


Choose your setup

There are three ways to run this — pick the one that fits.

# Path Who it's for You need
1 Hosted (mcp.sagecontinuum.org) Everyone. Zero install. An MCP client + a Sage token.
2 Local — stdio IDE users who want to run the server themselves. Python 3.11+ and this repo.
3 Local — HTTP Devs, custom agents, curl testing. Python 3.11+ or Docker.

All three expose the exact same tools. The only difference between hosted and local is how much data you can reach: without Sage credentials, every tool still runs but falls back to public data only. See Authentication & credentials for how to add your token.


1. Hosted (mcp.sagecontinuum.org)

The server is already running at https://mcp.sagecontinuum.org/mcp. Point any MCP client at it — no install needed.

Cursor (~/.cursor/mcp.json) or Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "sage": {
      "url": "https://mcp.sagecontinuum.org/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_USERNAME:YOUR_ACCESS_TOKEN"
      }
    }
  }
}

Get YOUR_ACCESS_TOKEN from https://portal.sagecontinuum.org/account/access. The Bearer value must be in username:token form for anything beyond public data.

Restart your client, then ask natural questions:

"Show me temperature readings from node W023 in the last hour." "Find nodes in Chicago with recent camera images." "What's the highest temperature recorded today across all nodes?"


2. Local — stdio (for IDE clients)

Run the server as a subprocess of your IDE. Nothing binds to a network port. This is the most private mode — data and credentials never leave your machine.

Install:

git clone https://github.com/waggle-sensor/sage-mcp.git
cd sage-mcp
pip install -r requirements.txt
cp .env.example .env       # edit and add SAGE_USER / SAGE_PASS if you have them

Wire it into Cursor/Claude Desktop:

{
  "mcpServers": {
    "sage-local": {
      "command": "/absolute/path/to/sage-mcp/scripts/run-local-stdio.sh",
      "env": {
        "SAGE_USER": "your-sage-username",
        "SAGE_PASS": "your-sage-access-token"
      }
    }
  }
}

env: values here override anything in .env — useful when you want different tokens per IDE profile. Omit them entirely to run against public data only.


3. Local — HTTP (for development or non-IDE clients)

Bind the server to a local port. Useful for curl, custom agents, browser extensions, or anything that connects to a URL rather than spawning a subprocess.

Option A — bare Python

pip install -r requirements.txt
cp .env.example .env       # optional
./scripts/run-local-http.sh

Server is now on http://127.0.0.1:8000/mcp. Quick sanity check:

curl http://127.0.0.1:8000/health
# {"status":"ok"}

Option B — Docker

cp .env.example .env       # optional
docker compose up          # http://127.0.0.1:8000/mcp — laptop-safe default

The default docker compose up publishes only to 127.0.0.1. To expose it on all interfaces (cloud deployment), use the cloud profile:

docker compose --profile cloud up -d

For older MCP clients that only speak SSE:

docker compose --profile sse up   # http://127.0.0.1:8001/sse

Point a client at your local server

{
  "mcpServers": {
    "sage-local-http": {
      "url": "http://127.0.0.1:8000/mcp"
    }
  }
}

Authentication & credentials

The server never requires a Sage token — it just does less without one.

Scenario What works What doesn't
No token Public sensor data, node listings, docs, plugin discovery, image proxy for public images Protected datasets, /proxy/image for restricted content, job submission (sesctl still needs a real token)
username:token provided Everything the token's Sage account has access to Anything not shared with your account

How to provide a token, in order of preference:

  1. .env file (SAGE_USER=… + SAGE_PASS=…) — picked up by both ./scripts/run-local-http.sh and ./scripts/run-local-stdio.sh and by docker compose.
  2. Per-request HTTP header — for the hosted server or any HTTP transport:
    • Authorization: Bearer username:token (recommended)
    • Authorization: Basic <base64(username:token)>
    • X-SAGE-Token: username:token
  3. Query parameter?token=username:token as a last resort (shows up in server logs, so avoid for anything sensitive).

Get your token from https://portal.sagecontinuum.org/account/access. Access to protected data also requires signing the Sage Data Use Agreement.


Configuration reference

Every option is an environment variable — see .env.example for the full list with comments.

Variable Default Purpose
MCP_TRANSPORT streamable-http stdio / sse / streamable-http / http (alias)
MCP_HOST 0.0.0.0 Bind address (network transports only)
MCP_PORT 8000 Bind port (network transports only)
MCP_PATH /mcp HTTP path (streamable-http only)
LOG_LEVEL INFO Python logging level
SAGE_USER, SAGE_PASS Basic auth for /proxy/image
SAGE_PROXY_BASE_URL http://localhost:8000 Public URL prefix in generated proxy links
ADMIN_API_KEY Required to hit /analytics/*
SAGE_MCP_SKIP_REGISTRY_REFRESH Skip ECR call on startup (offline/CI)

HTTP endpoints (non-MCP)

Path Auth Purpose
GET /health none Liveness / readiness probe
GET /proxy/image?url=… SAGE_USER/SAGE_PASS or per-request token Authenticated image proxy to storage.sagecontinuum.org
GET /analytics/summary admin key Aggregate usage counts
GET /analytics/users admin key Per-user stats
GET /analytics/tools admin key Per-tool stats
GET /analytics/user/{id} admin key One user + their tool usage
GET /analytics/activity admin key Recent activity feed (?limit=)

Admin API key is accepted via X-Admin-API-Key header, Authorization: Bearer <key>, or ?api_key=<key>.


Tools, resources & prompts

29 tools, 2 resources, 7 prompts. Highlights:

  • Sensor data: get_node_all_data, get_node_iio_data, get_environmental_summary, list_available_nodes, search_measurements, get_node_temperature, get_temperature_summary
  • Node metadata: get_node_info, list_all_nodes, get_sensor_details
  • Jobs: submit_sage_job, submit_plugin_job, submit_multi_plugin_job, check_job_status, query_job_data, force_remove_job, suspend_job
  • Geography: get_nodes_by_location, get_measurement_stat_by_location
  • Plugins: find_plugins_for_task, get_plugin_data, query_plugin_data_nl, create_plugin
  • Images: get_cloud_images, get_image_data, get_image_proxy_url
  • Docs: ask_sage_docs, sage_faq, search_sage_docs
  • Resources: query://{plugin}, stats://temperature
  • Prompts: getting_started_guide, plugin_development_guide, data_analysis_guide, troubleshooting_guide, and three "suggest" prompts.

More docs in the docs/ folder — Getting Started, Authentication, Custom Functions, Docker Deployment.


Testing

pip install -r requirements.txt
python -m pytest tests/          # 61 tests, no network required

The test suite mocks sage_data_client and the ECR registry — nothing hits Sage's servers during CI. Legacy interactive smoke scripts (test_auth.py, test_server.py, test_image_proxy.py, ...) still work as manual tests; they're excluded from pytest collection via pytest.ini.


Extending

Add a tool by decorating a function in one of the modules under sage_mcp_server/tools/:

# sage_mcp_server/tools/sensor_tools.py

@mcp.tool
def my_custom_analysis(data_query: str, analysis_type: str = "basic") -> str:
    """Perform a custom analysis on Sage data."""
    df = data_service.query_data(...)
    return f"Analysis results: ..."

See Custom Functions Guide for the full workflow (fork → add → deploy).


Project layout

sage_mcp.py                          # 30-line entrypoint; exposes `mcp`
sage_mcp_server/                     # FastMCP factory + services
├── server.py                        # build_server(), main()
├── auth.py                          # HTTP request auth extraction
├── analytics_service.py             # in-memory analytics
├── data_service.py                  # sage-data-client wrapper
├── docs_helper.py                   # docs search + FAQ
├── job_service.py                   # sesctl wrapper
├── job_templates.py                 # pre-baked plugin job templates
├── models.py                        # pydantic v2 domain models
├── plugin_generator.py              # cookiecutter-style plugin scaffolding
├── plugin_metadata.py               # ECR plugin registry
├── plugin_query_service.py          # NL plugin query
├── plugin_registry.py               # measurement/plugin catalog
├── utils.py                         # time parsing, timestamp formatting
└── tools/                           # MCP tools split by concern
    ├── sensor_tools.py
    ├── job_tools.py
    ├── geo_tools.py
    ├── plugin_tools.py
    ├── docs_tools.py
    ├── prompts.py
    └── http_routes.py               # /health, /analytics/*, /proxy/image

License

MIT. See LICENSE.

from github.com/waggle-sensor/sage-mcp

Установка Sage Server

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/waggle-sensor/sage-mcp

FAQ

Sage Server MCP бесплатный?

Да, Sage Server MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Sage Server?

Нет, Sage Server работает без API-ключей и переменных окружения.

Sage Server — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить Sage Server в Claude Desktop, Claude Code или Cursor?

Открой Sage Server на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Sage Server with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории development