Skip to main content
Glama
ryanmichaeljames

Dataverse MCP Server

dataverse_get_valid_relationship_entities

Read-onlyIdempotent

List WHICH tables may take part in a relationship — the enumeration, before you pick a target.

Instructions

List WHICH tables may take part in a relationship — the enumeration, before you pick a target.

Answers "which tables are eligible?" when you do not yet know what to point a lookup at. Its counterpart dataverse_check_relationship_eligibility answers "is THIS ONE table OK?" — a boolean about a table you can already name. The role values here mirror that tool's check_type values one for one, so use this to discover a candidate and that one to confirm a specific choice.

Call it before dataverse_create_one_to_many_relationship or dataverse_create_many_to_many_relationship: a table the platform excludes (many system and virtual tables) fails the create late and opaquely.

role selects one of three unbound functions:

  • 'referenced' — tables that can be the PRIMARY (one) side of a 1:N, i.e. valid lookup TARGETS.

  • 'referencing' — tables that can be the RELATED (many) side of a 1:N, i.e. tables that can HOLD a lookup.

  • 'many_to_many' — tables that can participate in an N:N. Takes no table_logical_name; supplying one is an input error rather than being ignored, because ignoring it would answer the environment-wide question while looking scoped.

table_logical_name DOES NOT NARROW THE ANSWER. It is optional for the two 1:N roles and Dataverse does validate it server-side (an unknown table is HTTP 400 [0x80041102] "not found in the MetadataCache"), but supplying it was measured live to return a BYTE-IDENTICAL list to omitting it, for every table tried. Every role therefore answers the environment-wide question: the tables eligible for that role at all. Passing a name buys you exactly one thing — proof the table exists — so pass it only when you want that check, and never read the result as "the tables THIS table may point at". This holds for CUSTOM tables as well as system ones: scoping by a custom table returned the same byte-identical 575-name list that 'account' and 'systemuser' did. The response says so explicitly via table_logical_name_filtered.

To ask about one specific table, use dataverse_check_relationship_eligibility, which returns a real per-table boolean. This tool cannot answer that question.

Supply a lowercase logical name ('account', not 'accounts'). Omitting it removes the parameter from the call entirely rather than sending an empty one — the two are different requests, even though they answer the same.

THE ANSWER IS BIG and 'referenced' is the biggest. Measured live: referenced 575 names / ~13 KB, many_to_many 305 / ~7 KB, referencing 166 / ~4 KB. None of these functions pages server-side, so names are trimmed to top (default 250) while count, total_count and has_more always describe the full set Dataverse returned.

The list is returned under EntityNames (live-confirmed for all three functions), which is tried first, then a by-shape fallback (a sole top-level list of strings); source names where it was actually found. If it cannot be located unambiguously, table_logical_names and the counts are OMITTED, normalized is false, and the untouched body is returned under raw_response — an unreadable payload is never reported as an empty list.

An empty list from a readable payload IS a real answer: it means no table qualifies for that role. A nonexistent table name is an HTTP error, not an empty list.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint, idempotentHint, destructiveHint), the description discloses highly relevant behavioral quirks: no server-side paging, client-side trimming, byte-identical lists when table_logical_name is supplied, fallback parsing logic, and the meaning of empty lists. It also discloses measured live sizes and error behavior (HTTP 400 for unknown names). These are exactly the kind of details that save an agent from misinterpreting results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and sibling distinction, and every paragraph adds essential caveats. However, it is quite long and repeats certain points (e.g., 'byte-identical' appears multiple times, 'measured live' is used repeatedly). Some trimming could be done without losing value, but overall the structure is logical and the detail is mostly earned.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists and annotations cover safety, the description still goes beyond to explain response shape, fallback mechanism, raw_response behavior, and empty-list semantics. It covers the full context an agent needs to correctly invoke this tool and interpret results, including warnings about huge payloads and the exact behavior of the optional table_logical_name parameter. This is complete for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although the input schema already has descriptions for each parameter, the tool description adds critical semantic nuance beyond the schema. For role, it clarifies that every role answers the environment-wide question and gives exact meanings for 'referenced', 'referencing', and 'many_to_many'. For table_logical_name, it emphasizes that the parameter 'DOES NOT NARROW THE ANSWER' and that omission is different from sending an empty string. It also explains top's trimming behavior with concrete numbers.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'List WHICH tables may take part in a relationship — the enumeration, before you pick a target.' It immediately distinguishes itself from the sibling tool dataverse_check_relationship_eligibility by contrasting 'which tables are eligible?' with 'is THIS ONE table OK?'. This is a clear, actions-focused purpose statement that leaves no ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance: 'Call it before dataverse_create_one_to_many_relationship or dataverse_create_many_to_many_relationship' and directs users to the alternative tool for single-table checks: 'To ask about one specific table, use dataverse_check_relationship_eligibility'. It also explains that table_logical_name should only be passed to prove existence, and that the tool is meant for the 'do not yet know what to point a lookup at' scenario.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ryanmichaeljames/dataverse-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server