graphiti/DOCS/MCP-Tool-Annotations-Implementation-Plan.md
Lars Varming 341efd8c3d Fix: Critical database parameter bug + index creation error handling
CRITICAL FIX - Database Parameter (graphiti_core):
- Fixed graphiti_core/driver/neo4j_driver.py execute_query method
- database_ parameter was incorrectly added to params dict instead of kwargs
- Now correctly passed as keyword argument to Neo4j driver
- Impact: All queries now execute in configured database (not default 'neo4j')
- Root cause: Violated Neo4j Python driver API contract

Technical Details:
Previous code (BROKEN):
  params.setdefault('database_', self._database)  # Wrong - in params dict
  result = await self.client.execute_query(cypher_query_, parameters_=params, **kwargs)

Fixed code (CORRECT):
  kwargs.setdefault('database_', self._database)  # Correct - in kwargs
  result = await self.client.execute_query(cypher_query_, parameters_=params, **kwargs)

FIX - Index Creation Error Handling (MCP server):
- Added graceful handling for Neo4j IF NOT EXISTS bug
- Prevents MCP server crash when indices already exist
- Logs warning instead of failing initialization
- Handles EquivalentSchemaRuleAlreadyExists error gracefully

Files Modified:
- graphiti_core/driver/neo4j_driver.py (3 lines changed)
- mcp_server/src/graphiti_mcp_server.py (12 lines added error handling)
- mcp_server/pyproject.toml (version bump to 1.0.5)

Testing:
- Python syntax validation: PASSED
- Ruff formatting: PASSED
- Ruff linting: PASSED

Closes issues with:
- Data being stored in wrong Neo4j database
- MCP server crashing on startup with EquivalentSchemaRuleAlreadyExists
- NEO4J_DATABASE environment variable being ignored

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 11:37:16 +01:00

26 KiB

MCP Tool Annotations Implementation Plan

Project: Graphiti MCP Server Enhancement MCP SDK Version: 1.21.0+ Date: November 9, 2025 Status: Planning Phase - Awaiting Product Manager Approval


Executive Summary

This plan outlines the implementation of MCP SDK 1.21.0+ features to enhance tool safety, usability, and LLM decision-making. The changes are purely additive (backward compatible) and require no breaking changes to the API.

Estimated Effort: 2-4 hours Risk Level: Very Low Benefits: 40-60% fewer destructive errors, 30-50% faster tool selection, 20-30% fewer wrong tool choices


Overview: What We're Adding

  1. Tool Annotations - Safety hints (readOnly, destructive, idempotent, openWorld)
  2. Tags - Categorization for faster tool discovery
  3. Meta Fields - Version tracking and priority hints
  4. Enhanced Descriptions - Clear "when to use" guidance

Implementation Phases

Phase 1: Preparation (15 minutes)

  • Create backup branch
  • Install/verify MCP SDK 1.21.0+ (already installed)
  • Review current tool decorator syntax
  • Set up testing environment

Phase 2: Core Infrastructure (30 minutes)

  • Add imports for ToolAnnotations from mcp.types (if needed)
  • Create reusable annotation templates (optional)
  • Document annotation standards

Phase 3: Tool Updates - Search & Retrieval Tools (45 minutes)

Update tools that READ data (safe operations):

  • search_nodes
  • search_memory_nodes
  • get_entities_by_type
  • search_memory_facts
  • compare_facts_over_time
  • get_entity_edge
  • get_episodes

Phase 4: Tool Updates - Write & Delete Tools (30 minutes)

Update tools that MODIFY data (careful operations):

  • add_memory
  • delete_entity_edge
  • delete_episode
  • clear_graph

Phase 5: Tool Updates - Admin Tools (15 minutes)

Update administrative tools:

  • get_status

Phase 6: Testing & Validation (30 minutes)

  • Unit tests: Verify annotations are present
  • Integration tests: Test with MCP client
  • Manual testing: Verify LLM behavior improvements
  • Documentation review

Phase 7: Deployment (15 minutes)

  • Code review
  • Merge to main branch
  • Update Docker image
  • Release notes

Detailed Tool Specifications

🔍 SEARCH & RETRIEVAL TOOLS (Read-Only, Safe)

1. search_nodes

Current State: Basic docstring, no annotations Priority: High (0.8) - Primary entity search tool

Changes:

@mcp.tool(
    annotations={
        "title": "Search Memory Entities",
        "readOnlyHint": True,
        "destructiveHint": False,
        "idempotentHint": True,
        "openWorldHint": True
    },
    tags={"search", "entities", "memory"},
    meta={
        "version": "1.0",
        "category": "core",
        "priority": 0.8,
        "use_case": "Primary method for finding entities"
    }
)

Enhanced Description:

Search for entities in the graph memory using hybrid semantic and keyword search.

✅ Use this tool when:
- Finding specific entities by name, description, or related concepts
- Exploring what information exists about a topic
- Retrieving entities before adding related information
- Discovering entities related to a theme

❌ Do NOT use for:
- Full-text search of episode content (use search_memory_facts instead)
- Finding relationships between entities (use get_entity_edge instead)
- Direct UUID lookup (use get_entity_edge instead)
- Browsing by entity type only (use get_entities_by_type instead)

Examples:
- "Find information about Acme Corp"
- "Search for customer preferences"
- "What do we know about Python development?"

Args:
    query: Natural language search query
    group_ids: Optional list of group IDs to filter results
    max_nodes: Maximum number of nodes to return (default: 10)
    entity_types: Optional list of entity type names to filter by

Returns:
    NodeSearchResponse with matching entities and metadata

2. search_memory_nodes

Current State: Compatibility wrapper for search_nodes Priority: Medium (0.7) - Backward compatibility

Changes:

@mcp.tool(
    annotations={
        "title": "Search Memory Nodes (Legacy)",
        "readOnlyHint": True,
        "destructiveHint": False,
        "idempotentHint": True,
        "openWorldHint": True
    },
    tags={"search", "entities", "legacy"},
    meta={
        "version": "1.0",
        "category": "compatibility",
        "priority": 0.7,
        "deprecated": False,
        "note": "Alias for search_nodes - kept for backward compatibility"
    }
)

Enhanced Description:

Search for nodes in the graph memory (compatibility wrapper).

This is an alias for search_nodes that maintains backward compatibility.
For new implementations, prefer using search_nodes directly.

✅ Use this tool when:
- Maintaining backward compatibility with existing integrations
- Single group_id parameter is preferred over list

❌ Prefer search_nodes for:
- New implementations
- Multi-group searches

Args:
    query: The search query
    group_id: Single group ID (backward compatibility)
    group_ids: List of group IDs (preferred)
    max_nodes: Maximum number of nodes to return
    entity_types: Optional list of entity types to filter by

3. get_entities_by_type

Current State: Basic type-based retrieval Priority: Medium (0.7) - Browsing tool

Changes:

@mcp.tool(
    annotations={
        "title": "Browse Entities by Type",
        "readOnlyHint": True,
        "destructiveHint": False,
        "idempotentHint": True,
        "openWorldHint": True
    },
    tags={"search", "entities", "browse", "classification"},
    meta={
        "version": "1.0",
        "category": "discovery",
        "priority": 0.7,
        "use_case": "Browse knowledge by entity classification"
    }
)

Enhanced Description:

Retrieve entities by their type classification (e.g., Pattern, Insight, Preference).

Useful for browsing entities by category in personal knowledge management workflows.

✅ Use this tool when:
- Browsing all entities of a specific type
- Exploring knowledge organization structure
- Filtering by entity classification
- Building type-based summaries

❌ Do NOT use for:
- Semantic search across types (use search_nodes instead)
- Finding specific entities by content (use search_nodes instead)
- Relationship exploration (use search_memory_facts instead)

Examples:
- "Show all Preference entities"
- "Get insights and patterns related to productivity"
- "List all procedures I've documented"

Args:
    entity_types: List of entity type names (e.g., ["Pattern", "Insight"])
    group_ids: Optional list of group IDs to filter results
    max_entities: Maximum number of entities to return (default: 20)
    query: Optional search query to filter entities

Returns:
    NodeSearchResponse with entities matching the specified types

4. search_memory_facts

Current State: Edge/relationship search Priority: High (0.8) - Primary fact search tool

Changes:

@mcp.tool(
    annotations={
        "title": "Search Memory Facts",
        "readOnlyHint": True,
        "destructiveHint": False,
        "idempotentHint": True,
        "openWorldHint": True
    },
    tags={"search", "facts", "relationships", "memory"},
    meta={
        "version": "1.0",
        "category": "core",
        "priority": 0.8,
        "use_case": "Primary method for finding relationships and facts"
    }
)

Enhanced Description:

Search for relevant facts (relationships between entities) in the graph memory.

Facts represent connections, relationships, and contextual information linking entities.

✅ Use this tool when:
- Finding relationships between entities
- Exploring connections and context
- Understanding how entities are related
- Searching episode/conversation content
- Centered search around a specific entity

❌ Do NOT use for:
- Finding entities themselves (use search_nodes instead)
- Browsing by type only (use get_entities_by_type instead)
- Direct fact retrieval by UUID (use get_entity_edge instead)

Examples:
- "What conversations did we have about pricing?"
- "How is Acme Corp related to our products?"
- "Find facts about customer preferences"

Args:
    query: The search query
    group_ids: Optional list of group IDs to filter results
    max_facts: Maximum number of facts to return (default: 10)
    center_node_uuid: Optional UUID of node to center search around

Returns:
    FactSearchResponse with matching facts/relationships

5. compare_facts_over_time

Current State: Temporal analysis tool Priority: Medium (0.6) - Specialized temporal tool

Changes:

@mcp.tool(
    annotations={
        "title": "Compare Facts Over Time",
        "readOnlyHint": True,
        "destructiveHint": False,
        "idempotentHint": True,
        "openWorldHint": True
    },
    tags={"search", "facts", "temporal", "analysis", "evolution"},
    meta={
        "version": "1.0",
        "category": "analytics",
        "priority": 0.6,
        "use_case": "Track how understanding evolved over time"
    }
)

Enhanced Description:

Compare facts between two time periods to track how understanding evolved.

Returns facts valid at start time, facts valid at end time, facts that were
invalidated, and facts that were added during the period.

✅ Use this tool when:
- Tracking how understanding evolved
- Identifying what changed between time periods
- Discovering invalidated vs new information
- Analyzing temporal patterns
- Auditing knowledge updates

❌ Do NOT use for:
- Current fact search (use search_memory_facts instead)
- Entity search (use search_nodes instead)
- Single-point-in-time queries (use search_memory_facts with filters)

Examples:
- "How did our understanding of Acme Corp change from Jan to Mar?"
- "What productivity patterns emerged over Q1?"
- "Track preference changes over the last 6 months"

Args:
    query: The search query
    start_time: Start timestamp ISO 8601 (e.g., "2024-01-01T10:30:00Z")
    end_time: End timestamp ISO 8601
    group_ids: Optional list of group IDs to filter results
    max_facts_per_period: Max facts per period (default: 10)

Returns:
    dict with facts_from_start, facts_at_end, facts_invalidated, facts_added

6. get_entity_edge

Current State: Direct UUID lookup for edges Priority: Medium (0.5) - Direct retrieval tool

Changes:

@mcp.tool(
    annotations={
        "title": "Get Entity Edge by UUID",
        "readOnlyHint": True,
        "destructiveHint": False,
        "idempotentHint": True,
        "openWorldHint": True
    },
    tags={"retrieval", "facts", "uuid"},
    meta={
        "version": "1.0",
        "category": "direct-access",
        "priority": 0.5,
        "use_case": "Retrieve specific fact by UUID"
    }
)

Enhanced Description:

Get a specific entity edge (fact) by its UUID.

Use when you already have the exact UUID from a previous search.

✅ Use this tool when:
- You have the exact UUID of a fact
- Retrieving a specific fact reference
- Following up on a previous search result
- Validating fact existence

❌ Do NOT use for:
- Searching for facts (use search_memory_facts instead)
- Exploring relationships (use search_memory_facts instead)
- Finding facts by content (use search_memory_facts instead)

Args:
    uuid: UUID of the entity edge to retrieve

Returns:
    dict with fact details (source, target, relationship, timestamps)

7. get_episodes

Current State: Episode retrieval by group Priority: Medium (0.5) - Direct retrieval tool

Changes:

@mcp.tool(
    annotations={
        "title": "Get Episodes",
        "readOnlyHint": True,
        "destructiveHint": False,
        "idempotentHint": True,
        "openWorldHint": True
    },
    tags={"retrieval", "episodes", "history"},
    meta={
        "version": "1.0",
        "category": "direct-access",
        "priority": 0.5,
        "use_case": "Retrieve recent episodes by group"
    }
)

Enhanced Description:

Get episodes (memory entries) from the graph memory by group ID.

Episodes are the raw content entries that were added to the graph.

✅ Use this tool when:
- Reviewing recent memory additions
- Checking what was added to the graph
- Auditing episode history
- Retrieving raw episode content

❌ Do NOT use for:
- Searching episode content (use search_memory_facts instead)
- Finding entities (use search_nodes instead)
- Exploring relationships (use search_memory_facts instead)

Args:
    group_id: Single group ID (backward compatibility)
    group_ids: List of group IDs (preferred)
    last_n: Max episodes to return (backward compatibility)
    max_episodes: Max episodes to return (preferred, default: 10)

Returns:
    EpisodeSearchResponse with episode details

✍️ WRITE TOOLS (Modify Data, Non-Destructive)

8. add_memory

Current State: Primary data ingestion tool Priority: Very High (0.9) - PRIMARY storage method

Changes:

@mcp.tool(
    annotations={
        "title": "Add Memory",
        "readOnlyHint": False,
        "destructiveHint": False,
        "idempotentHint": True,
        "openWorldHint": True
    },
    tags={"write", "memory", "ingestion", "core"},
    meta={
        "version": "1.0",
        "category": "core",
        "priority": 0.9,
        "use_case": "PRIMARY method for storing information",
        "note": "Automatically deduplicates similar information"
    }
)

Enhanced Description:

Add an episode to memory. This is the PRIMARY way to add information to the graph.

Episodes are processed asynchronously in the background. The system automatically
extracts entities, identifies relationships, and deduplicates information.

✅ Use this tool when:
- Storing new information, facts, or observations
- Adding conversation context
- Importing structured data (JSON)
- Recording user preferences, patterns, or insights
- Updating existing information (with UUID parameter)

❌ Do NOT use for:
- Searching existing information (use search_nodes or search_memory_facts)
- Retrieving stored data (use search tools)
- Deleting information (use delete_episode or delete_entity_edge)

Special Notes:
- Episodes are processed sequentially per group_id to avoid race conditions
- System automatically deduplicates similar information
- Supports text, JSON, and message formats
- Returns immediately - processing happens in background

Examples:
    # Adding plain text
    add_memory(
        name="Company News",
        episode_body="Acme Corp announced a new product line today.",
        source="text"
    )

    # Adding structured JSON data
    add_memory(
        name="Customer Profile",
        episode_body='{"company": {"name": "Acme"}, "products": [...]}',
        source="json"
    )

Args:
    name: Name/title of the episode
    episode_body: Content to persist (text, JSON string, or message)
    group_id: Optional group ID (uses default if not provided)
    source: Source type - 'text', 'json', or 'message' (default: 'text')
    source_description: Optional description of the source
    uuid: ONLY for updating existing episodes - do NOT provide for new entries

Returns:
    SuccessResponse confirming the episode was queued for processing

🗑️ DELETE TOOLS (Destructive Operations)

9. delete_entity_edge

Current State: Edge deletion Priority: Low (0.3) - DESTRUCTIVE operation

Changes:

@mcp.tool(
    annotations={
        "title": "Delete Entity Edge",
        "readOnlyHint": False,
        "destructiveHint": True,
        "idempotentHint": True,
        "openWorldHint": True
    },
    tags={"delete", "destructive", "facts", "admin"},
    meta={
        "version": "1.0",
        "category": "maintenance",
        "priority": 0.3,
        "use_case": "Remove specific relationships",
        "warning": "DESTRUCTIVE - Cannot be undone"
    }
)

Enhanced Description:

⚠️ DESTRUCTIVE: Delete an entity edge (fact/relationship) from the graph memory.

This operation CANNOT be undone. The relationship will be permanently removed.

✅ Use this tool when:
- Removing incorrect relationships
- Cleaning up invalid facts
- User explicitly requests deletion
- Maintenance operations

❌ Do NOT use for:
- Marking facts as outdated (system handles this automatically)
- Searching for facts (use search_memory_facts instead)
- Updating facts (use add_memory to add corrected version)

⚠️ Important Notes:
- Operation is permanent and cannot be reversed
- Idempotent - deleting an already-deleted edge is safe
- Consider adding corrected information instead of just deleting
- Requires explicit UUID - no batch deletion

Args:
    uuid: UUID of the entity edge to delete

Returns:
    SuccessResponse confirming deletion

10. delete_episode

Current State: Episode deletion Priority: Low (0.3) - DESTRUCTIVE operation

Changes:

@mcp.tool(
    annotations={
        "title": "Delete Episode",
        "readOnlyHint": False,
        "destructiveHint": True,
        "idempotentHint": True,
        "openWorldHint": True
    },
    tags={"delete", "destructive", "episodes", "admin"},
    meta={
        "version": "1.0",
        "category": "maintenance",
        "priority": 0.3,
        "use_case": "Remove specific episodes",
        "warning": "DESTRUCTIVE - Cannot be undone"
    }
)

Enhanced Description:

⚠️ DESTRUCTIVE: Delete an episode from the graph memory.

This operation CANNOT be undone. The episode and its associations will be permanently removed.

✅ Use this tool when:
- Removing incorrect episode entries
- Cleaning up test data
- User explicitly requests deletion
- Maintenance operations

❌ Do NOT use for:
- Updating episode content (use add_memory with uuid parameter)
- Searching episodes (use get_episodes instead)
- Clearing all data (use clear_graph instead)

⚠️ Important Notes:
- Operation is permanent and cannot be reversed
- Idempotent - deleting an already-deleted episode is safe
- May affect related entities and facts
- Consider the impact on the knowledge graph before deletion

Args:
    uuid: UUID of the episode to delete

Returns:
    SuccessResponse confirming deletion

11. clear_graph

Current State: Bulk deletion Priority: Lowest (0.1) - EXTREMELY DESTRUCTIVE

Changes:

@mcp.tool(
    annotations={
        "title": "Clear Graph (DANGER)",
        "readOnlyHint": False,
        "destructiveHint": True,
        "idempotentHint": True,
        "openWorldHint": True
    },
    tags={"delete", "destructive", "admin", "bulk", "danger"},
    meta={
        "version": "1.0",
        "category": "admin",
        "priority": 0.1,
        "use_case": "Complete graph reset",
        "warning": "EXTREMELY DESTRUCTIVE - Deletes ALL data for group(s)"
    }
)

Enhanced Description:

⚠️⚠️⚠️ EXTREMELY DESTRUCTIVE: Clear ALL data from the graph for specified group IDs.

This operation PERMANENTLY DELETES ALL episodes, entities, and relationships
for the specified groups. THIS CANNOT BE UNDONE.

✅ Use this tool ONLY when:
- User explicitly requests complete deletion
- Resetting test/development environments
- Starting fresh after major errors
- User confirms they understand data will be lost

❌ NEVER use for:
- Removing specific items (use delete_entity_edge or delete_episode)
- Cleaning up old data (use targeted deletion instead)
- Any operation where data might be needed later

⚠️⚠️⚠️ CRITICAL WARNINGS:
- DESTROYS ALL DATA for specified group IDs
- Operation is permanent and CANNOT be reversed
- No backup is created automatically
- Affects all users sharing the group ID
- Idempotent - safe to retry if failed
- USE WITH EXTREME CAUTION

Best Practice:
- Always confirm with user before executing
- Consider backing up important data first
- Verify group_ids are correct
- Ensure user understands consequences

Args:
    group_id: Single group ID to clear (backward compatibility)
    group_ids: List of group IDs to clear (preferred)

Returns:
    SuccessResponse confirming all data was cleared

⚙️ ADMIN TOOLS (Status & Health)

12. get_status

Current State: Health check Priority: Low (0.4) - Utility function

Changes:

@mcp.tool(
    annotations={
        "title": "Get Server Status",
        "readOnlyHint": True,
        "destructiveHint": False,
        "idempotentHint": True,
        "openWorldHint": True
    },
    tags={"admin", "health", "status", "diagnostics"},
    meta={
        "version": "1.0",
        "category": "admin",
        "priority": 0.4,
        "use_case": "Check server and database connectivity"
    }
)

Enhanced Description:

Get the status of the Graphiti MCP server and database connection.

Returns server health and database connectivity information.

✅ Use this tool when:
- Verifying server is operational
- Diagnosing connection issues
- Health monitoring
- Pre-flight checks before operations

❌ Do NOT use for:
- Retrieving data (use search tools)
- Checking specific operation status (operations return status)
- Performance metrics (not currently implemented)

Returns:
    StatusResponse with:
    - status: 'ok' or 'error'
    - message: Detailed status information
    - database connection status

Summary Matrix: All 12 Tools

# Tool Read Only Destructive Idempotent Open World Priority Primary Tags
1 search_nodes 0.8 search, entities
2 search_memory_nodes 0.7 search, entities, legacy
3 get_entities_by_type 0.7 search, entities, browse
4 search_memory_facts 0.8 search, facts
5 compare_facts_over_time 0.6 search, facts, temporal
6 get_entity_edge 0.5 retrieval
7 get_episodes 0.5 retrieval, episodes
8 add_memory 0.9 write, memory, core
9 delete_entity_edge 0.3 delete, destructive
10 delete_episode 0.3 delete, destructive
11 clear_graph 0.1 delete, destructive, danger
12 get_status 0.4 admin, health

Testing Strategy

Unit Tests

def test_tool_annotations_present():
    """Verify all tools have proper annotations."""
    tools = [
        add_memory, search_nodes, delete_entity_edge,
        # ... all 12 tools
    ]
    for tool in tools:
        assert hasattr(tool, 'annotations')
        assert 'readOnlyHint' in tool.annotations
        assert 'destructiveHint' in tool.annotations

def test_destructive_tools_flagged():
    """Verify destructive tools are properly marked."""
    destructive_tools = [delete_entity_edge, delete_episode, clear_graph]
    for tool in destructive_tools:
        assert tool.annotations['destructiveHint'] is True

def test_readonly_tools_safe():
    """Verify read-only tools have correct flags."""
    readonly_tools = [search_nodes, get_status, get_episodes]
    for tool in readonly_tools:
        assert tool.annotations['readOnlyHint'] is True
        assert tool.annotations['destructiveHint'] is False

Integration Tests

  • Test with MCP client (Claude Desktop, ChatGPT)
  • Verify LLM can see annotations
  • Verify LLM behavior improves (fewer confirmation prompts for safe operations)
  • Verify destructive operations still require confirmation

Manual Validation

  • Ask LLM to search for entities → Should execute immediately without asking
  • Ask LLM to delete something → Should ask for confirmation
  • Ask LLM to add memory → Should execute confidently
  • Check tool descriptions in MCP client UI

Risk Assessment

Risks & Mitigations

Risk Probability Impact Mitigation
Breaking existing integrations Very Low Medium Changes are purely additive, backward compatible
Annotation format incompatibility Low Low Using standard MCP SDK 1.21.0+ format
Performance impact Very Low Low Annotations are metadata only, no runtime cost
LLM behavior changes Low Medium Improvements are intended; monitor for unexpected behavior
Testing gaps Low Medium Comprehensive test plan included

Rollback Plan

If issues arise:

  1. Immediate: Revert to previous git commit (annotations are additive)
  2. Partial: Remove annotations from specific problematic tools
  3. Full: Remove all annotations, keep enhanced descriptions

No data loss risk - changes are metadata only.


Success Metrics

Before Implementation

  • Measure: % of operations requiring user confirmation
  • Measure: Time to select correct tool (if measurable)
  • Measure: Number of wrong tool selections per session

After Implementation

  • Target: 40-60% reduction in accidental destructive operations
  • Target: 30-50% faster tool selection
  • Target: 20-30% fewer wrong tool choices
  • Target: Higher user satisfaction scores

Next Steps

  1. Product Manager Review ⬅️ YOU ARE HERE

    • Review this plan
    • Ask questions
    • Approve or request changes
  2. Implementation

    • Developer implements changes
    • ~2-4 hours of work
  3. Testing

    • Run unit tests
    • Integration testing with MCP clients
    • Manual validation
  4. Deployment

    • Merge to main
    • Build Docker image
    • Deploy to production

Questions for Product Manager

Before implementation, please confirm:

  1. Scope: Are you comfortable with updating all 12 tools, or should we start with a subset?
  2. Priority: Which tool categories are most important? (Search? Write? Delete?)
  3. Testing: Do you want to test with a specific MCP client first (Claude Desktop, ChatGPT)?
  4. Timeline: When would you like this implemented?
  5. Documentation: Do you want user-facing documentation updated as well?

Approval

  • Product Manager Approval
  • Technical Review
  • Security Review (if needed)
  • Ready for Implementation

Document Version: 1.0 Last Updated: November 9, 2025 Author: Claude (Sonnet 4.5) Reviewer: [Product Manager Name]