HexagonML ModelManager MCP Server
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
HexagonML ModelManager MCP Server
A modular MCP server for interacting with the HexagonML ModelManager API, with full tool discoverability and clean architecture.
Architecture
server/
├── config.py # Environment configuration and server setup
├── auth.py # Per-caller ModelManager credential resolution
├── clients.py # ModelManager API client factory and context
├── health.py # HTTP /health endpoint
├── main.py # Main entry point (standalone mode)
├── server_simple.py # FastMCP CLI entry point
├── tools/
│ ├── model_tools.py # Model management tools
│ ├── usecase_tools.py # Usecase management tools
│ ├── modelcard_tools.py # Model card management tools
│ ├── forecasting_tools.py # Forecasting tools
│ └── forecasting_governance_tools.py # Governance report tools
├── handlers/
│ ├── response_handlers.py # API response classification and formatting
│ └── prompt_handler.py # MCP prompt templates
└── utils/
├── helpers.py # Response handling and validation helpers
├── validators.py # Payload validation functions
└── base.py # Base classes and common patternsRelated MCP server: RAGFlow MCP Server
Available Tools
Model Management
Tool | Description |
| Upload a new ML model |
| Update model metadata or configuration |
| Permanently delete a model |
| Retrieve model performance metrics |
Usecase Management
Tool | Description |
| Create a new usecase (supports Forecasting type) |
| Update usecase configuration |
| Permanently delete a usecase |
| List all usecases |
Model Cards
Tool | Description |
| Generate a model card for a model |
| Retrieve model card data with optional filtering |
Forecasting
Tool | Description |
| Retrieve forecasts for a usecase |
MCP Prompts
Prompt | Description |
| Instructs the LLM how to narrate forecast results to users |
Configuration
Copy .env.example to .env and fill in your values:
cp .env.example .envVariable | Required | Default | Description |
| Yes | — | Base URL of the ModelManager API |
| Yes | — | Directory for generated output files |
| No | — | Fallback ModelManager credential, used only when the calling client sends none. Set it for single-user servers; leave it unset for shared deployments (see Authentication) |
| No |
| Network interface the server listens on |
| No |
| Port the server listens on |
Docker note:
MM_API_BASE_URL=http://127.0.0.1:8000will not resolve from inside a container. Usehttp://host.docker.internal:8000on Mac/Windows, orhttp://172.17.0.1:8000on Linux. In Kubernetes use the in-cluster Service DNS name, e.g.http://mm.tai-mm-ws.svc.cluster.local:8000.
Authentication
Every ModelManager call this server makes is authenticated with an mmgr3 credential. Whose credential depends on how you deploy:
Deployment |
| Who ModelManager sees |
Shared — one HTTP server, many people | unset | Each caller, via the key they send on the request |
Single-user — local stdio, CI job | set | The account that owns |
A caller-supplied credential always wins; MM_API_KEY applies only when the caller sent none.
Callers pass their credential in either header:
Authorization: Api-Key <your-personal-key> # preferred
X-MM-API-Key: <your-personal-key> # when a proxy already uses AuthorizationAuthorization: Bearer <jwt> also works, since mmgr3 accepts JWTs on the same endpoints — but a JWT expires after 60 minutes, so personal API keys are the right choice for MCP clients. Any other scheme is ignored rather than forwarded.
Users generate their own key on the MCP Endpoints page (/mcp) in ModelManager; it is displayed exactly once. Keys are named, revocable, and optionally expiring, so each client can be revoked independently.
Don't set
MM_API_KEYon a shared deployment. It becomes an anonymous fallback identity that any caller who can reach the port inherits, which defeats per-user attribution and revocation. The published image excludes.env, so a deployed container is passthrough-only unless you explicitly set the variable.
A tool call with no usable credential is rejected before the tool runs, with a message naming the header to send.
Running the Server
Option 1: FastMCP CLI (recommended)
fastmcp run server/server_simple.py --transport http --host 0.0.0.0 --port 9000Option 2: Standalone Python
python server/main.pyOption 3: Development / Inspector
fastmcp dev server/server_simple.pyOption 4: Docker Compose
# Build and start
docker compose up --build
# Run in background
docker compose up --build -d
# Stop
docker compose downOption 5: Docker (manual)
# Build
docker build -t hex-mm-mcp:latest .
# Run
docker run -d --name hex-mm-mcp \
-p 9000:9000 \
--env-file .env \
hex-mm-mcp:latestConnecting an MCP client
Two things are needed in every case: the server's URL (its MCP endpoint is /mcp) and your own ModelManager API key from the /mcp page in ModelManager.
A deployed server (the normal case)
Point the client at the deployed URL and send your key as a header. This is the shared-deployment shape — everyone uses the same URL with their own key.
Claude Code — one command:
claude mcp add --transport http hex-mm-mcp https://mcp.example.com/mcp \
--header "Authorization: Api-Key ${MM_API_KEY}"Claude Code / VS Code / Cursor — or by config file (.mcp.json in a project, or the client's own settings):
{
"mcpServers": {
"hex-mm-mcp": {
"type": "http",
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Api-Key YOUR_PERSONAL_KEY"
}
}
}
}Claude Desktop and other clients that only launch local commands — bridge to the remote server with mcp-remote:
{
"mcpServers": {
"hex-mm-mcp": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://mcp.example.com/mcp",
"--header", "Authorization:Api-Key YOUR_PERSONAL_KEY"
]
}
}
}Replace https://mcp.example.com/mcp with your deployment's URL and YOUR_PERSONAL_KEY with the key you generated. Prefer your client's secret/environment-variable support over pasting the key into a file that gets committed.
Verify the endpoint is reachable before wiring up a client:
curl https://mcp.example.com/health
# {"status":"healthy","service":"hexagonml-modelmanager-mcp"}A local server you run yourself
Single-user, so the key can live in the server's environment (MM_API_KEY in .env) instead of in each client's config:
{
"mcpServers": {
"hex-mm-mcp": {
"command": "fastmcp",
"args": [
"run",
"/path/to/hex-mm-mcp/server/server_simple.py",
"--transport", "http",
"--host", "127.0.0.1",
"--port", "9000"
]
}
}
}Local Docker
{
"mcpServers": {
"hex-mm-mcp": {
"command": "docker",
"args": [
"run", "--rm", "-i", "--network=host",
"-e", "MM_API_KEY",
"-e", "MM_API_BASE_URL",
"-e", "OUTPUT_DIR",
"hex-mm-mcp:latest"
],
"env": {
"MM_API_KEY": "your-api-key",
"MM_API_BASE_URL": "http://host.docker.internal:8000",
"OUTPUT_DIR": "/tmp/mm-output"
}
}
}
}LLM Presentation Guidance
The get_forecast tool uses two complementary mechanisms to guide how the LLM presents forecast data to users.
Embedded _llm_instructions
Every get_forecast response includes a _llm_instructions field. The LLM reads this automatically as part of the tool result and follows the rules when composing its reply — no client configuration needed.
Key rules embedded in every response:
Lead with the summary (date range, value range min/max/avg)
Explain
lower_bound/upper_boundas a confidence intervalReference
last_actual_updateto indicate data freshnessFlag
resolved: falseas an unresolvable requestAvoid echoing raw JSON back to the user
MCP Prompt (forecast_presentation_guide)
A named MCP prompt is also registered on the server. MCP-aware clients (Claude Desktop, MCP Inspector) can fetch it and inject it as a system prompt at the start of a conversation, priming the LLM for the whole session rather than per-call.
To use it in a client that supports MCP prompts:
prompts/get → forecast_presentation_guideMechanism | When it fires | Client support needed |
| Every | None — automatic |
| On explicit prompt request | MCP prompt-capable client |
Development
Tests
uv run --with pytest python -m pytest tests/ -qtests/conftest.py puts server/ on sys.path, so tests import the modules the
same way fastmcp runs them (from config import mcp).
CI (.github/workflows/mcp-ci.yml) gates every push
on those tests plus a check that the server still imports and registers its tools,
then publishes modelmanagerdev/mcp:<git-sha> — an immutable tag, so a deployment
always traces back to an exact commit.
Adding a New Tool
Create a new module (e.g.,
server/new_tools.py)Import
mcpfromconfigand use the@mcp.tooldecoratorImport the module in
server/server_simple.py
# server/new_tools.py
from fastmcp import Context
from config import mcp
from clients import get_mm_client
from utils import safe_response_to_dict, create_error_response
import asyncio
@mcp.tool(
name="new_tool",
description="Description of the tool",
tags={"category", "modelmanager"},
meta={"version": "1.0", "author": "HexagonML"},
)
async def new_tool(ctx: Context, required_param: str, optional_param: str = None) -> dict:
"""Tool docstring shown in MCP playgrounds."""
if not required_param or not required_param.strip():
return create_error_response(
message="required_param is required",
error_type="ValidationError"
)
await ctx.info("Starting operation")
await ctx.report_progress(progress=20, total=100)
try:
client = get_mm_client(ctx, 'client_type')
await ctx.report_progress(progress=40, total=100)
response = await asyncio.to_thread(client.api_method, required_param)
await ctx.report_progress(progress=80, total=100)
result = safe_response_to_dict(response)
await ctx.info("Operation completed")
await ctx.report_progress(progress=100, total=100)
return result
except ValueError as e:
await ctx.error(f"Validation error: {str(e)}")
return create_error_response(
message="A validation error occurred. Please check your input.",
error_type="ValidationError"
)
except Exception as e:
await ctx.error(f"Operation failed: {str(e)}")
return create_error_response(
message="An internal error occurred. Please try again.",
error_type="InternalError"
)Troubleshooting
Port already in use
kill -9 $(lsof -t -i:9000)
# or use a different port
fastmcp run server/server_simple.py --port 9001Missing environment variables
The server exits at startup with a message listing which of MM_API_BASE_URL and OUTPUT_DIR are missing. MM_API_KEY is optional and its absence is normal for a shared deployment.
"No ModelManager credential for this request"
The calling client sent no credential and the server has no MM_API_KEY fallback. Add Authorization: Api-Key <key> to the client's config (see Connecting an MCP client).
401 from ModelManager on every tool call
The credential reached ModelManager but was rejected — the key is revoked, expired, or mistyped. Check its status badge on the /mcp page in ModelManager and generate a new one if needed. Note the scheme is Api-Key, not Bearer.
Connection refused / API errors
Confirm the ModelManager API is reachable at
MM_API_BASE_URLWhen running in Docker, see the Docker note in the Configuration section above
Verify the key in use is a valid, non-expired key issued from ModelManager's
/mcppage and that its owning account can access the use case
License
MIT License — see the LICENSE file for details.
This server cannot be deployed
Maintenance
Related MCP Connectors
A Model Context Protocol server for Wix AI tools
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
List models, read model details and send chat messages in Cerebras.
The Google GKE MCP server is a managed Model Context Protocol server that provides AI applications with tools to manage Google Kubernetes Engine (GKE) clusters and Kubernetes resources. It exposes a structured, discoverable interface that allows AI agents to interact with GKE and Kubernetes APIs, enabling them to inspect cluster configurations, retrieve Kubernetes resource YAMLs, monitor operations like cluster upgrades, diagnose issues, and optimize costs—all without needing to parse text output or use complex kubectl commands.
Related MCP Servers
- FlicenseBqualityDmaintenanceImplements the Model Context Protocol (MCP) to provide AI models with a standardized interface for connecting to external data sources and tools like file systems, databases, or APIs.1153-
- AlicenseNot gradedqualityDmaintenanceProvides a comprehensive Model Context Protocol interface for RAGFlow, enabling AI models to perform semantic retrieval, manage datasets, and handle document chunks. It supports advanced features like GraphRAG and RAPTOR for sophisticated knowledge base management and natural language querying.MIT
- AlicenseNot gradedqualityDmaintenanceProvides a standardized interface for interacting with Semrush's tools and services through a unified API using the Model Context Protocol.2MIT
- AlicenseNot gradedqualityDmaintenanceImplements the Model Context Protocol for managing, ingesting, and querying structured and unstructured data with integration to graph databases, vector search, and LLMs.3MIT