Skip to content

Expose auto-discovered methods as individual MCP tools (hybrid approach)#35

Merged
baubakg merged 3 commits intomainfrom
mcp-method-discovery
Apr 21, 2026
Merged

Expose auto-discovered methods as individual MCP tools (hybrid approach)#35
baubakg merged 3 commits intomainfrom
mcp-method-discovery

Conversation

@baubakg
Copy link
Copy Markdown
Member

@baubakg baubakg commented Apr 21, 2026

Summary:

  • Previously all 2000+ auto-discovered methods were embedded as plain text inside java_call's description, exceeding LLM context
    windows and making method discovery impossible without trial-and-error 404 guessing
  • Each public static method is now exposed as its own tool in tools/list (ClassName_methodName naming, inputSchema with
    arg0/arg1/... params) — searchable by keyword via ToolSearch
  • Individual tool calls route through handleIndividualToolCall() → handleJavaCall(), so PRECHAIN applies automatically
  • java_call retained for multi-step chains, overloaded/instance methods, and cases where step B needs the live Java object from step A

Test plan:

  • 279 tests pass (mvn -Dtest=MCPBridgeServerTest,MCPToolDiscoveryTest test)
  • tools/list returns individual tools + java_call + ibs_diagnostics
  • Individual tool calls return correct results
  • java_call chaining (including complex object pass-by-reference) still works
  • PRECHAIN applies to individual tool calls

baubakg and others added 2 commits April 21, 2026 17:23
Previously all auto-discovered methods were embedded as plain text in
java_call's description. With 2000+ methods this exceeded LLM context
windows and got truncated, making method discovery impossible without
trial-and-error 404 guessing.

Each public static method is now exposed as its own tool in tools/list
(name: ClassName_methodName, inputSchema with arg0/arg1/... params).
Individual tool calls are routed through handleIndividualToolCall() which
builds a synthetic single-step callContent and delegates to handleJavaCall()
so PRECHAIN is applied automatically.

java_call is retained for multi-step chains, overloaded/instance methods,
and any case where step B needs the live Java object returned by step A.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mermaid flowchart showing the startup package scan that populates
tools/list, and the two per-call paths (individual tool and java_call)
converging on handleJavaCall() through the isolated classloader.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

…uilders

The constructor's try-catch for JsonProcessingException was dead code — the
schemas are hardcoded constants that never fail to parse. handleIndividualToolCall's
catch was also dead code since handleJavaCall catches its own exceptions internally.
Replaced both with no-exception-possible patterns to eliminate the uncovered lines.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

@baubakg baubakg merged commit d07cbe7 into main Apr 21, 2026
8 checks passed
@baubakg baubakg deleted the mcp-method-discovery branch April 21, 2026 16:16
baubakg added a commit that referenced this pull request Apr 21, 2026
…ch) (#35)

* Expose auto-discovered methods as individual MCP tools (hybrid approach)

Previously all auto-discovered methods were embedded as plain text in
java_call's description. With 2000+ methods this exceeded LLM context
windows and got truncated, making method discovery impossible without
trial-and-error 404 guessing.

Each public static method is now exposed as its own tool in tools/list
(name: ClassName_methodName, inputSchema with arg0/arg1/... params).
Individual tool calls are routed through handleIndividualToolCall() which
builds a synthetic single-step callContent and delegates to handleJavaCall()
so PRECHAIN is applied automatically.

java_call is retained for multi-step chains, overloaded/instance methods,
and any case where step B needs the live Java object returned by step A.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add architecture diagram to MCP method discovery section

Mermaid flowchart showing the startup package scan that populates
tools/list, and the two per-call paths (individual tool and java_call)
converging on handleJavaCall() through the isolated classloader.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix coverage gap: replace JSON schema parsing with programmatic map builders

The constructor's try-catch for JsonProcessingException was dead code — the
schemas are hardcoded constants that never fail to parse. handleIndividualToolCall's
catch was also dead code since handleJavaCall catches its own exceptions internally.
Replaced both with no-exception-possible patterns to eliminate the uncovered lines.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
baubakg added a commit that referenced this pull request Apr 22, 2026
* Align README MCP section with MCP.md

- Fix tool discovery model: tools/list returns one tool (java_call with
  embedded catalog), not per-method named tools
- Fix tools/call example to use java_call + callContent, not tool name
- Rename "Fallback Tool" section — java_call is the only MCP tool
- Add ibs_diagnostics, IBS.MCP.PRECHAIN, IBS.MCP.REQUIRE_JAVADOC
- Fix dependency version 2.11.18 → 2.11.19 to match MCP.md
- Update TOC

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update docs to version 3.11.0

Add 3.11.0 release notes entry covering MCP doc corrections, new env
vars, dependency bumps, and CI GPG fix. Update version references in
README and MCP.md from 2.11.19 to 3.11.0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Simplify 3.11.0 release notes to high-level summary

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add issue #12 reference to 3.11.0 MCP release note

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Bump GitHub Actions to v5 to fix Node.js 20 deprecation warning

actions/checkout, actions/setup-java, and actions/cache all moved from
v4 (Node.js 20) to v5 (Node.js 24).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Bump actions/upload-artifact to v5 to fix Node.js 20 deprecation warning

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* [maven-release-plugin] prepare release parent-3.11.0

* [maven-release-plugin] prepare for next development iteration

* Add missing Javadoc @param and @return to MCPRequestHandler#handle

Fixes Javadoc warnings raised during the release build.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update version to 3.11.1 in docs and add Central promotion step

- Bump all doc version references from 3.11.0 to 3.11.1
- Add POST /manual/upload step to release workflow to trigger
  Central Publisher Portal promotion after staging deploy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add Central promotion step to deploy workflow

Mirrors the same POST /manual/upload step added to the release workflow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Remove Central promotion step from deploy workflow

Snapshot deploys go directly to the snapshot repository — no staging
repository is created, so the promotion POST returns 400. The promotion
step belongs only in the release workflow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* [maven-release-plugin] prepare release parent-3.11.1

* [maven-release-plugin] prepare for next development iteration

* Fix CI badge staleness for SonarCloud quality gate and codecov (#22)

Trigger SonarCloud analysis on push to main (not just PRs) so the quality
gate badge stays current after merges. Remove dead jacoco log step that
referenced a non-existent step output.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update dependency org.testng:testng to v7.12.0 (#21)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update dependency org.mockito:mockito-core to v5.23.0 (#20)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update log4j2 monorepo to v2.25.4 (#23)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update actions/checkout action to v6 (#24)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Expose auto-discovered methods as individual MCP tools (hybrid approach) (#35)

* Expose auto-discovered methods as individual MCP tools (hybrid approach)

Previously all auto-discovered methods were embedded as plain text in
java_call's description. With 2000+ methods this exceeded LLM context
windows and got truncated, making method discovery impossible without
trial-and-error 404 guessing.

Each public static method is now exposed as its own tool in tools/list
(name: ClassName_methodName, inputSchema with arg0/arg1/... params).
Individual tool calls are routed through handleIndividualToolCall() which
builds a synthetic single-step callContent and delegates to handleJavaCall()
so PRECHAIN is applied automatically.

java_call is retained for multi-step chains, overloaded/instance methods,
and any case where step B needs the live Java object returned by step A.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add architecture diagram to MCP method discovery section

Mermaid flowchart showing the startup package scan that populates
tools/list, and the two per-call paths (individual tool and java_call)
converging on handleJavaCall() through the isolated classloader.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix coverage gap: replace JSON schema parsing with programmatic map builders

The constructor's try-catch for JsonProcessingException was dead code — the
schemas are hardcoded constants that never fail to parse. handleIndividualToolCall's
catch was also dead code since handleJavaCall catches its own exceptions internally.
Replaced both with no-exception-possible patterns to eliminate the uncovered lines.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Prepare release 3.11.2

- Add 3.11.2 release notes entry (hybrid MCP tool discovery, dependency bumps, CI)
- Update version references in README and docs/MCP.md from 3.11.1 to 3.11.2

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Document release process in CLAUDE.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README MCP section for hybrid tool discovery (3.11.2)

The Discovering Tools and Calling a Discovered Tool sections still
described the old single-java_call approach. Updated to reflect that
tools/list now returns one named tool per auto-discovered method plus
java_call and ibs_diagnostics, and that individual tools can be called
directly for stateless single-method invocations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix stale version in /test endpoint response example (3.11.2)

The health check response example still showed 2.11.16 instead of 3.11.2.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* [maven-release-plugin] prepare release parent-3.11.2

* [maven-release-plugin] prepare for next development iteration

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: adobe-bot <Grp-opensourceoffice@adobe.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant