Skip to content

propose: list_clients MCP tool — outbound counterpart to list_routes#37

Merged
HumanBean17 merged 1 commit into
masterfrom
propose/list-clients-mcp-tool
May 6, 2026
Merged

propose: list_clients MCP tool — outbound counterpart to list_routes#37
HumanBean17 merged 1 commit into
masterfrom
propose/list-clients-mcp-tool

Conversation

@HumanBean17
Copy link
Copy Markdown
Owner

Summary

Companion propose to PR #36 (brownfield annotations v2). After v2 lands, Feign declarations leave the Route table because they're correctly modeled as outbound @CodebaseClient annotations rather than inbound routes. This leaves a real workflow without an entry point:

"Show me every outbound HTTP call this service makes, what service it targets, and what kind of client it uses."

Pre-v2, agents reach for list_routes(framework=feign) — which is wrong on three counts:

  1. Only returns Feign declarations; imperative RestTemplate / WebClient call sites with @CodebaseClient overrides are invisible.
  2. Conflates "this service exposes a Feign-fronted endpoint" with "this service calls a Feign-fronted endpoint" — two directions, same query.
  3. Post-v2, returns nothing (Feign rows leave the Route table).

This propose closes the gap with a first-class outbound-client query path.

What lands

  1. Client graph node table — one row per @CodebaseClient annotation (Feign methods synthesised from source; imperative call sites only when explicitly annotated).
  2. DECLARES_CLIENT(Symbol → Client) rel table — mirrors the existing EXPOSES(Symbol → Route) edge.
  3. list_clients MCP tool — filters symmetric to list_routes: microservice, client_kind, target_service, path_prefix, method.

HTTP_CALLS(Symbol → Route) stays unchanged — Client is additional caller-side metadata, not a replacement. Pass6's hint-recovery walk retargets from the caller's http_consumer route to the caller's DECLARES_CLIENT → Client path. Same data, new home.

Surface

list_clients(
    microservice: str | None = None,
    client_kind: str | None = None,    # feign_method | rest_template | web_client
    target_service: str | None = None,
    path_prefix: str | None = None,
    method: str | None = None,
    limit: int = 100,
) -> ClientsListOutput

ClientRowDto mirrors RouteRowDto field-for-field where applicable (id, path, path_template, path_regex, method, microservice, module, filename, start_line, end_line, resolved) plus client_kind, target_service, member_fqn, member_id.

Out of scope (sketched, separate proposals)

  • get_client_by_path(microservice, path_template, method) — symmetric with get_route_by_path
  • find_client_callers(client_id)
  • find_client_target_route(client_id)
  • Producer node + list_async_producers (the async outbound parallel)

Open questions inside

  1. target_service foreign-key vs string — recommend string for v1
  2. Should Client carry call-edge resolution outcome — recommend keep on HTTP_CALLS only
  3. list_clients vs list_http_clients naming — recommend the shorter form
  4. Auto-emit Client rows for un-annotated RestTemplate/WebClient call sites — recommend opt-in via @CodebaseClient for v1

Schema impact

ONTOLOGY_VERSION bump: 9 → 10. Additive (new node + rel tables only); no destructive schema changes.

Tests

This is a doc-only propose; no code changes. Test baseline unchanged.

Sequencing

This PR depends on PR #36 (v2 annotations) landing first. The data the tool reads from doesn't exist until v2 reshapes how Feign declarations are stored. Implementation PRs for list_clients follow after v2 implementation.

…utes

Companion propose to the v2 brownfield annotations PR (#36).

After v2 lands, Feign declarations leave the Route table — they're
correctly modeled as outbound @CodebaseClient annotations rather than
inbound routes. This leaves a real workflow without an entry point:
"show me every outbound HTTP call this service makes".

Pre-v2, agents reach for list_routes(framework=feign), which is wrong
on three counts (only Feign, conflates direction, returns nothing
post-v2). The propose adds:

1. A new Client graph node table storing outbound-client declarations
   (one row per @CodebaseClient annotation; Feign methods synthesised
   from source).

2. A new DECLARES_CLIENT(Symbol → Client) rel table mirroring the
   existing EXPOSES(Symbol → Route) edge.

3. A list_clients MCP tool with filters symmetric to list_routes
   (microservice, client_kind, target_service, path_prefix, method).

The HTTP_CALLS(Symbol → Route) edge stays unchanged — Client is
additional caller-side metadata, not a replacement. Pass6's hint
recovery walk retargets from the caller's http_consumer route to
the caller's DECLARES_CLIENT → Client path. Same data, new home.

Three follow-up tools sketched but punted:
- get_client_by_path (symmetric with get_route_by_path)
- find_client_callers
- find_client_target_route

A parallel Producer node + list_async_producers tool is also flagged
as future work for the async outbound side.

ONTOLOGY_VERSION bump: 9 → 10.

No code change in this propose; doc-only.
@HumanBean17 HumanBean17 merged commit e433cbe into master May 6, 2026
@HumanBean17 HumanBean17 deleted the propose/list-clients-mcp-tool branch May 10, 2026 21:18
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.

1 participant