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
Описание
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:
.envfile (SAGE_USER=…+SAGE_PASS=…) — picked up by both./scripts/run-local-http.shand./scripts/run-local-stdio.shand bydocker compose.- 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
- Query parameter —
?token=username:tokenas 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.
Установка Sage Server
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/waggle-sensor/sage-mcpFAQ
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
GitHub
PRs, issues, code search, CI status
автор: GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
автор: mcpdotdirectCompare Sage Server with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории development
