Skip to main content
Glama

analyze_repo_structure

Read-only

Analyze a code repository and propose ontology node candidates from package, README, and source structure without modifying vault frontmatter.

Instructions

R16 (autonomous ingest base) — analyze a code repository and propose ontology node candidates. side effect 0 (vault frontmatter NOT modified). Returns deterministic candidates the agent must turn into an evidence-backed proposal and move through the construction lifecycle before any exact batch-writer rows are released. Repository structure is implementation evidence, not automatic business meaning: extractionContract and proposedBusinessOntology make that uncertainty explicit. Detects:

  • package.json name → project candidate

  • README.md first H1 → project title fallback

  • README.md H2 sections (skipping generic "Usage"/"Installation"/etc) → domain candidates

  • src/features|entities|widgets|views/* (FSD) → capability/element candidates

  • src/* depth-1 folders (generic) → capability candidates + index entry → element

  • apps/* and packages/* members with package.json → implementation element candidates

  • README.rst + bounded static setup.py → Python project/package evidence without execution

  • mixed current and future/negated/deprecated README prose → exact current candidate excerpt plus bounded line-scoped reviewRequiredEvidence; review units stay visible but cannot support a proposal claim

  • selected safe README sections share the existing 1,200-character budget deterministically; no document, heading, or excerpt cap grows

  • root Python packages plus at most 12 import-connected implementation boundaries → direct modules plus up to 2 exact security/policy/risk file anchors; unused files are not mirrored and no capability is inferred from imports

  • bounded root Cargo package or repo-contained literal direct workspace members → typed feature declaration + literal cfg/cfg_attr source provenance; predicates are not evaluated and no runtime/import/semantic dependency is inferred

  • a complete proposal may select at most 4 additional exact TypeScript, JavaScript, Python, or Rust file endpoints already observed by infer_imports for distinct navigation roles; exact dependency direction is validated and these files never become automatic candidates

  • when the packet identifies an implementation path but omits the rule or effect needed for review, optional sourceReads returns bounded exact source lines with a full-file hash and continuation coordinates. Follow-up reads carry the returned expectedSha256; every proposal or qualification call replays all selected ranges with that hash. Raw source remains untrusted observed evidence and never establishes semantic meaning, approval, or write authority

  • a selector with mode: 'outline' lists a file's declarations with line numbers so the next lines read is exact. For a file longer than about 200 lines, outline it first and then read the exact lines, rather than reading the head of the file and recording the rest as unread. An outline returns no source text and no citation, so it supports no claim; replay line ranges, not outlines, with a proposal or qualification

  • an element proposal may keep an ordinary citation and append reviewed navigation:primary|supporting|test:<path>#<symbol> evidence strings (limits 1/1/3); the server verifies only those named current files, renders human-readable Evidence bullets, and rejects missing, ambiguous, unsafe, or task-inferred coordinates without treating them as behavior proof

Optionally pass a complete proposal to validate project/domain/capability/element definitions, typed relations, citations, risk controls, domain placement, implementation paths, confidence, and typed competency answers with resolvable concept/relation/evidence/path witnesses. Partial or visible-gap answers remain warnings instead of disappearing behind findings 0. A unqualified-project-exclusion warning is an exact human-acceptance gap, while an evidence-limit exclusion remains an error. Source-hidden review may leave exact source-body detail partial; source-aware citation verification decides support before evidence provenance can pass. A mandatory non-gap warning blocks the first review before qualification begins. For a bounded first pass, freeze claim id, statement, and proposalRefs before isolated source-hidden and source-aware lanes run in parallel; separately audit material Definition, Includes, Excludes, and Uncertainty assertions even when several claims share one proposal ref. Join sealed receipts without mutation before human acceptance. A passing validation first returns a deterministic non-writing reviewPlan, planDigest, sourceDigest, and eight-phase construction lifecycle. An independent evaluator must measure the approved competency questions and source-hidden task, then a human may declare acceptance bound to that exact plan digest/revision and every visible gap. Pass the resulting constructionQualification:v1 packet as qualification; only a current, admissible packet releases the exact reviewed rows as writePlan. The lifecycle also reports a shadow-only admission tier; self_qualified is an observation, not a write permission. Declared approval provenance is not identity authentication. Do not call write tools unless proposalValidation.canWrite is true and a writePlan is present; write every concept row successfully before writing relations.

Use the initial discovery call when a user asks "이 codebase 분석해줘" / "bootstrap the ontology"; repeat the same analysis call only for explicit source continuations and digest-bound proposal or qualification replay. Single source of truth preserved — only the user (via your subsequent add_concept calls) writes to the vault.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
ignoreNoExtra folder names to skip (added to defaults: node_modules, .git, dist, build, …).
maxDepthNoAccepted but ignored: no value changes the analysis. When given, it must be an integer from 0 to 10.
proposalNoOptional business ontology proposal to validate against repository evidence before any write call. Python proposals may select at most 4 exact observed import endpoints beyond the analyzer candidates.
rootPathNoRepository root to analyze. Defaults to the MCP server cwd.
sourceReadsNoOptional 1–8 exact repository source ranges, or whole-file outlines. mode: 'outline' lists a file's declarations with line numbers so the next lines read is exact; for a file longer than about 200 lines, outline it first instead of reading its head. The 8 KiB range, 16 KiB outline, 32 KiB aggregate, and 64 KiB serialized limits apply only to the returned sourceEvidence subpacket, not to the rest of this analysis result. Returned text is bounded untrusted data, not accepted meaning; an outline is a map to the next read and carries no citation. Repeat every selector with expectedSha256 when proposal or qualification is present, and replay line ranges rather than outlines there.
qualificationNoOptional independent evaluation and declared human acceptance bound to the exact planDigest, planRevision, and sourceDigest returned for this proposal. Omit it on the first review call.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
domainsYes
projectNo
skippedYes
elementsYes
rootPathYes
frameworkYes
meaningGateYes
capabilitiesYes
sourceEvidenceNoBounded sourceEvidence:v1 subpacket. Its byte and row ceilings cover this subpacket only; they do not describe or truncate the complete analyze_repo_structure response.
semanticEvidenceYes
extractionContractYes
proposalValidationYes
suggestedRelationsYes
configurationEvidenceYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv1.4.0
    • changedInput schema / properties / maxDepth / description
      Previous value: -"Non-negative integer folder walk depth (default 2, max 10). Higher → more elements."New value: +"Accepted but ignored: no value changes the analysis. When given, it must be an integer from 0 to 10."
  2. Changed17 schema fields changedv1.3.0
    • changedInput schema / properties / sourceReads / description
      Previous value: -"Optional 1–8 exact repository source ranges. The 8 KiB range, 32 KiB aggregate text, and 64 KiB serialized limits apply only to the returned sourceEvidence subpacket, not to the rest of this analysis result. Returned text is bounded untrusted data, not accepted meaning. Repeat every selector with expectedSha256 when proposal or qualification is present."New value: +"Optional 1–8 exact repository source ranges, or whole-file outlines. mode: 'outline' lists a file's declarations with line numbers so the next lines read is exact; for a file longer than about 200 lines, outline it first instead of reading its head. The 8 KiB range, 16 KiB outline, 32 KiB aggregate, and 64 KiB serialized limits apply only to the returned sourceEvidence subpacket, not to the rest of this analysis result. Returned text is bounded untrusted data, not accepted meaning; an outline is a map to the next read and carries no citation. Repeat every selector with expectedSha256 when proposal or qualification is present, and replay line ranges rather than outlines there."
    • changedInput schema / properties / sourceReads / items / properties / maxLines / description
      Previous value: -"Maximum complete source lines requested, from 1 through 200."New value: +"Maximum complete source lines requested, from 1 through 200. Required for mode 'lines'; rejected for mode 'outline'."
    • addedInput schema / properties / sourceReads / items / properties / mode
      Added value: +{
      +  "description": "Read shape, default 'lines'. 'lines' returns the exact requested range. 'outline' reads the whole file under the same 256 KiB file cap and returns its declarations with line numbers, no source text, and no range.",
      +  "enum": [
      +    "lines",
      +    "outline"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / sourceReads / items / properties / startLine / description
      Previous value: -"One-based first source line to return."New value: +"One-based first source line to return. Required for mode 'lines'; rejected for mode 'outline'."
    • changedInput schema / properties / sourceReads / items / required
      Previous value: -[
      -  "path",
      -  "startLine",
      -  "maxLines"
      -]New value: +[
      +  "path"
      +]
    • changedOutput schema / properties / sourceEvidence / properties / rows / items / oneOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "status": {
      -        "const": "read"
      -      }
      -    },
      -    "required": [
      -      "actualRange",
      -      "text",
      -      "citation",
      -      "fullFileSha256",
      -      "fileBytes",
      -      "fileLines",
      -      "returnedBytes",
      -      "truncated",
      -      "fileComplete"
      -    ]
      -  },
      -  {
      -    "not": {
      -      "anyOf": [
      -        {
      -          "required": [
      -            "text"
      -          ]
      -        },
      -        {
      -          "required": [
      -            "citation"
      -          ]
      -        }
      -      ]
      -    },
      -    "properties": {
      -      "status": {
      -        "enum": [
      -          "refused",
      -          "omitted"
      -        ]
      -      }
      -    },
      -    "required": [
      -      "reason"
      -    ]
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "status": {
      +        "const": "read"
      +      }
      +    },
      +    "required": [
      +      "actualRange",
      +      "text",
      +      "citation",
      +      "fullFileSha256",
      +      "fileBytes",
      +      "fileLines",
      +      "returnedBytes",
      +      "truncated",
      +      "fileComplete"
      +    ]
      +  },
      +  {
      +    "not": {
      +      "anyOf": [
      +        {
      +          "required": [
      +            "text"
      +          ]
      +        },
      +        {
      +          "required": [
      +            "citation"
      +          ]
      +        }
      +      ]
      +    },
      +    "properties": {
      +      "status": {
      +        "const": "outlined"
      +      }
      +    },
      +    "required": [
      +      "mode",
      +      "sha256",
      +      "language",
      +      "declarationCount",
      +      "declarations",
      +      "fileBytes",
      +      "fileLines",
      +      "returnedBytes",
      +      "truncated"
      +    ]
      +  },
      +  {
      +    "not": {
      +      "anyOf": [
      +        {
      +          "required": [
      +            "text"
      +          ]
      +        },
      +        {
      +          "required": [
      +            "citation"
      +          ]
      +        }
      +      ]
      +    },
      +    "properties": {
      +      "status": {
      +        "enum": [
      +          "refused",
      +          "omitted"
      +        ]
      +      }
      +    },
      +    "required": [
      +      "reason"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / sourceEvidence / properties / rows / items / properties / declarationCount
      Added value: +{
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / sourceEvidence / properties / rows / items / properties / declarations
      Added value: +{
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "kind": {
      +        "enum": [
      +          "function",
      +          "method",
      +          "class",
      +          "type",
      +          "interface",
      +          "struct",
      +          "enum",
      +          "const",
      +          "export",
      +          "section"
      +        ],
      +        "type": "string"
      +      },
      +      "line": {
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "name": {
      +        "minLength": 1,
      +        "pattern": "^(?!\\s)(?!.*\\s$)(?!.*\\u0000).+$",
      +        "type": "string"
      +      },
      +      "signature": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "line",
      +      "kind",
      +      "name",
      +      "signature"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / sourceEvidence / properties / rows / items / properties / language
      Added value: +{
      +  "minLength": 1,
      +  "pattern": "^(?!\\s)(?!.*\\s$)(?!.*\\u0000).+$",
      +  "type": "string"
      +}
    • addedOutput schema / properties / sourceEvidence / properties / rows / items / properties / mode
      Added value: +{
      +  "enum": [
      +    "outline"
      +  ],
      +  "type": "string"
      +}
    • removedOutput schema / properties / sourceEvidence / properties / rows / items / properties / requestedRange / additionalProperties
      Removed value: -false
    • addedOutput schema / properties / sourceEvidence / properties / rows / items / properties / requestedRange / anyOf
      Added value: +[
      +  {
      +    "type": "null"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "maxLines": {
      +        "maximum": 200,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "startLine": {
      +        "minimum": 1,
      +        "type": "integer"
      +      }
      +    },
      +    "required": [
      +      "startLine",
      +      "maxLines"
      +    ],
      +    "type": "object"
      +  }
      +]
    • removedOutput schema / properties / sourceEvidence / properties / rows / items / properties / requestedRange / properties
      Removed value: -{
      -  "maxLines": {
      -    "maximum": 200,
      -    "minimum": 1,
      -    "type": "integer"
      -  },
      -  "startLine": {
      -    "minimum": 1,
      -    "type": "integer"
      -  }
      -}
    • removedOutput schema / properties / sourceEvidence / properties / rows / items / properties / requestedRange / required
      Removed value: -[
      -  "startLine",
      -  "maxLines"
      -]
    • removedOutput schema / properties / sourceEvidence / properties / rows / items / properties / requestedRange / type
      Removed value: -"object"
    • addedOutput schema / properties / sourceEvidence / properties / rows / items / properties / sha256
      Added value: +{
      +  "pattern": "^[a-f0-9]{64}$",
      +  "type": "string"
      +}
    • changedOutput schema / properties / sourceEvidence / properties / rows / items / properties / status / enum
      Previous value: -[
      -  "read",
      -  "refused",
      -  "omitted"
      -]New value: +[
      +  "read",
      +  "outlined",
      +  "refused",
      +  "omitted"
      +]
  3. Changed5 schema fields changedv1.2.5
    • addedInput schema / properties / qualification / properties / purposeAuthority / properties / decisions / minItems
      Added value: +1
    • addedInput schema / properties / qualification / properties / purposeAuthority / properties / nonGoals / minItems
      Added value: +1
    • addedInput schema / properties / qualification / properties / purposeAuthority / properties / sourceRefs / minItems
      Added value: +1
    • addedInput schema / properties / sourceReads
      Added value: +{
      +  "description": "Optional 1–8 exact repository source ranges. The 8 KiB range, 32 KiB aggregate text, and 64 KiB serialized limits apply only to the returned sourceEvidence subpacket, not to the rest of this analysis result. Returned text is bounded untrusted data, not accepted meaning. Repeat every selector with expectedSha256 when proposal or qualification is present.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "expectedSha256": {
      +        "description": "Optional 64-character lowercase SHA-256 of the complete file. Required on every selector when proposal or qualification is present.",
      +        "pattern": "^[a-f0-9]{64}$",
      +        "type": "string"
      +      },
      +      "maxLines": {
      +        "description": "Maximum complete source lines requested, from 1 through 200.",
      +        "maximum": 200,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "path": {
      +        "description": "Literal repository-relative source path, at most 1,024 Unicode characters; no glob or directory traversal.",
      +        "maxLength": 1024,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "startLine": {
      +        "description": "One-based first source line to return.",
      +        "minimum": 1,
      +        "type": "integer"
      +      }
      +    },
      +    "required": [
      +      "path",
      +      "startLine",
      +      "maxLines"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 8,
      +  "minItems": 1,
      +  "type": "array"
      +}
    • addedOutput schema / properties / sourceEvidence
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Bounded sourceEvidence:v1 subpacket. Its byte and row ceilings cover this subpacket only; they do not describe or truncate the complete analyze_repo_structure response.",
      +  "properties": {
      +    "contract": {
      +      "enum": [
      +        "sourceEvidence:v1"
      +      ],
      +      "type": "string"
      +    },
      +    "coverage": {
      +      "enum": [
      +        "requested-ranges-only"
      +      ],
      +      "type": "string"
      +    },
      +    "limits": {
      +      "additionalProperties": {
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "type": "object"
      +    },
      +    "repositoryComplete": {
      +      "enum": [
      +        false
      +      ],
      +      "type": "boolean"
      +    },
      +    "rows": {
      +      "items": {
      +        "additionalProperties": false,
      +        "oneOf": [
      +          {
      +            "properties": {
      +              "status": {
      +                "const": "read"
      +              }
      +            },
      +            "required": [
      +              "actualRange",
      +              "text",
      +              "citation",
      +              "fullFileSha256",
      +              "fileBytes",
      +              "fileLines",
      +              "returnedBytes",
      +              "truncated",
      +              "fileComplete"
      +            ]
      +          },
      +          {
      +            "not": {
      +              "anyOf": [
      +                {
      +                  "required": [
      +                    "text"
      +                  ]
      +                },
      +                {
      +                  "required": [
      +                    "citation"
      +                  ]
      +                }
      +              ]
      +            },
      +            "properties": {
      +              "status": {
      +                "enum": [
      +                  "refused",
      +                  "omitted"
      +                ]
      +              }
      +            },
      +            "required": [
      +              "reason"
      +            ]
      +          }
      +        ],
      +        "properties": {
      +          "actualRange": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "endLine": {
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "startLine": {
      +                "minimum": 1,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "startLine",
      +              "endLine"
      +            ],
      +            "type": "object"
      +          },
      +          "citation": {
      +            "minLength": 1,
      +            "pattern": "^(?!\\s)(?!.*\\s$)(?!.*\\u0000).+$",
      +            "type": "string"
      +          },
      +          "fileBytes": {
      +            "minimum": 0,
      +            "type": "integer"
      +          },
      +          "fileComplete": {
      +            "type": "boolean"
      +          },
      +          "fileLines": {
      +            "minimum": 0,
      +            "type": "integer"
      +          },
      +          "fullFileSha256": {
      +            "pattern": "^[a-f0-9]{64}$",
      +            "type": "string"
      +          },
      +          "next": {
      +            "anyOf": [
      +              {
      +                "type": "null"
      +              },
      +              {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "expectedSha256": {
      +                    "pattern": "^[a-f0-9]{64}$",
      +                    "type": "string"
      +                  },
      +                  "maxLines": {
      +                    "maximum": 200,
      +                    "minimum": 1,
      +                    "type": "integer"
      +                  },
      +                  "path": {
      +                    "minLength": 1,
      +                    "pattern": "^(?!\\s)(?!.*\\s$)(?!.*\\u0000).+$",
      +                    "type": "string"
      +                  },
      +                  "startLine": {
      +                    "minimum": 1,
      +                    "type": "integer"
      +                  }
      +                },
      +                "required": [
      +                  "path",
      +                  "startLine",
      +                  "maxLines",
      +                  "expectedSha256"
      +                ],
      +                "type": "object"
      +              }
      +            ]
      +          },
      +          "path": {
      +            "minLength": 1,
      +            "pattern": "^(?!\\s)(?!.*\\s$)(?!.*\\u0000).+$",
      +            "type": "string"
      +          },
      +          "reason": {
      +            "minLength": 1,
      +            "pattern": "^(?!\\s)(?!.*\\s$)(?!.*\\u0000).+$",
      +            "type": "string"
      +          },
      +          "requestComplete": {
      +            "type": "boolean"
      +          },
      +          "requestedRange": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "maxLines": {
      +                "maximum": 200,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "startLine": {
      +                "minimum": 1,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "startLine",
      +              "maxLines"
      +            ],
      +            "type": "object"
      +          },
      +          "returnedBytes": {
      +            "minimum": 0,
      +            "type": "integer"
      +          },
      +          "status": {
      +            "enum": [
      +              "read",
      +              "refused",
      +              "omitted"
      +            ],
      +            "type": "string"
      +          },
      +          "text": {
      +            "type": "string"
      +          },
      +          "truncated": {
      +            "type": "boolean"
      +          }
      +        },
      +        "required": [
      +          "status",
      +          "path",
      +          "requestedRange",
      +          "requestComplete",
      +          "next"
      +        ],
      +        "type": "object"
      +      },
      +      "maxItems": 8,
      +      "minItems": 1,
      +      "type": "array"
      +    },
      +    "serializedBytes": {
      +      "maximum": 65536,
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "totalReturnedBytes": {
      +      "maximum": 32768,
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "trust": {
      +      "enum": [
      +        "untrusted-source-data"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "contract",
      +    "trust",
      +    "limits",
      +    "coverage",
      +    "repositoryComplete",
      +    "rows",
      +    "totalReturnedBytes",
      +    "serializedBytes"
      +  ],
      +  "type": "object"
      +}
  4. First observedv0.13.0

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds substantial context beyond them: side effect 0, deterministic candidates, bounded read/edit budgets (1,200-char README budget, 8/16/32/64 KiB limits, ~200-line outline threshold), the full review/qualification lifecycle, and the rule that returned source is untrusted evidence that never grants write authority. None of this is recoverable from the annotations or schema.

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

Conciseness2/5

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

The purpose is front-loaded, but the body is a ~1,500-word wall mixing bullet lists with dense jargon (reviewRequiredEvidence, sourceHiddenTask, constructionQualification:v1, axisResults). Several constraints are repeated verbatim (the expectedSha256 replay rule and the 'outline first for >200-line files' advice each appear twice), so not every sentence earns its place. Much of the lifecycle policy reads like documentation rather than selection guidance.

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?

An output schema exists, so return values need not be explained, yet the description still covers the critical output-side contract (reviewPlan, planDigest, sourceDigest, writePlan gating, eight-phase lifecycle, shadow-only admission tier). For a tool of this complexity with 6 params and nested proposal/qualification objects, the agent has enough to call it correctly and know what gates follow.

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

Parameters4/5

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

Schema description coverage is already 100%, so the schema carries baseline semantics for ignore, maxDepth, proposal, sourceReads, qualificitation. The description nonetheless adds real meaning: maxDepth is accepted but ignored, sourceReads mode 'outline' returns no source text or citation and must be replayed as line ranges, and expectedSha256 becomes mandatory whenever proposal or qualification is present.

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 opening sentence states a specific verb+resource (analyze a code repository and propose ontology node candidates) and immediately scopes the side effect (vault frontmatter NOT modified). The enumerated detection rules (package.json, README H1/H2, FSD folders, Cargo/Python packages) make it unmistakable versus siblings like infer_imports or read_source, which it explicitly references.

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

Usage Guidelines4/5

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

It gives explicit trigger guidance ('Use the initial discovery call when a user asks ... / bootstrap the ontology') and constrains recurrence ('repeat the same analysis call only for explicit source continuations and digest-bound proposal or qualification replay'). It also states prerequisites for downstream writes (do not call write tools unless proposalValidation.canWrite and a writePlan exist). It stops short of naming alternative sibling tools to prefer for narrower cases.

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