Skip to content

Schema quality: missing property descriptions across official MCP servers #3669

Closed

Description

@KryptosAI

Summary

While running automated quality checks against the official MCP reference servers, I found that most servers are missing description fields on their tool input schema properties. This matters because LLMs use these descriptions to understand how to call tools correctly — without them, the model has to guess what each parameter means from the name alone.

Findings

Tested with MCP Observatory v0.13.0 on 2026-03-22.

server-filesystem (11 tools, 18 missing descriptions)

Every tool property across all 11 tools lacks a description:

  • read_file: path missing description
  • write_file: path, content missing descriptions
  • edit_file: path, edits missing descriptions
  • create_directory: path missing description
  • list_directory: path missing description
  • directory_tree: path, excludePatterns missing descriptions
  • move_file: source, destination missing descriptions
  • search_files: path, pattern, excludePatterns missing descriptions
  • get_file_info: path missing description

server-everything (13 tools, 5 missing descriptions + 4 missing required)

  • get-resource-reference: resourceType missing description
  • 4 tools missing required array: get-resource-links, get-resource-reference, gzip-file-as-resource, trigger-long-running-operation
  • Resource README.md.gz missing description

server-memory (6 tools, 4 missing descriptions)

  • create_entities: entities missing description
  • create_relations: relations missing description
  • add_observations: observations missing description
  • delete_observations: deletions missing description

Why this matters

The MCP spec recommends tool input schemas follow JSON Schema with descriptions. When an LLM sees:

{ "type": "string" }

vs:

{ "type": "string", "description": "Absolute or relative path to the file to read" }

The second version produces significantly better tool-use accuracy. Since these are the reference implementations that other server authors look at, setting a good example here would improve schema quality across the ecosystem.

Suggested fix

Add description fields to all tool input schema properties. Example for read_file:

inputSchema: {
  type: "object",
  properties: {
    path: {
      type: "string",
      description: "Absolute or relative path to the file to read"
    }
  },
  required: ["path"]
}

Reproduction

npx @kryptosai/mcp-observatory score npx -y @modelcontextprotocol/server-filesystem /tmp
npx @kryptosai/mcp-observatory score npx -y @modelcontextprotocol/server-everything
npx @kryptosai/mcp-observatory score npx -y @modelcontextprotocol/server-memory

Activity

  1. khalidsaidi commented on Mar 24, 2026

    @khalidsaidi
  2. radeshgovind-2005 commented on Mar 27, 2026

    @radeshgovind-2005

    Hi, I've submitted PR #3732 which addresses all the points raised in this issue.

  3. jashshah999 commented on May 5, 2026

    @jashshah999
  4. PengSpirit commented on May 9, 2026

    @PengSpirit
  5. Ben-Home commented on Jun 13, 2026

    @Ben-Home
  6. cliffhall commented on Oct 19, 2026

    @cliffhall
    Member

    Triage: Priority Low (total 4)

    • Severity 2: Many tool input properties still lack descriptions, and adding them is a usability improvement that helps models call the tools correctly.
    • Urgency 2: wanted eventually
    • Bonuses: none

    Board: Servers V2 (#43), Status Incoming, awaiting maintainer review (no milestone yet). Part of the backlog triage in #4875.

  7. cliffhall commented on Oct 20, 2026

    @cliffhall
    Member

    Prior work, from the PR backlog triage (#4877). These outside pull requests addressed this issue against the pre-refactor code:

    They are being closed as part of the backlog triage in #4875, since the repository now takes issues rather than outside PRs and their diffs predate the v2 refactor. They stay readable and serve as prototypes for the fix here. Thank you to their authors.

  8. Pranav-Nexus commented on Oct 21, 2026

    @Pranav-Nexus

    v2 Codebase Audit (origin/main / v2.0.0) & Ready-to-Run Factory Prompt

    Following the v2 spec refactor (#4857) and backlog triage (#4875 / #4877), I audited the current v2 codebase across all three servers (filesystem, memory, everything) to see what was already resolved by the refactor and what still lacks property descriptions under the AGENTS.md rule ("Validate tool input with Zod schemas, with descriptions on the fields").

    1. What v2 Already Fixed vs. What Remains

    • src/filesystem/server.ts (16 properties across 11 tools still missing .describe()):

      • Architectural cleanup opportunity: In v2, tool registration now passes jsonSchema2020(<Tool>ArgsSchema.shape) directly to inputSchema, so adding .describe() on the top-level Zod schemas automatically populates the advertised 2020-12 JSON Schema. However, read_file and read_text_file still inline a duplicate { path, tail, head } object inside jsonSchema2020({...}) instead of passing ReadTextFileArgsSchema.shape.
      • Missing property descriptions:
        • ReadTextFileArgsSchema: path
        • ReadMediaFileArgsSchema: path
        • WriteFileArgsSchema: path, content
        • EditFileArgsSchema: path, edits
        • CreateDirectoryArgsSchema: path
        • ListDirectoryArgsSchema: path
        • ListDirectoryWithSizesArgsSchema: path
        • DirectoryTreeArgsSchema: path, excludePatterns
        • MoveFileArgsSchema: source, destination
        • SearchFilesArgsSchema: path, pattern, excludePatterns
        • GetFileInfoArgsSchema: path
      • Behavioral nuance worth noting in search_files vs directory_tree descriptions:
        • In search_files (lib.ts searchFilesWithValidation), both pattern and excludePatterns are evaluated directly via minimatch(relativePath, ..., { dot: true })—meaning a bare directory name like excludePatterns: ["node_modules"] only excludes the top-level directory entry itself while still traversing children unless **/node_modules/** is passed (and a bare filename pattern: "foo.ts" only matches at the root of path unless **/foo.ts or *.ts is used).
        • In contrast, directory_tree (server.ts buildTree) auto-expands non-wildcard excludePatterns to **/${pattern} and **/${pattern}/**. Calling out the expected glob syntax (e.g., '*.ts', '**/*.json', ['**/node_modules/**']) in the parameter descriptions prevents first-turn agent retries.
    • src/memory/index.ts (5 top-level properties still missing .describe()):

      • delete_entities (entityNames), delete_relations (relations), and open_nodes (names) already have .describe() in v2.
      • Still missing .describe():
        • SearchNodesQuerySchema (search_nodes -> query)
        • create_entities (entities: z.array(EntitySchema))
        • create_relations (relations: z.array(RelationSchema))
        • add_observations (observations: z.array(...))
        • delete_observations (deletions: z.array(...))
    • src/everything/ (1 property missing .describe()):

      • The required arrays and resource descriptions noted in the original v1 report are already resolved in v2.
      • Only src/everything/tools/get-resource-reference.ts -> GetResourceReferenceSchema.shape.resourceType (z.enum([RESOURCE_TYPE_TEXT, RESOURCE_TYPE_BLOB]).default(RESOURCE_TYPE_TEXT)) is still missing .describe().

    2. Prompt for the Agentic Workflow (CONTRIBUTING.md format)

    Per CONTRIBUTING.md, here is a self-contained prompt that can be fed directly into the repository's workflow to close #3669 with protocol-level test assertions in server-tools.test.ts:

    Resolve #3669 by ensuring every advertised tool input schema property across `src/filesystem`, `src/memory`, and `src/everything` has a clear `.describe(...)` annotation, and pin the invariant in protocol-level `listTools()` tests:
    
    1. **`src/filesystem/server.ts`**:
       - Add `.describe(...)` to all 16 undocumented fields across `ReadTextFileArgsSchema` (`path`), `ReadMediaFileArgsSchema` (`path`), `WriteFileArgsSchema` (`path`, `content`), `EditFileArgsSchema` (`path`, `edits`), `CreateDirectoryArgsSchema` (`path`), `ListDirectoryArgsSchema` (`path`), `ListDirectoryWithSizesArgsSchema` (`path`), `DirectoryTreeArgsSchema` (`path`, `excludePatterns`), `MoveFileArgsSchema` (`source`, `destination`), `SearchFilesArgsSchema` (`path`, `pattern`, `excludePatterns`), and `GetFileInfoArgsSchema` (`path`).
       - For `SearchFilesArgsSchema.pattern`, explicitly state that it matches file/directory names (not file contents) using a `minimatch` glob relative to `path` (e.g. `"*.ts"`, `"**/*.json"`).
       - For `excludePatterns` on `SearchFilesArgsSchema` and `DirectoryTreeArgsSchema`, document glob exclusion syntax (e.g. `["**/node_modules/**", "**/.git/**"]`).
       - Deduplicate `read_file` and `read_text_file` `inputSchema` registrations by passing `jsonSchema2020(ReadTextFileArgsSchema.shape)` instead of repeating the inline `{ path, tail, head }` object.
    
    2. **`src/memory/index.ts`**:
       - Add `.describe(...)` to `SearchNodesQuerySchema` and the top-level array fields in `create_entities` (`entities`), `create_relations` (`relations`), `add_observations` (`observations`), and `delete_observations` (`deletions`).
    
    3. **`src/everything/tools/get-resource-reference.ts`**:
       - Add `.describe(...)` to `resourceType` in `GetResourceReferenceSchema`.
    
    4. **Protocol-level tests**:
       - In `src/filesystem/__tests__/server-tools.test.ts` (and equivalent tool-list tests in `memory` and `everything`), add an assertion over `await client.listTools()` verifying that for every tool, every property in `tool.inputSchema.properties` has a non-empty `string` `description`.
       - Run `npm run format` and `npm run local:gate` (including 90% per-file coverage).
  9. modified the milestones: v2.3.0, v2.4.0 on Oct 25, 2026
  10. jajazpua commented on Nov 1, 2026

    @jajazpua
  11. jajazpua commented on Nov 4, 2026

    @jajazpua

    Because the measurements cited here were made with MCP Observatory v0.13.0 in March 2026, I'd rerun the current reference servers before attributing all the same missing-description counts to their latest versions.

    For a safe patch review, compare the actual tools/list manifests before/after: (1) verify each newly described field points to the same schema path, (2) ensure the required arrays, types, enum values and defaults remain unchanged unless intentionally fixed, and (3) score description coverage separately from behavioral/schema compatibility.

    That would distinguish a documentation-quality improvement from a possibly breaking contract edit. This is a proposed verification method; I haven't rerun Observatory against current server releases.

  12. self-assigned this
    on Nov 5, 2026
  13. added 2 commits that reference this issue on Nov 5, 2026
  14. cliffhall commented on Nov 5, 2026

    @cliffhall
    Member

    Fixed by #5475: every tool input property in the filesystem, memory and everything servers now has a description, and a test in each TypeScript server fails on any property without one. The Python servers were already fully described.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions