Skip to content

Data Flow & Observability

Understanding Hatago’s data flow makes troubleshooting and performance tuning much easier.

PointWhat you seeTypical errorsHow to see it
📍1: Hub inputRequest payload, timestampsJSON parse, auth--verbose
📍2: Server I/OForwarded req, latencytimeout, connect--verbose
📍3: Hub outputAggregated responsetransform errors--verbose
Terminal window
hatago serve # default log level is roughly "info"

Typical output: server start/stop, major errors, connection state changes.

Terminal window
# Mirror logs and keep a file
hatago serve --verbose 2>&1 | tee hatago.log
# Watch for warnings and timeouts
hatago serve --verbose 2>&1 | grep -E "(ERROR|WARN|timeout)"
# Timestamp each line (requires moreutils `ts`)
hatago serve --verbose 2>&1 | ts '[%Y-%m-%d %H:%M:%S]'

Enable with HATAGO_METRICS=1, then fetch /metrics.

Terminal window
HATAGO_METRICS=1 hatago serve --http --port 3535
curl -s http://127.0.0.1:3535/metrics | jq .
scripts/monitor-hatago.js
const { spawn } = require('child_process');
const readline = require('readline');
const metrics = { requests: 0, responses: 0, errors: 0, totalTime: 0 };
const hatago = spawn('npx', ['@himorishige/hatago-mcp-hub', 'serve', '--verbose'], { stdio: ['pipe','pipe','pipe'] });
const rl = readline.createInterface({ input: hatago.stderr, crlfDelay: Infinity });
rl.on('line', (line) => {
if (line.includes('Received request')) metrics.requests++;
if (line.includes('Response sent')) metrics.responses++;
if (line.includes('ERROR')) metrics.errors++;
const m = line.match(/\((\d+)ms\)/); if (m) metrics.totalTime += parseInt(m[1]);
if (metrics.requests && metrics.requests % 10 === 0) {
console.log({ ...metrics, avgMs: metrics.totalTime / (metrics.responses || 1) });
}
});
LayerSymptomCommandFirst action
1. Startupcommand not foundwhich hatagoCheck PATH or use npx @.../hatago-mcp-hub
2. ConfigInvalid config`cat hatago.config.jsonjq .`
3. Env${VAR} not foundecho $VARExport or set in .env
4. Server spawnspawn ENOENTwhich npxUse absolute path if needed
5. NetworkECONNREFUSEDcurl -I <url>Verify URL/firewall
6. Auth401 Unauthorizedecho $API_TOKENRefresh token / scopes
7. TimeoutRequest timeouttime curl <url>Increase timeout / retry
Terminal window
# Extract timing markers from verbose logs
hatago serve --verbose 2>&1 \
| grep -oE '\\(([^)]*)ms\\)' \
| grep -oE '[0-9]+' \
| awk '{sum+=$1; n++} END{print "avg:", (n?sum/n:0) "ms"}'
scripts/diagnose-hatago.sh
#!/usr/bin/env bash
echo "🔍 Hatago diagnose"
echo "Node.js: $(node --version)"
echo "npm: $(npm --version)"
echo "Hatago: $(npx @himorishige/hatago-mcp-hub --version 2>/dev/null || echo 'Not installed')"
echo "\n📄 Config:"
if [ -f hatago-config.json ]; then
jq . hatago-config.json >/dev/null 2>&1 && echo "✅ Valid JSON" || echo "❌ Invalid JSON"
echo "Servers: $(jq '.mcpServers | length' hatago-config.json)"
else
echo "❌ hatago-config.json not found"
fi
echo "\n🌐 Quick check:"
echo '{"jsonrpc":"2.0","method":"resources/read","id":1,"params":{"uri":"hatago://servers"}}' \
| timeout 5 npx @himorishige/hatago-mcp-hub serve --stdio 2>/dev/null \
| jq -r '.result.contents[0].text' \
| jq -r '.total' \
| grep -Eq '^[0-9]+$' && echo "✅ Hub is responding" || echo "❌ Hub not responding"

Architecture

Troubleshooting

Config Reference