Skip to content

Add MCP server support (issue #12) #13

Merged
baubakg merged 27 commits intomainfrom
mcp
Apr 16, 2026
Merged

Add MCP server support (issue #12) #13
baubakg merged 27 commits intomainfrom
mcp

Conversation

@baubakg
Copy link
Copy Markdown
Member

@baubakg baubakg commented Apr 14, 2026

Summary

  • Exposes Java methods as MCP tools via a new POST /mcp endpoint (JSON-RPC 2.0),
    enabling AI agents (Claude Code, etc.) to call Java methods directly
    by default (IBS.MCP.REQUIRE_JAVADOC=true)
  • Adds java_call fallback tool for call chaining and instance methods
  • Migrates Sonatype publishing from oss.sonatype.org to
    ossrh-staging-api.central.sonatype.com (legacy host retirement)

New configuration

Property Default Purpose
IBS.MCP.ENABLED false Enables the /mcp endpoint
IBS.MCP.REQUIRE_JAVADOC true Only expose methods with Javadoc
IBS.CLASSLOADER.STATIC.INTEGRITY.PACKAGES Packages to scan for tools

Test plan

  • MCPToolDiscoveryTest — unit tests for discovery, Javadoc gate, hasJavadoc() helper
  • MCPBridgeServerTest — integration tests for initialize, tools/list, tools/call, java_call
  • Verify undocumented methods absent from tools/list (Javadoc gate)

baubakg and others added 27 commits April 13, 2026 16:32
Exposes configured Java packages as MCP tools over JSON-RPC 2.0 on the
existing Spark port, enabling AI clients to discover and invoke methods
via the Model Context Protocol without a separate server or port.

- MCPToolDiscovery: scans IBS.CLASSLOADER.STATIC.INTEGRITY.PACKAGES at
  startup and builds a tool catalogue (one tool per public static method)
  with JSON Schema derived from parameter types; disambiguates overloads
  by param count, skips ambiguous same-count overloads
- MCPRequestHandler: handles initialize / tools/list / tools/call over
  JSON-RPC 2.0; includes a generic java_call fallback tool for instance
  methods and call chaining; all exceptions returned as isError responses
- IntegroAPI: registers POST /mcp when IBS.MCP.ENABLED=true
- ConfigValueHandlerIBS: adds IBS.MCP.ENABLED feature flag (default false)
- 31 new tests (MCPToolDiscoveryTest + MCPBridgeServerTest), all passing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Set FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true on all four jobs so
actions/checkout@v4 and actions/setup-java@v4 run on Node.js 24.
This addresses the deprecation warning ahead of the June 2026 deadline.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Maven 4 requires --settings and its value on separate lines in
maven.config. The single-line format worked in Maven 3 but the
GitHub Actions runner has been updated to Maven 4.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents the POST /mcp endpoint: how to enable it, tool discovery,
tools/list and tools/call JSON-RPC examples, the java_call fallback,
type mapping table, and limitations. Adds a 2.11.19 release note entry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two chapters:
- Testing with bridgeService-data: start commands, concrete curl examples
  for initialize / tools/list / tools/call using real SimpleStaticMethods
  and ClassWithLogger methods, table of intentionally excluded tools.
- Exposing an external project: injection and aggregator deployment models,
  package config, tool naming convention illustrated with an example class.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Describes what each public static method actually does, its parameters,
and return value — making the methods self-documenting and suitable as
the basis for MCP tool descriptions in a follow-up step.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
At compile time, therapi-runtime-javadoc-scribe (added to bridgeService-data)
embeds Javadoc comments into the compiled JAR as classpath resources.
At runtime, MCPToolDiscovery reads them via RuntimeJavadoc.getJavadoc(method)
to populate tool descriptions and @param text for parameter descriptions,
falling back to the generated "Calls ClassName.method()" string when no
Javadoc is present.

External projects exposing their own methods as MCP tools need to add
therapi-runtime-javadoc-scribe to their build (see docs/MCP.md).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Explains that adding therapi-runtime-javadoc-scribe with provided scope
is all that's needed — the existing mvn clean package automatically embeds
Javadoc during compilation. BridgeService reads it transparently at startup.
Tools remain functional without the dependency; only description quality differs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both unit (MCPToolDiscoveryTest) and integration (MCPBridgeServerTest) tests
now verify that the description for SimpleStaticMethods_methodReturningString
contains "success string" — confirming that therapi-runtime-javadoc is
reading the embedded Javadoc rather than falling back to the generated string.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All tools/list response examples now show actual Javadoc text rather than
the fallback "Calls ClassName.method()" strings. Parameter descriptions
also reflect @param Javadoc tags. The EmailService example in the external
project section shows the before/after contrast explicitly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents how to register a running BridgeService instance as an HTTP MCP
server in Claude Code: start command, claude mcp add syntax (global and
project-scoped), resulting JSON config, verification with claude mcp list,
and how to remove the registration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Only methods with a non-empty Javadoc comment are exposed as MCP tools
by default (IBS.MCP.REQUIRE_JAVADOC=true). This prevents generic fallback
descriptions ("Calls ClassName.method()") from reaching MCP clients, which
would give agents no useful signal about when to invoke a tool.

Adds hasJavadoc(Method) helper in MCPToolDiscovery and wires the gate into
both branches of discoverTools(). Set IBS.MCP.REQUIRE_JAVADOC=false to
expose all public static methods regardless of documentation.

docs/MCP.md gains two new sections: a Javadoc quality gate guide with
before/after description examples, and a "Naming your MCP server" section
explaining that the client-side registration name determines the tool
namespace (mcp__<name>__...) and should reflect the project, not the
generic "bridgeService" default.

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

Replace OSSRH endpoints in distributionManagement (pom.xml) and the CI
settings profile (.github/workflows/settings.xml) with the OSSRH staging
API compatibility layer on central.sonatype.com.

oss.sonatype.org access is being retired; the new host is
ossrh-staging-api.central.sonatype.com which mirrors the legacy staging
API surface. No plugin changes are needed since this project uses the
standard maven-release-plugin + maven-deploy-plugin flow.

NOTE: the SONATYPE_USERNAME and SONATYPE_PASSWORD GitHub secrets must be
rotated to a User Token generated on central.sonatype.com — tokens from
oss.sonatype.org will return 401.

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

Adding Javadoc to SimpleStaticMethods shifted methodThrowsException from
line 67 to line 125. Update the assertion to match the new line number.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces mutable tags with immutable commit SHAs to prevent supply chain
attacks where a tag could be silently moved to a different commit.

- sonarsource/sonarqube-quality-gate-action@master → @cb3ed20
- codecov/codecov-action@v4 → @b9fd7d1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New milestone: MCP tool exposure with Javadoc quality gate. Version
scheme is MAJOR.JAVA_COMPAT.PATCH — middle segment stays at 11 (Java 11
compatibility); Java version decoupling is a future task.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Central no longer hosts snapshots at ossrh-staging-api; the correct
endpoint is central.sonatype.com/repository/maven-snapshots/.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- IBS.MCP.PRECHAIN: new config to prepend auth/setup call-chain entries
  before every auto-discovered tool invocation; prechain keys are stripped
  from the response and secret headers are resolved via the standard
  dependency mechanism
- Error responses from MCP tool calls now return a full ErrorObject JSON
  (title, code, detail, originalException, originalMessage, failureAtStep)
  matching the /call endpoint, instead of a bare exception string
- handleJavaCall unwraps callContent when an MCP client serialises it as
  a JSON string rather than a nested object
- Request headers forwarded to discovered-tool invocations so ibs-secret-*
  secrets are available to prechain steps
- 15 new integration tests covering all of the above

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
HTTP headers whose name starts with the configured prefix (default
ibs-env-) are extracted and injected as environment variables for
every MCP tool call — both auto-discovered tools and java_call.
The prefix is stripped and the variable name is uppercased to
handle HTTP/1.1 header case normalization.

Configurable via IBS.MCP.ENV.HEADER.PREFIX. Documented in docs/MCP.md
with a .claude.json example.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The __ibs_mcp_env__ synthetic re-injection step was added defensively
in case a prechain step wiped the env var cache. Analysis of the actual
Campaign prechain (setCurrentAuthenticationToLocal) confirmed it never
calls setIntegroCache, so the re-injection is unnecessary. Remove the
step, the supporting clearIntegroCache test helper, and the test that
validated the now-removed behaviour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PRECHAIN entries are now prepended to the callContent of every java_call
invocation, consistent with auto-discovered tool behaviour. User steps can
reference the PRECHAIN key (e.g. "ibs_auth") to receive its return value by
reference. PRECHAIN keys are stripped from returnValues and callDurations
before the result is returned.

Tests updated and extended: the old negative test (PRECHAIN not applied) is
replaced by a positive test verifying PRECHAIN is applied and stripped, plus
two new tests covering key-reference chaining and complex-object pass-by-
reference through the full MCP HTTP layer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ion, and centralized error mapping

- ibs-env-* headers now inject environment variables into the Java
  execution context without touching the call payload; prefix is stripped
  and the key uppercased before injection (IBS.ENV.HEADER.PREFIX config)
- IBS.HEADERS.FILTER.PREFIX config added to restrict which plain headers
  enter the call-chain arg cache
- CallContent.coerceArg() extracted from castArgs(); adds String to
  int/long/double/float/boolean coercion so MCP/REST clients can pass
  numeric args as JSON strings without ambiguity
- BridgeServiceFactory.createExceptionPayLoad(Exception) centralises the
  exception-to-HTTP-code mapping used by both /call and /mcp endpoints
- README and docs/MCP.md updated to document the new header mechanisms

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Maven filtering substitutes ${project.version} at build time so that
ConfigValueHandlerIBS.readVersion() can return the correct version
string at runtime instead of "unknown".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ibs_diagnostics: built-in MCP tool (no HOST dependency) that reports IBS
  version, deployment mode, MCP config state, and header classification
  (secret key names, decoded env-var headers, regular header count)
- ibs-prechain header: client-side alternative to IBS.MCP.PRECHAIN env var;
  used when the env var is absent, enabling per-client prechain config
- docs/MCP.md: document both features including diagnostics response fields
  and ibs-prechain header configuration example

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

- Best Practices chapter: Javadoc quality principle (garbage in, garbage out)
  with before/after examples and guidance on what every exposed method needs
- MCP Configuration Reference table: IBS.MCP.ENABLED, IBS.MCP.PRECHAIN,
  IBS.MCP.REQUIRE_JAVADOC with defaults in one place
- Cursor connection section with full config example
- Generic Other MCP clients section with connection requirements table
- Fix TOC misalignment: Connecting to Claude Code sub-entries were listed
  under Best Practices

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

- New section: Passing secrets and environment variables in MCP client config
  covering ibs-secret-* and ibs-env-* with examples, key-difference table,
  and full registration example combining all header types
- Explicit callout that ibs-env- prefix is stripped before injection —
  ibs-env-AC.UITEST.HOST becomes AC.UITEST.HOST, not IBS-ENV-AC.UITEST.HOST

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
in_ for method parameters, l_ for local variables, lt_ for block-scoped
variables, no prefix for for-loop counters.

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

@baubakg baubakg merged commit 3c49212 into main Apr 16, 2026
7 checks passed
@baubakg baubakg deleted the mcp branch April 16, 2026 19:28
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