Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
The Sekha MCP server demonstrates solid foundational quality with 7 well-named tools serving a coherent memory management domain. All tools have descriptions (90-150 chars each), input schemas with proper types, and sensible parameter validation. However, critical gaps in output schema documentation, error handling guidance, and missing tool annotations prevent higher scores. The schema definitions visible in the tool inventory are thorough (UUID validation, enum constraints, min/max bounds), but the source code provided does not include the actual output schema documentation for any tool, which is a significant omission. Security and composition are sound within the domain scope.
Tools (7)
memory_exportread onlyauthsource verified77/100
Export conversation to JSON or Markdown format for backup or external use
Output schemas not documented in source code. No visible return type specifications for any tool (memory_store, memory_search, memory_get_context, etc.). LLMs cannot infer what fields to expect in responses, preventing reliable downstream composition and multi-step planning.
No tool annotations visible. Tools lack readOnlyHint, destructiveHint, or idempotentHint attributes in registration. memory_store and memory_update are destructive operations; memory_search, memory_get_context, memory_export, memory_stats are read-only. LLMs cannot determine operation safety without explicit hints.
Document return types for all 7 tools. For memory_search: return {results: [{conversation_id, label, snippet, similarity_score, timestamp}], total_count, next_cursor}. For memory_get_context: return {conversation_id, label, folder, messages: [{role, content, timestamp, metadata}], metadata: {created_at, updated_at, importance_score}}. This enables LLM to reliably extract IDs for downstream calls.
Add tool annotations to tool registration. Modify server.py @list_tools() to include readOnlyHint and destructiveHint: memory_store, memory_update → {readOnlyHint: false, destructiveHint: true}; memory_search, memory_get_context, memory_export, memory_stats → {readOnlyHint: true, destructiveHint: false}. memory_prune is read-only but informs destructive decisions → {readOnlyHint: true, destructiveHint: false}.
Add explicit error recovery guidance to tool implementations. In memory_store_tool(): if validation fails (bad folder pattern, invalid timestamp), return ToolError with message: 'Invalid folder path. Must match pattern /[a-zA-Z0-9_\-/]*. Example: /projects/ai. Use memory_stats to list existing folders.' For duplicate labels: 'Conversation label already exists in folder. Use memory_search to find existing conversation and memory_update to modify it.' See pattern:recovery-guide.
Enhance parameter descriptions with prerequisites and examples. memory_update description: 'Update an existing conversation. conversation_id is the UUID returned by memory_store or memory_search. To find an ID, call memory_search first with a natural language query. Exactly one of {label, folder, importance_score} required.' memory_prune description: 'Get suggestions for conversations to prune. Returns list of candidate conversation_ids, scores, and metadata. Use memory_export to backup before deletion, or memory_update to lower importance_score instead of deletion.' This prevents wasted calls.
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Error handling and recovery guidance absent from source code. No visible error responses, recovery hints, or actionable error classification. memory_store validation error responses not shown; memory_search failure modes not documented. Pattern: recovery-guide requires agent-readable error messages that guide next steps.
Tool descriptions missing context on prerequisites and downstream dependencies. memory_get_context description does not mention that it requires a valid conversation_id from memory_search or memory_store. memory_prune does not explain what actions the agent should take on returned suggestions. Incomplete docstrings force LLMs to guess.
No confirmation/dry-run mechanism for destructive operations. memory_store and memory_update modify state irreversibly. Pattern: confirmation-request recommends a dry-run step or explicit user confirmation for agent-initiated changes that cannot be easily rolled back.
memory_prune tool lacks actionable output guidance. Description states 'Get AI-powered suggestions' but does not document the response format (is it a list of conversation IDs? scores? metadata?). Without knowing what memory_prune returns, agents cannot reliably decide whether to call memory_store for archival, memory_export for backup, or delete.
memory_prune
Implement idempotency markers. memory_store should accept an optional idempotency_key (UUID) to prevent duplicate conversations if retried. Document: 'If provided, server ensures at most one conversation created per idempotency_key.' memory_update should be naturally idempotent (update is idempotent by definition), document this in description. See pattern:idempotent-operation.
Add per-parameter constraint descriptions. memory_store folder parameter: already has pattern in schema, but add to description: 'Folder path (must start with /, use only alphanumeric/dash/underscore characters, max depth 5 levels). Example: /projects/ai or /archive/2024). memory_search limit parameter: 'Maximum results to return. Default 10. Higher values slower; max 50 recommended for LLM context windows.' This makes constraints unambiguous to LLMs.
Expand memory_prune description to include concrete next steps. Current: 'Get AI-powered suggestions for pruning old or low-importance conversations.' Improved: 'Returns list of candidate conversation IDs with age, importance score, and summary. Agent should decide: export for archive (memory_export), lower importance (memory_update), or delete. Common threshold: conversations >90 days old AND importance_score < 3.0.' This guides agent composition.
Add permission/scope declarations to tool docstrings (pattern:scope-declaration). Example for memory_store: 'Scope: write:memory. Requires authenticated Sekha user. Rate limit: 100 writes/hour.' For memory_search: 'Scope: read:memory. Includes only conversations visible to authenticated user. Results filtered by access control.' This clarifies security model.
Document pagination for memory_search explicitly. Input schema has limit and filter_labels; output should include total_count and next_cursor for multi-page results. Description: 'Supports pagination for large result sets. Use limit (max 50) and previous call\'s next_cursor to fetch subsequent pages. Total_count shows total available results.' Without pagination documentation, agents cannot handle >50 conversations reliably.
Add examples to tool inventory comments in server.py. Above @list_tools(), add: '# Example: memory_search({"query": "python projects", "limit": 10}) → {results: [...], total_count: 42, next_cursor: "abc123"} # Example: memory_store({"label": "Q4 Planning", "folder": "/projects", "messages": [...]}) → {conversation_id: "uuid-...", created_at: "2024-..."} # These examples are for documentation only; actual responses validated against schemas.' This helps maintainers and users understand expected flows.