Structured MCP filter schemas, hardened value enums, tool-description rewrite#315
Merged
Merged
Conversation
search/find/neighbors `filter`/`edge_filter` params are now typed NodeFilter/EdgeFilter (structured, extra-forbidden) instead of opaque dict|str, so MCP clients see field-level enums and descriptions. Value taxonomies role/framework/source_layer/client_kind/producer_kind are Literal enums. Rewrite the five tool descriptions and _INSTRUCTIONS to drop internal-implementation leaks, cross-reference sibling tools, and document strict-frame failure modes. apply_auto_scope operates on NodeFilter. Co-Authored-By: Claude <noreply@anthropic.com>
The in-source @CodebaseHttpClient(clientKind=) / @CodebaseProducer(producerKind=) enum paths did str(val) with no validation, unlike the YAML path. Validate against VALID_CLIENT_KINDS/VALID_PRODUCER_KINDS (deferred import to avoid the java_ontology->ast_java cycle) and warn-and-ignore on unknown — this closes the last open producers, making client_kind/producer_kind a closed set safe to surface as enums. Also document in java_ontology.py that VALID_ROLES deliberately excludes OTHER (inference-only fallback; the read-side Role enum includes it). Co-Authored-By: Claude <noreply@anthropic.com>
The structured filter schemas PR makes role/framework/source_layer/ client_kind/producer_kind closed Literal enums with extra="forbid", so stale or omitted values are now hard schema errors instead of silent no-ops. Align the three consumer-facing operating manuals with the now-closed sets: - Framework glossary: drop the non-existent `codebase_async_route` (only ever a function name, never a stored value), add the missing `feign`, drop the misleading `...` (the set is now closed/exhaustive). - NodeFilter applicability tables: add `source_layer` to the client and producer rows (applicable per _NODEFILTER_APPLICABLE_FIELDS, previously undocumented). - Strict-frame note: invalid enum values (e.g. wrong case) are rejected earlier at the schema layer with the valid set listed - distinct from the success=false applicability path. - Glossary: add Source layers (client/producer) closed value set. Doc-only; no code or test impact. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Scope
Make the MCP filter surface structured and visible to clients, harden the
value taxonomies to enums, rewrite the tool descriptions, and close the
indexer-side validation holes that made two of those enums trustworthy.
Accumulated across a multi-session effort (no separate propose — incrementally
reviewed with the user); shipped as two logical commits.
Changes
server.py,mcp_v2.py):search/find/neighborsfilterandedge_filterare typedNodeFilter/EdgeFilterinstead ofopaque
dict | str, so the tool input schema now exposes field-level types,enums, and descriptions (
$ref NodeFilter/$ref EdgeFilter).mcp_v2.py):role,framework,source_layer,client_kind,producer_kindareLiteralenums (the last two newly closed).ast_java.py): the in-source@CodebaseHttpClient(clientKind=)/@CodebaseProducer(producerKind=)enumpaths now validate against
VALID_CLIENT_KINDS/VALID_PRODUCER_KINDS(warn + ignore on unknown), mirroring the existing YAML path. Deferred import
to avoid the
java_ontology → ast_javacycle. This is what makesclient_kind/producer_kinda closed set safe to surface as enums.VALID_ROLES/OTHER(java_ontology.py): added a comment documentingthat
OTHERis deliberately excluded — it is the inference-only fallback(read-side
Roleenum includes it; write-sideVALID_ROLESdoes not).OTHERwas not added to
VALID_ROLES(would weaken@CodebaseRole/brownfieldvalidation with no benefit).
_INSTRUCTIONS(server.py): droppedinternal-implementation leaks, added sibling-tool cross-references, documented
strict-frame failure modes (incl. the
dedup_calls-without-CALLS silentno-op,
hybrid+table='all'→success=false).apply_auto_scope(server.py): operates onNodeFilter(model_copyinjection).
Behavior changes
filter/edge_filterare now structured withextra="forbid". Unknown keys / bad enum values now fail at the FastMCP schemalayer as a
ToolErrorthat names the bad field and lists the valid enumvalues (a net teaching improvement — the old
success=falseenvelope neverlisted valid values for enum fields). Per-kind applicability and wildcard
checks still return the in-function
success=falseenvelope (withhints_structured). Direct v2 Python callers are unaffected (still acceptdicts, still get the teaching envelope).
@CodebaseHttpClient(clientKind=…)/@CodebaseProducer(producerKind=…)values are now dropped (warned on stderr)instead of stored verbatim.
Reindex / ontology / env
ontology_versionbump — no graph schema/column change and noenrichment-semantic change.
kinds under the old hole: that data remains in the graph but is no longer
filterable via the new enum.
Validation
ruff check .cleanpytest tests— 769 passed, 11 skipped (11 skips pre-existing/env-gated;+2 new tests
test_29a/test_29bcovering the source-annotation validation)🤖 Generated with Claude Code