MCP server for finding relationships between Dynamics 365 tables
This MCP server provides 5 domain-focused tools for exploring Dynamics 365 table relationships. Tool naming is clear and verb-forward. However, significant gaps exist in parameter descriptions, output schema documentation, and error handling. All tools are READ_ONLY and safe, but descriptions are generic and would not guide an LLM toward optimal tool selection. Parameter descriptions are minimal (e.g., 'Name of the table to find relationships for (case-insensitive)' provides no guidance on format, length limits, or what constitutes a valid table name). Output schemas are undocumented, callers cannot infer return structure before execution. Error handling is absent; no guidance on recovery paths. Tool definitions are visible in source code, so no inference penalty applies.
Find all tables directly related to a specific table.
Find paths between two tables through their relationships.
Get detailed information about the direct relationship between two tables.
Get statistics about the loaded relationships.
List all tables in the dataset.
Output schemas completely undocumented. Tools return dicts, lists, and complex nested structures (e.g., find_relationship_path returns [{'table': str, 'field': str, 'relationship_type': str}]) but LLMs have no way to infer structure before calling. This violates pattern:response-shaper and forces LLMs to guess field names on downstream operations.
Parameter descriptions are minimal and generic. 'relationship_file' appears in all 5 tools described only as 'Optional path to the relationship file. If not provided, uses the default.' No guidance on format (absolute vs relative?), file size limits, encoding expectations, or where the default file is located. This violates pattern:tool-description.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 45 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 48 | - | v1 |
'table' and 'table1'/'table2' parameters lack constraints and format guidance. No indication of case sensitivity (though docstrings say 'case-insensitive', this is not in parameter descriptions), length limits, allowed characters, or what happens if a nonexistent table is provided. 'table: Name of the table to find relationships for (case-insensitive)' gives minimal actionable guidance to an LLM.
No error handling or recovery guidance. Code does not show try/catch blocks, validation, or error categorization. If a nonexistent table is passed to find_related_tables, the LLM receives no guidance on what went wrong or how to proceed. Violates pattern:recovery-guide and pattern:error-classification.
find_relationship_path 'levels' parameter lacks numeric constraints. No minimum/maximum documented. What happens if levels=999999? What is the performance cost? This invites LLMs to pass absurd values. Baseline: numeric params should declare min/max (e.g., 'levels: 0 - 10').
Tool descriptions are too generic (45 - 50 chars typical) and lack context on WHEN to use each tool instead of alternatives. 'Find all tables directly related to a specific table' vs 'Find paths between two tables through their relationships', the distinction is buried and not obvious for LLM selection logic. Baseline: A+ tools have 50 - 200 char descriptions with use-case clarity.