Skip to content

Use FastMCP tags + visibility control for profile-based tool loading #324

@dtehan-td

Description

@dtehan-td

Summary

Replace the current regex-based profile module loading with FastMCP v3 tags + mcp.disable(tags=...) so all tools are registered at startup and profile filtering happens via tag-based enable/disable with automatic list_tools updates.

Background

Currently, profiles determine which tools are registered via regex pattern matching on tool name prefixes in module_loader.py. Disabling a tool post-startup is not supported. FastMCP v3 allows attaching tags at registration time and calling mcp.disable(tags=...) to hide tools from clients dynamically — disabled tools are excluded from list_tools and trigger notifications/tools/list_changed automatically.

Proposed Approach

TAG_MAP = {"base_": "base", "dba_": "dba", "rag_": "rag", ...}

def tag_for(tool_name: str) -> set[str]:
    for prefix, tag in TAG_MAP.items():
        if tool_name.startswith(prefix):
            return {tag}
    return set()

# Register all tools with tags
mcp.tool(name=name, tags=tag_for(name))(wrapped)

# Apply profile: disable tools not in the allowed set
allowed_tags = profile_allowed_tags(profile_name)
mcp.disable(tags=all_tags - allowed_tags)

Files to Change

  • app.py:80-116 (feature flags)
  • app.py:530-583 (registration loop)
  • module_loader.py (can be simplified)
  • tools/__init__.py

Value

  • Dynamic enable/disable at runtime without re-registration.
  • list_tools automatically excludes disabled tools — progressive disclosure is simplified.
  • notifications/tools/list_changed sent automatically when tools are enabled/disabled.
  • Simplifies module_loader.py — regex matching replaced by tag lookup.

Dependencies

Should be done together with Lifespan management (#9). The profile filter needs the lifespan-supplied connection to discover analytic functions.

Metadata

Metadata

Assignees

No one assigned
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions