BetterDB MonitorBLOCK
Real-time monitoring, slowlog analysis, and audit trails for Valkey and Redis
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://hub.docker.com/r/betterdb/monitor) [](https://hub.docker.com/r/betterdb/monitor/tags) [](https://artifacthub.io/packages/search?repo=betterdb-monitor) [](https://www.npmjs.com/package/@betterdb/monitor) [](https://www.npmjs.com/package/@betterdb/monitor) [](https://github.com/betterdb-inc/monitor/actions/workflows/api-tests.yml) [](LICENSE) [](https://valkey.io) [](https://redis.io)
The monitoring layer that Valkey deserves.
BetterDB persists what Valkey throws away - slowlogs, command patterns, client activity, anomaly signals - so you can debug what happened at 3am, not just what's happening now. Built for Valkey 8.x with native support for COMMANDLOG, CLUSTER SLOT-STATS, and per-thread I/O metrics. Redis 6+ compatible for everything else.
Website | Docker Hub | npm | Documentation | Blog
BetterDB is built by BetterDB Inc., a public benefit company operating under the OCV Open Charter.
![BetterDB Monitor - Key Analytics with per-type key size distribution h
cffef10ac693OBSERVED · 2026-09-24Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add mcp --env BETTERDB_TOKEN=${BETTERDB_TOKEN} -- npx -y @betterdb/[email protected]Exposed tools (78)
69 read · 8 write · 1 destructive. Blast radius: 1 tool can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
add_connection | write | Add a new Valkey/Redis connection to BetterDB. Optionally set it as the active default. |
ai_instance_history | read | Get the stored metrics time-series for one AI component instance (hits, misses, hit rate, cost saved, evictions, item count, index size, threshold). Use ai_list_instances first to find the instance field identifier. Use this to see trends: hit-rate degradation, growth, threshold drift. |
ai_list_instances | read | |
cache_approve_proposal | read | Approve a pending proposal. Synchronously applies the change to Valkey and returns the terminal status (applied|failed). Idempotent: a second call on an already-applied proposal returns the cached result. |
cache_edit_and_approve_proposal | write | Edit an existing pending proposal and approve it in one step. Provide exactly one edit field matching the proposal type: new_threshold for threshold_adjust, new_ttl_seconds for tool_ttl_adjust. Invalidate proposals are not editable. |
cache_get_proposal | read | Fetch a single cache proposal by id, including its audit trail. |
cache_health | read | Detailed health for a single cache. Response branches by type: semantic_cache reports category_breakdown + uncertain_hit_rate; agent_cache reports tool_breakdown. |
cache_list | read | List all caches (semantic_cache and agent_cache) registered for the active instance, with hit rate and total ops. |
cache_list_pending_proposals | read | List pending cache proposals for the active instance, newest first. Optionally filter by cache_name. |
cache_propose_invalidate | read | Propose a cache invalidation for review. Filter shape depends on cache type: semantic_cache requires filter_kind=valkey_search + filter_expression; agent_cache requires filter_kind in (tool|key_prefix|session) + filter_value. Warns when estimated_affected exceeds 10000. |
cache_propose_threshold_adjust | read | Propose a semantic-cache similarity-threshold change for review. Creates a pending proposal that requires human approval before any change is applied. Reasoning must be at least 20 characters. |
cache_propose_tool_ttl_adjust | read | Propose an agent-cache per-tool TTL change for review. Creates a pending proposal that requires human approval. Reasoning must be at least 20 characters. |
cache_recent_changes | read | Recent proposals for a single cache (any status), so agents can avoid re-proposing pending or recently-applied changes. Newest first. |
cache_reject_proposal | read | Reject a pending proposal. Optionally records a reason in the audit trail. |
cache_similarity_distribution | read | Histogram of recent similarity scores (20 buckets, width 0.1) for a semantic_cache. Errors on agent_cache. |
cache_threshold_recommendation | read | Threshold-tuning recommendation for a semantic_cache, based on the rolling similarity-score window. Errors with INVALID_CACHE_TYPE on agent_cache. |
cache_tool_effectiveness | read | Per-tool hit rate, cost saved, and TTL recommendation for an agent_cache. Errors with INVALID_CACHE_TYPE on semantic_cache. |
calculate | read | Math helper |
capability | read | Runtime capability key (e.g. canSlowLog, canCommandLog, canLatency) |
correlate_ai_trace | read | |
deliveryId | read | Delivery ID |
eventName | read | Name of the latency event |
get_acl_audit | read | Get persisted ACL audit log entries from storage. Filter by username, reason (auth, command, key, channel), or time range. Use this to investigate why a connection is failing or audit access patterns. |
get_acl_failures | read | Get ACL/authentication failures from audit log |
get_ai_trace | read | Get the full span waterfall for one AI trace: every span with timing, parent relationships, and attributes (model, cache hit/miss, similarity scores). Use list_ai_traces to find trace IDs. |
get_anomalies | read | Get anomaly detection events from persisted storage. BetterDB continuously runs Z-score analysis on memory, hit rate, CPU, and other metrics — this returns the detected anomalies. Use to investigate what triggered an alert or correlate with an incident. |
get_client_activity | read | Get time-bucketed client activity from persisted snapshots. Shows connection counts, command distribution, and buffer usage over time. Use startTime/endTime to focus on a specific incident window. |
get_client_analytics | read | Get client connection analytics and trends |
get_client_list | read | Get list of connected clients grouped by name |
get_clients | read | Get the active client list with connection details. |
get_cluster_node_stats | read | Get per-node performance stats: memory usage, ops/sec, connected clients, replication offset, and CPU. Use this to identify hot nodes, lagging replicas, or uneven load distribution. |
get_cluster_nodes | read | Discover all nodes in the Valkey cluster — role (master/replica), address, health status, and slot ranges. Returns an error message if this instance is not running in cluster mode. |
get_cluster_slowlog | read | Get the aggregated slowlog across ALL nodes in the cluster. This is the primary tool for finding slow commands in cluster mode — per-node slowlogs are incomplete. Returns an error message if not in cluster mode. |
get_commandlog | read | Get the most recent entries from COMMANDLOG (Valkey 8+ only, superset of slowlog). |
get_commandlog_history | read | Get persisted COMMANDLOG entries from storage (Valkey 8+ only). Supports time range filtering to investigate specific incidents. Returns empty with a note if COMMANDLOG is not supported on this instance. |
get_commandlog_patterns | read | Get analyzed COMMANDLOG patterns from persisted storage (Valkey 8+ only). Like get_slowlog_patterns but includes large-request and large-reply patterns in addition to slow commands. |
get_connected_clients | read | Get number of connected and blocked clients |
get_forecast | read | Get a capacity forecast for one metric: current trajectory and projected time until the resource ceiling is hit. Metric kinds: opsPerSec, usedMemory, cpuTotal, memFragmentation. Use for capacity planning ( |
get_health | read | |
get_hot_keys | read | |
get_inference_latency | read | |
get_info | read | Get INFO stats for the active instance. Contains all health data: memory, clients, replication, keyspace, stats (hit rate, ops/sec), and server info. Optionally filter to a section: server|clients|memory|stats|replication|keyspace. |
get_key_count | read | Get total number of keys in the database |
get_largest_keys | read | |
get_latency | read | Get latency event history for the active instance. |
get_latency_history | read | Get the full latency history for a named event (e.g. |
get_latency_regressions | read | Get detected latency regressions (sustained p99 command-latency degradations vs baseline) from persisted storage. Companion to get_anomalies: same event store, pre-filtered to latency regressions. Use when investigating |
get_memory | read | Get memory diagnostics: MEMORY DOCTOR assessment and MEMORY STATS breakdown. |
get_memory_usage | read | Get memory usage statistics |
get_server_status | read | Get current server status: connected clients, memory usage, ops/sec, total keys, uptime |
get_slot_stats | read | Get per-slot key counts and CPU usage (Valkey 8.0+ only). Use orderBy= |
get_slowlog | read | Get the most recent slow commands from the slowlog. |
get_slowlog_patterns | read | Get analyzed slowlog patterns from persisted storage. Groups slow commands by normalized pattern, showing frequency, average duration, and example commands. Survives slowlog buffer rotation — data goes back as far as BetterDB has been running. |
get_vector_indexes | read | Get health details for every vector search index on the instance: document count, memory usage, indexing failures, and percent indexed. Requires the Search module (valkey-search / RediSearch) on the connection — errors clearly if absent. Use to diagnose incomplete indexing or index memory growth. |
get_weather | read | Get current weather for a city |
id | write | Connection ID to set as default |
list_ai_traces | read | List recent AI application traces ingested via OpenTelemetry (LLM calls, cache lookups, memory recalls, retrieval spans). Not tied to a Valkey instance — traces come from instrumented AI apps. Use get_ai_trace for a full span waterfall and correlate_ai_trace to join a trace with live Valkey state. |
list_instances | read | List all Valkey/Redis instances registered in BetterDB. Shows connection status and capabilities. |
memory_approve_forget | read | Approve a pending forget proposal, applying the deletion against the live store. |
memory_forget | read | Propose forgetting memories (by id, or by scope/tags). Creates a pending proposal that a human must approve before anything is deleted. |
memory_get | read | Fetch a single memory by ID from a store. |
memory_list | read | List memories in a store, newest first, with optional scope and tag filters. |
memory_list_pending_forgets | read | List pending forget proposals awaiting approval on an instance. |
memory_recall | read | Recall memories from a store by a precomputed query vector (the caller supplies the embedding). |
memory_reject_forget | read | Reject a pending forget proposal without deleting anything. |
memory_stats | read | Get item count, eviction count, and live config for a memory store. |
memory_stores | read | List agent-memory stores discovered on an instance (name, capabilities, stats key). |
nodeId | read | Node ID |
parameter | read | Configuration parameter name |
remove_connection | destructive | Remove a connection from BetterDB. |
run_latency_diagnosis | write | Run latency diagnostic analysis |
run_memory_diagnosis | write | Run memory diagnostic analysis |
search | read | Search web |
select_instance | read | Select which instance subsequent tool calls operate on. |
set_default_connection | write | Set a connection as the active default for BetterDB. |
start_monitor | write | Start the BetterDB monitor as a persistent background process. If already running, returns the existing URL. The monitor persists across MCP sessions and must be stopped explicitly with stop_monitor. |
stop_monitor | write | Stop a persistent BetterDB monitor process that was previously started with start_monitor or --autostart --persist. |
test_connection | read | Test a Valkey/Redis connection without persisting it. Use before add_connection to validate credentials. |
Trust audit
BLOCKgrade F · trust 36/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | FAIL |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (11 observation(s))
- Network
- declared (8 observation(s))
- Shell
- declared (5 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (25)
LICENSE_SIGNING_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
BROKER_SIGNING_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
webhook-payload-formatter.ts
return new Function('specifier', 'return import(specifier)') as EsmImport;exec(
exec(`npx esbuild src/index.ts --bundle --platform=node --target=node20 --outfile=dist/index.js --external:@inquirer/prompts --external:commander --external:picocolors --define:__CLI_VERSION__='"${cliplaceholder="id_ed25519"
proprietary/node_modules
this.logger.warn(`Failed to update lastUsedAt for token ${token.id}: ${String(error)}`);console.log(`[Agent] Rebuilding Valkey client with fresh IAM token (attempt ${this.reconnectAttempt}, delay ${delayMs}ms)`);this.logger.error(`Failed to sign entitlement token for ${license.id}: ${(error as Error).message}`);this.logger.warn(`Error deleting secret ${params.secretName}: ${error.message}`);this.logger.warn(`Secret ${secretName} already exists in ${namespace}, continuing...`);CMD wget -T 2 -q --spider "http://127.0.0.1:${PORT:-3001}/api/health" || exit 1CMD wget -T 2 -q --spider "http://127.0.0.1:${PORT:-3001}/api/health" || exit 1if (microseconds < MICROSECONDS_TO_MS) return `${microseconds}μs`;-e STORAGE_URL=postgresql://dev:devpass@localhost:5432/postgres \
'postgres://betterdb:devpassword@localhost:5433/betterdb';
'postgres://betterdb:devpassword@localhost:5433/betterdb';
-e STORAGE_URL=postgresql://dev:devpass@localhost:5432/postgres \
secret: 'slack-secret-key-123',
const SECRET = 'cloud-session-secret';
const SECRET = 'cloud-session-secret';
const SECRET = 'cloud-session-secret';
token: 'signed.offline.token',
Gates applied: critical_finding, no_behavioural_pass.
cffef10ac693full audit observations/trust-audit/mcp-server/betterdb-inc__betterdb-monitor.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-09-24 | cffef10ac693 | BLOCK | F | 36 | first audit |
Questions
What is the BetterDB Monitor MCP server?
Real-time monitoring, slowlog analysis, and audit trails for Valkey and Redis
What tools does BetterDB Monitor expose?
78 in total: 69 read-only, 8 that write, and 1 that can delete or overwrite (remove_connection). Every one is listed on this page with its risk.
Is BetterDB Monitor safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (36/100) and found 7 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 1 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does BetterDB Monitor need?
It reads ADMIN_API_TOKEN, AGENT_AUTH_MODE, AGENT_TOKEN_POSTGRES_TEST_DSN, AUTH_BROKER_KEY_ID, AUTH_BROKER_PUBLIC_KEY, AUTH_PRIVATE_KEY, AUTH_PUBLIC_KEY, AUTH_PUBLIC_URL, AUTH_SECRET, BETTERDB_LICENSE_KEY, BETTERDB_TOKEN and BROKER_API_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does BetterDB Monitor run?
It speaks stdio, so it runs as a local process your client starts. It is published on npm as @app/entitlement at 1.12.0.
How current is this page?
The grade is for one exact copy of the source (cffef10ac693), read on 2026-09-24. The repository is watched and re-audited when it changes.