Skip to content

Add schema discovery command and read-only MCP tool (#160) - #184

Merged
Mike Krüger (mkrueger) merged 9 commits into
mainfrom
dev/mkrueger/schema-discovery
Aug 31, 2026
Merged

Add schema discovery command and read-only MCP tool (#160)#184
Mike Krüger (mkrueger) merged 9 commits into
mainfrom
dev/mkrueger/schema-discovery

Conversation

@mkrueger

@mkrueger Mike Krüger (mkrueger) commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements the M4 schema / describe discovery tool from the Agentic & Automation Roadmap.

Adds a read-only schema command and matching MCP tool that return a cheap, bounded discovery summary of a Cosmos DB container. This lets agents and users understand container structure without repeatedly sampling data or guessing field names.

For the current container, or one selected with --database / --container, the default result includes:

  • Partition key path(s)
  • Indexing policy summary: mode, automatic flag, included/excluded path counts, and composite/spatial/vector index counts
  • Estimated document count read from the x-ms-resource-usage quota header without scanning the container
  • Inferred field schema from a bounded document sample: dot-notation paths for nested objects, distinct observed JSON types (string, number, boolean, object, array, null), and the number of sampled documents containing each field

--sample <n> controls the sample size and is clamped to 1-100 (default 20). Sampling is bounded server-side with SELECT TOP n and client-side with MaxItemCount.

--fields-only (alias --short) skips the container metadata read and returns only sampledDocuments and fields, producing a smaller, lower-latency CLI or MCP result.

Default output

{
  "database": "MyDB",
  "container": "Products",
  "partitionKeyPaths": ["/category"],
  "documentCountEstimate": 1280,
  "sampleSize": 20,
  "sampledDocuments": 20,
  "indexingPolicy": {
    "indexingMode": "Consistent",
    "automatic": true,
    "includedPaths": 1,
    "excludedPaths": 1,
    "compositeIndexes": 0,
    "spatialIndexes": 0,
    "vectorIndexes": 0
  },
  "fields": [
    { "path": "id", "types": ["string"], "presence": 20 },
    { "path": "category", "types": ["string"], "presence": 20 },
    { "path": "price", "types": ["number"], "presence": 18 }
  ]
}

Fields-only output

{
  "sampledDocuments": 20,
  "fields": [
    { "path": "id", "types": ["string"], "presence": 20 },
    { "path": "category", "types": ["string"], "presence": 20 },
    { "path": "price", "types": ["number"], "presence": 18 }
  ]
}

Implementation notes

  • Uses a no-I/O container resolver so schema discovery does not perform redundant existence checks.
  • Default mode performs one container metadata read plus one bounded item query.
  • Fields-only mode performs only the bounded item query.
  • Field presence is counted once per document, including documents with duplicate JSON property names.
  • A Cosmos 404 is translated to the standard localized container-not-found error without adding pre-validation requests.
  • SQL numeric literals use invariant formatting.

Acceptance criteria

  • Command and MCP tool[CosmosCommand("schema")] with read-only, idempotent, open-world MCP annotations
  • Bounded and read-onlySELECT TOP n, client page-size bound, and sample size clamped to 1-100; document count comes from the quota header
  • Structured output — JSON results for both shell and MCP, including a reduced fields-only contract
  • Docs and tests — README, command documentation, changelog, localization, schema behavior tests, and MCP tool-contract tests

Validation

  • Full Release test suite: 2,248 passed, 98 skipped, 0 failed
  • Focused schema/help/localization suite after final review fixes: 31 passed, 0 failed
  • CodeQL, offline integration tests, emulator integration tests, build/package, and CLA checks pass

Fixes #160

Add a read-only 'schema' command that infers a container's structure from a bounded sample: partition key path(s), indexing policy summary, estimated document count, and inferred field types (dot notation for nested objects, per-field presence and observed JSON types). --sample selects the sample size (clamped to 1-100, default 20); --database/--container override the target. Exposed as a read-only MCP tool.

Includes localization keys, docs (README, docs/commands.md), CHANGELOG entry, and unit tests for the sample-clamping and type-inference helpers.
Comment thread CosmosDBShell.Tests/CommandTests/SchemaCommandTests.cs Fixed
@github-code-quality

github-code-quality Bot commented Jul 20, 2026

Copy link
Copy Markdown

Code Coverage Overview

Languages: C#

C# / code-coverage/dotnet

The overall line coverage in commit 9e76b61 in the dev/mkrueger/schema-... branch remains at 61%, unchanged from commit 2fe15b7 in the main branch.

Show a line coverage summary of the most impacted files.
File main 2fe15b7 dev/mkrueger/schema-... 9e76b61 +/-
D:\a\CosmosDBSh...osmosCommand.cs 38% 37% -1%
D:\a\CosmosDBSh...chemaCommand.cs 0% 63% +63%

Updated August 31, 2026 09:20 UTC

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new schema discovery command (and matching read-only MCP tool) to provide a bounded, structured JSON summary of a Cosmos DB container—partition key paths, indexing policy summary, estimated document count, and inferred field types from a small sample—supporting agentic workflows that need fast, low-risk container introspection.

Changes:

  • Introduces SchemaCommand with bounded sampling (--sample clamped to 1–100) and JSON schema inference (dot-notation paths + type sets + per-field presence).
  • Adds unit tests covering sample clamping and schema/type inference helpers.
  • Updates user-facing docs/help text (README, docs/commands.md, localization strings, CHANGELOG).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
README.md Adds schema to the feature list and describes its discovery output at a high level.
docs/commands.md Documents schema usage, options, examples, and sample output JSON.
CosmosDBShell/lang/en.ftl Adds localized descriptions for the schema command and its options.
CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/SchemaCommand.cs Implements the new schema command and MCP annotation; includes sample clamping + field inference logic.
CosmosDBShell.Tests/CommandTests/SchemaCommandTests.cs Adds unit tests for command registration and helper behaviors (clamping + inference).
CHANGELOG.md Records the new schema command/tool as a new feature.

Comment thread docs/commands.md Outdated
Comment thread docs/commands.md Outdated
Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/SchemaCommand.cs Outdated
Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/SchemaCommand.cs
Copilot AI review requested due to automatic review settings August 25, 2026 09:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

docs/commands.md:654

  • The sample output shows "indexingMode": "consistent", but the implementation surfaces ContainerIndexingPolicyView.IndexingMode, which is populated via indexingPolicy.IndexingMode.ToString() and will be Pascal-cased (e.g., "Consistent", same as the existing info command output). This makes the sample output misleading.
  "indexingPolicy": {
    "indexingMode": "consistent",
    "automatic": true,

Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/SchemaCommand.cs
Copilot AI review requested due to automatic review settings August 31, 2026 07:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/SchemaCommand.cs
Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/SchemaCommand.cs
Comment thread docs/commands.md Outdated
Copilot AI review requested due to automatic review settings August 31, 2026 08:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings August 31, 2026 09:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/SchemaCommand.cs Outdated
Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/SchemaCommand.cs
Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/SchemaCommand.cs
Copilot AI review requested due to automatic review settings August 31, 2026 09:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Suppressed comments (1)

CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/SchemaCommand.cs:96

  • The NotFound handler always throws error-container_not_found, but a 404 can also be triggered by a missing database. That can produce a misleading message ("container not found") when the real issue is "database not found". Consider checking database existence on the NotFound path and only emitting the container-not-found message when the database is confirmed to exist.
        catch (CosmosException e) when (e.StatusCode == HttpStatusCode.NotFound)
        {
            throw new CommandException(
                "schema",
                MessageService.GetArgsString(
                    "error-container_not_found",
                    "container",
                    containerName,
                    "database",
                    databaseName),
                e);
        }

@mkrueger
Mike Krüger (mkrueger) merged commit 4bc063e into main Aug 31, 2026
9 checks passed
@mkrueger
Mike Krüger (mkrueger) deleted the dev/mkrueger/schema-discovery branch August 31, 2026 10:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

M4. schema / describe discovery tool

3 participants