Skip to content

feat(mcp): tool visibility presets and per-tool include/exclude configuration #786

@joshrotenberg

Description

@joshrotenberg

Problem

redisctl-mcp currently registers 304 tools. Most MCP clients degrade past ~50-100 tools (increased token usage parsing descriptions, model confusion selecting tools, higher latency). The --tools CLI flag provides toolset-level filtering (cloud/enterprise/database) but that's too coarse -- enabling enterprise loads all 92 tools when a user likely needs 5-10.

Adding more tools (#769 alone adds ~30 CRDB tools) will make this worse. We need a visibility mechanism that controls which tools are registered with the MCP router, not just which are allowed by policy.

Design

Config in mcp-policy.toml

[tools]
# Start from a curated preset, or "none" for fully manual selection
preset = "essentials"

# Add individual tools on top of the preset
include = ["enterprise_raw_api", "get_enterprise_crdb"]

# Remove specific tools from the preset
exclude = ["flush_database"]

Resolution order

  1. Determine enabled toolsets from --tools CLI flag (default: all compiled toolsets). Four toolsets: cloud, enterprise, database, app (profile management)
  2. Start with preset tool set, filtered to enabled toolsets only (or empty set for preset = "none")
  3. Add include tools (only if their toolset is enabled)
  4. Remove exclude tools
  5. Apply existing policy tier/deny/allow on top (safety gating is unchanged)

show_policy and list_available_tools are always registered regardless of visibility config (system tools).

Toolsets

Four toolsets, all opt-in via --tools:

Toolset Flag value Tools Description
Cloud cloud 148 Redis Cloud API management
Enterprise enterprise 92 Redis Enterprise cluster management
Database database 55 Direct Redis command execution
App app 8 Profile/config management (list, show, create, delete, set defaults)

Currently --tools defaults to all compiled toolsets. Profile (app) tools are currently always registered -- this change makes them part of the normal toolset system so users can exclude them.

Presets (defined in code, per-platform)

Presets are composed from per-platform subsets. Only the subsets for enabled toolsets are included.

  • all -- every tool in enabled toolsets (current behavior, backward compatible default when no [tools] section)
  • none -- empty set, fully manual via include
  • essentials -- curated common operations, composed from per-platform subsets:
    • Cloud subset (~15): list/get subscriptions, list/get databases, get account, get regions, list tasks, get backup status, get slow log, cloud_raw_api
    • Enterprise subset (~15): get cluster, list/get databases, list nodes, get node, get license, list alerts, list logs, get cluster stats, get database stats, enterprise_raw_api
    • Database subset (~15): ping, info, keys, get, set, del, scan, health_check, dbsize, memory_stats, slowlog, client_list, redis_command
    • App subset (~5): profile_list, profile_show, profile_validate, profile_path

If --tools cloud,database is set, the essentials preset only includes the Cloud and Database subsets (~30 tools instead of ~50).

Platform-specific presets could follow later: cloud-admin, enterprise-monitoring, database-debug, etc.

Agent introspection

The agent should be aware of tools that exist but aren't loaded. This enables it to suggest: "You could add get_enterprise_crdb_replication_lag to your tools config to monitor CRDB replication directly."

Implementation:

  • A list_available_tools read-only tool (always registered) that returns all tool names/descriptions grouped by toolset, annotated with which are currently active vs available
  • Include a summary in the router instructions: "N tools loaded from preset 'essentials'. Use list_available_tools to see all M available tools and get suggestions."
  • The tool could suggest relevant tools based on context: "For CRDB management, consider adding these tools: ..."

CLI interaction

  • --tools cloud,enterprise,database,app for toolset filtering (applied before preset/include/exclude). Default: all compiled toolsets
  • No [tools] section in policy file = preset = "all" (backward compatible)
  • [tools] section with just preset and no include/exclude is the simplest config

Example configs

Cloud-only monitoring:

tier = "read-only"

[tools]
preset = "essentials"
# With --tools cloud, only the cloud subset of essentials is loaded

CRDB-focused operations (enterprise only, no profile management):

tier = "read-write"

[tools]
preset = "essentials"
include = [
    "list_enterprise_crdbs",
    "get_enterprise_crdb",
    "get_enterprise_crdb_tasks",
    "create_enterprise_crdb",
    "update_enterprise_crdb",
]
# Run with: redisctl-mcp --tools enterprise

Fully manual, minimal surface:

tier = "full"

[tools]
preset = "none"
include = [
    "list_subscriptions",
    "get_database",
    "redis_ping",
    "redis_info",
    "cloud_raw_api",
]

Everything (current behavior, explicit):

tier = "read-only"

[tools]
preset = "all"

Acceptance criteria

  • ToolsConfig struct with preset, include, exclude fields in policy config
  • Four toolsets: cloud, enterprise, database, app (profile management moves from always-on to toolset-gated)
  • Presets defined as per-platform constant sets, composed based on enabled toolsets
  • all, none, essentials presets implemented
  • Tool visibility filtering applied during router construction (tools not in visible set are never registered)
  • --tools CLI flag updated to include app as a toolset value, defaults to all
  • show_policy and list_available_tools always registered (system tools, not part of any toolset)
  • list_available_tools introspection tool (always registered, read-only) returns active vs available tools with descriptions
  • Router instructions updated to reflect loaded vs available tool counts
  • Backward compatible: no [tools] section = all tools loaded
  • Tests for preset resolution, include/exclude, platform filtering, interaction with policy tier
  • Documentation in show_policy output

Context

Blocks #769 and future tool additions. Related to #766 (policy config) and #768 (raw passthrough -- the escape hatch that makes small presets viable).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmcpRelated to the MCP server

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions