A portable Node.js/TypeScript tool for managing a Morpheus Lumerin AI inference provider node. It exposes all provider operations—health checks, model management, bid adjustment, earnings claiming, and balance monitoring—through three interfaces: a CLI for terminal use, an MCP server for AI coding agents (Claude Code, Cline, Continue.dev, OpenCode), and an OpenAI function-calling schema for any agent using the OpenAI tools API. An optional autonomous ops agent monitors the node on a configurable interval, auto-claims earnings, alerts on low balances, and restarts the proxy-router when it goes down.
flowchart TB
subgraph interfaces["Interfaces"]
CLI["CLI\nmorpheus-node-manager"]
MCP["MCP Server\nmorpheus-node-manager-mcp"]
OAI["OpenAI Tools\ntools + handleToolCall()"]
end
subgraph agents["AI Agents"]
CC["Claude Code"]
CLINE["Cline / Continue.dev"]
AGENT["Any OpenAI-compatible agent"]
end
subgraph core["Core Layer (src/core/)"]
CLIENT["client.ts\nHTTP + endpoint allowlist"]
HEALTH["health.ts\ntwo-stage health check"]
MODELS["models.ts\nlist / add / remove"]
BIDS["bids.ts\nadjust bid"]
EARN["earnings.ts\nclaim sessions"]
PROV["provider.ts\nbalances + BigInt wei"]
end
subgraph opsagent["Ops Agent (Docker)"]
LOOP["agent.ts\n5-min monitoring loop"]
AUDIT["audit.ts\nappend-only log"]
ALERTS["alerts.ts\nTelegram / Slack webhook"]
end
subgraph hetzner["Hetzner VPS 5.161.177.217"]
ROUTER["morpheus-router\nproxy-router process\n:3333 inference :8082 API"]
end
subgraph backends["Inference Backends"]
VENICE["Venice AI\nGLM-5, Kimi K2.5"]
AKASH["AkashChat\nOpenRouter\nOllama ..."]
end
subgraph chain["Arbitrum Mainnet"]
MARKET["Morpheus Marketplace\nbids · sessions · MOR payments"]
end
CC --> MCP
CLINE --> MCP
AGENT --> OAI
CLI --> core
MCP --> core
OAI --> core
core --> CLIENT
CLIENT -->|"REST API\nbasic auth"| ROUTER
ROUTER -->|"OpenAI-compatible"| VENICE
ROUTER -->|"OpenAI-compatible"| AKASH
ROUTER <-->|"Arbitrum RPC\nbids · sessions · claims"| MARKET
LOOP --> core
LOOP --> AUDIT
LOOP --> ALERTS
LOOP -->|"systemctl restart"| ROUTER
npm install -g morpheus-node-manager
# Check node health (process alive + blockchain connected)
morpheus-node-manager status --url http://localhost:8082 --password admin
# List marketplace models with your active bids highlighted
morpheus-node-manager models
# Check ETH and MOR wallet balances
morpheus-node-manager balances
# Register a new model with an opening bid
morpheus-node-manager add-model \
--name "glm-4-9b" \
--ipfs-cid QmYourModelCard \
--stake-wei 100000000000000000 \
--price-wei 100000000 \
--api-type openai \
--api-url https://api.venice.ai/api/v1 \
--api-key YOUR_VENICE_KEY \
--model-name glm-4-9bRequires Node.js >= 22.
| Tool | What it does |
|---|---|
node_status |
Two-stage health check: first confirms the process responds to /healthcheck, then verifies blockchain connectivity via /blockchain/latestBlock. Returns wallet address, formatted ETH/MOR balances, active bid count, active session count, and provider registration status. |
list_models |
All models registered on the Morpheus marketplace. Your active bids are surfaced inline on each model (myBid field) with current price and bid ID. |
add_model |
Register a model on-chain and post an opening bid in a single call. Accepts all 6 proxy-router backend apiType values. Returns the new model ID and bid ID. |
remove_model |
Remove a model and all your bids for it. Requires a confirm token of the form DELETE_MODEL_<first8chars> to prevent accidental deletion. |
adjust_bid |
Update your price for a model. Deletes the existing bid and posts a new one. Note: there is a brief (<1s) bid gap between the delete and re-post. |
claim_earnings |
Inspect and claim MOR from completed provider sessions. Supports dry-run mode, per-call claim caps, and a minimum claimable threshold. |
check_balances |
ETH and MOR balances for the node wallet, returned in both human-readable format (0.05 ETH) and raw wei. |
provider_info |
Provider registration record: stake, fee (basis points), registered endpoint, and all currently active bids. |
morpheus-node-manager <command> [options]
Commands:
status Check node health and status
models List marketplace models and your bids
add-model Register a new model on the marketplace
remove-model Remove a model (requires --model-id and --confirm)
adjust-bid Adjust your bid price for a model
claim Claim earnings from provider sessions
balances Check ETH and MOR balances
provider Show provider registration info
Global options:
--url <url> Proxy-router API URL (default: http://localhost:8082)
--user <user> API basic auth user (default: admin)
--password <pwd> API basic auth password
--cookie <path> Path to proxy-router .cookie file
--insecure Allow http:// for non-localhost URLs (trusted networks only)
All commands return JSON to stdout. The status command exits with code 1 if the node is unhealthy, making it suitable for use in shell scripts and health checks.
Examples:
# Claim up to 5 sessions, minimum 0.001 MOR each
morpheus-node-manager claim --max-claims 5 --min-claimable 1000000000000000
# Dry-run: see what's claimable without submitting transactions
morpheus-node-manager claim --dry-run
# Adjust bid price
morpheus-node-manager adjust-bid --model-id 0xabcdef1234... --price-wei 200000000
# Remove a model (first 8 chars of model ID required in confirm token)
morpheus-node-manager remove-model \
--model-id 0xabcdef1234567890 \
--confirm DELETE_MODEL_0xabcdef
# Read password from proxy-router .cookie file automatically
morpheus-node-manager status --cookie /path/to/proxy-router/.cookieAny OpenAI-compatible endpoint works with --api-type openai. These providers are ready to use:
| Provider | Base URL | Notes |
|---|---|---|
| Venice AI | https://api.venice.ai/api/v1 |
DIEM credits; free tier available |
| AkashChat | https://chatapi.akash.network/api/v1 |
Always free |
| AkashML | https://api.akashml.com/v1 |
$100 signup credit |
| NEAR AI | https://cloud-api.near.ai/v1 |
Beta; free |
| OpenRouter | https://openrouter.ai/api/v1 |
300+ models; USDC accepted |
| Together AI | https://api.together.xyz/v1 |
$25 credit |
| Hyperbolic | https://api.hyperbolic.xyz/v1 |
Free tier; use openai type for LLM, hyperbolic-sd for image gen |
| Local Ollama | http://localhost:11434/v1 |
Self-hosted; always free |
For Anthropic Claude directly, use --api-type claudeai. For image generation, use prodia-v2, prodia-sd, prodia-sdxl, or hyperbolic-sd.
The MCP server exposes all 8 tools over stdio, compatible with any MCP client.
Claude Code (~/.claude/claude_desktop_config.json or .mcp.json):
{
"mcpServers": {
"morpheus": {
"command": "node",
"args": ["/path/to/morpheus-node-manager/dist/mcp-server.js"],
"env": {
"MORPHEUS_API_URL": "http://localhost:8082",
"MORPHEUS_API_PASSWORD": "your-password"
}
}
}
}Cline (.clinerules or MCP settings):
{
"mcpServers": {
"morpheus": {
"command": "morpheus-node-manager-mcp",
"env": {
"MORPHEUS_API_URL": "http://localhost:8082",
"MORPHEUS_API_PASSWORD": "your-password"
}
}
}
}If installed globally via npm, the binary morpheus-node-manager-mcp is available directly. Otherwise point to dist/mcp-server.js with node.
The MCP server reads configuration from environment variables. All MORPHEUS_* env vars apply (see Configuration).
For agents using the OpenAI tools API directly:
import { tools, handleToolCall } from 'morpheus-node-manager';
const config = {
apiUrl: 'http://localhost:8082',
apiUser: 'admin',
apiPassword: 'your-password',
};
// Pass tools to your OpenAI API call
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages,
tools,
tool_choice: 'auto',
});
// Handle tool calls from the response
for (const call of response.choices[0].message.tool_calls ?? []) {
const result = await handleToolCall(
call.function.name,
JSON.parse(call.function.arguments),
config
);
// result is a JSON string — add to messages as a tool response
}tools is a static array of OpenAI function-calling schema objects. handleToolCall(name, args, config) dispatches to the appropriate core function and returns a JSON string result. Both are typed exports from dist/index.js.
An autonomous monitoring daemon that runs on a configurable interval (default: every 5 minutes).
What it does each cycle:
- Two-stage health check — if the node is unhealthy, restarts the proxy-router service (systemctl on Linux, launchctl on macOS) up to
maxConsecutiveRestartstimes before alerting and stopping - Balance check — sends an alert if ETH or MOR drops below configured thresholds
- Auto-claim — claims earnings from completed sessions, respecting a per-cycle cap and minimum claimable amount
- Bid presence check — alerts if any registered model has no active bid
Circuit breakers:
- Restart cap: stops auto-restarting after
maxConsecutiveRestartsconsecutive failures and sends a critical alert - Claim rate limit: per-session timestamps prevent redundant claim attempts
- Lockfile: prevents concurrent runs (stale locks are detected and cleared)
- Startup grace: non-critical alerts suppressed until 2 consecutive healthy checks
Running the ops agent:
# One-shot check (suitable for cron)
node dist/ops-agent/index.js --once --config /etc/morpheus-node-manager/config.json
# Daemon mode (runs continuously on configured interval)
node dist/ops-agent/index.js --config /etc/morpheus-node-manager/config.jsonConfiguration — copy templates/config.example.json and edit:
{
"apiUrl": "http://localhost:8082",
"apiUser": "admin",
"apiPassword": "CHANGE_ME",
"checkIntervalMs": 300000,
"thresholds": {
"minMorWei": "500000000000000000",
"minEthWei": "10000000000000000"
},
"autoClaim": true,
"maxClaimsPerCycle": 5,
"autoRestart": true,
"maxConsecutiveRestarts": 3,
"alerts": {
"webhookUrl": "",
"type": "generic"
}
}type accepts "telegram", "slack", or "generic" (generic sends a JSON POST with { title, body, severity }).
Deployment templates are in templates/:
morpheus-ops-agent.service+morpheus-ops-agent.timer— systemd (Linux)com.morpheus.ops-agent.plist— launchd (macOS)
The ops agent writes an append-only JSON audit log (audit.json by default) recording every health check, claim, restart, and alert. State is persisted to state.json across runs.
The HTTP client enforces a strict allowlist. Any endpoint not on the list throws before making a network request. The following endpoints are additionally blocked regardless of allowlist position:
| Blocked path | Reason |
|---|---|
POST /blockchain/send/eth |
Irreversible ETH transfer |
POST /blockchain/send/mor |
Irreversible MOR transfer |
DELETE /wallet |
Removes the wallet entirely |
POST /wallet/mnemonic |
Replaces the wallet seed phrase |
POST /wallet/privateKey |
Replaces the wallet private key |
GET /docker/* |
Remote code execution risk |
GET /ipfs/download/* |
Path traversal risk |
Additional security behaviors:
remove_modelconfirmation token. The tool requiresconfirm: "DELETE_MODEL_<first8chars_of_modelId>". This is enforced in code before any API call is made. The wrong token throwsConfirmation mismatch.- HTTPS enforcement.
http://is refused for non-localhost URLs. Use--insecureorMORPHEUS_INSECURE=trueonly when connecting over an SSH tunnel, VPN, or private network you control. - Config file permissions.
~/.morpheus-node-manager.jsonis written with mode0600. The config loader warns if the file is group- or world-readable. adjust_bidgap. Adjusting a bid deletes the old bid before posting the new one. For high-traffic models, plan bid adjustments during low-traffic windows.
Priority order: CLI flags > environment variables > ~/.morpheus-node-manager.json > .cookie file > defaults.
| Environment variable | CLI flag | Description | Default |
|---|---|---|---|
MORPHEUS_API_URL |
--url |
Proxy-router REST API URL | http://localhost:8082 |
MORPHEUS_API_USER |
--user |
Basic auth username | admin |
MORPHEUS_API_PASSWORD |
--password |
Basic auth password | (empty) |
MORPHEUS_COOKIE_PATH |
--cookie |
Path to proxy-router .cookie file |
(none) |
MORPHEUS_INSECURE |
--insecure |
Allow http:// for non-localhost |
false |
The .cookie file is the password file written by the proxy-router at startup. If the file contains user:password, only the password portion is used.
To persist configuration so you don't have to pass flags every time:
# Write config manually
cat > ~/.morpheus-node-manager.json << EOF
{
"apiUrl": "http://localhost:8082",
"apiUser": "admin",
"apiPassword": "your-password"
}
EOF
chmod 600 ~/.morpheus-node-manager.jsongit clone https://github.com/betterbrand/Morpheus-skilled-agent.git
cd Morpheus-skilled-agent
npm install
npm run build
npm testThe test suite runs 21 tests against an in-process mock HTTP server — no running proxy-router required. Tests cover the client allowlist, health check logic, balance formatting (BigInt-safe), bid active/inactive detection, model listing, remove_model confirmation guard, and config HTTPS enforcement.
npm test
client allowlist
- blocks POST /blockchain/send/eth
- blocks DELETE /wallet
- blocks POST /wallet/privateKey
- blocks GET /docker/anything
- blocks GET /ipfs/download/file
node_status
- returns healthy when both healthcheck and latestBlock succeed
- includes formatted balances
- reports activeBids from wrapped response
checkBalances
- returns formatted ETH and MOR (lowercase API keys)
weiToFormatted
- formats 1 ETH correctly
- formats 0.05 ETH correctly
- handles BigInt safely (no precision loss at large values)
bidIsActive
- treats DeletedAt='0' as active
- treats DeletedAt=null as active
- treats non-zero DeletedAt as inactive
listModels
- returns models with bid info from wrapped response
removeModel confirmation guard
- rejects wrong confirm token
- accepts correct DELETE_MODEL_<first8> token
config
- rejects http:// for remote URLs
- allows http:// for localhost
- allows http:// for remote with --insecure
- strips trailing slash from URL
ℹ tests 21
✓ pass 21
Morpheus is a decentralized AI marketplace. Providers stake MOR tokens, register models, and post bids to sell inference capacity to users. The proxy-router is the provider's node software: it manages sessions, validates payments on-chain, and routes inference requests to a backend (Venice AI, AkashChat, OpenRouter, local Ollama, etc.). This tool wraps the proxy-router's REST API to make provider operations scriptable and agent-accessible.
Published at: https://github.com/betterbrand/Morpheus-skilled-agent