feat(ext-mcp): add MCP (Model Context Protocol) server extension
CI / Build & Test (push) Failing after 4m57s
CI / Build & Test (push) Failing after 4m57s
Streamable HTTP transport (JSON-RPC 2.0 over POST), one-class-per-tool/resource/prompt API mirroring RequestHandler, boot-time-precompiled schema/list payloads for a zero-alloc hot path, and optional OAuth2 protection built on flash-ext-oidc (lazy-loaded, RFC 8707 audience binding, RFC 9728 Protected Resource Metadata). Registers the module in the root and flash-extensions POMs and adds the ext-mcp commit scope to AGENTS.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
8ece9975de
commit
d7f36a7aea
@@ -0,0 +1,56 @@
|
||||
# flash-ext-mcp
|
||||
|
||||
`flash-ext-mcp` turns a Flash5 app into an [MCP](https://modelcontextprotocol.io) (Model Context
|
||||
Protocol) server: JSON-RPC 2.0 over the Streamable HTTP transport, tools/resources/prompts
|
||||
declared as plain classes and discovered at boot, optional OAuth2 protection built on
|
||||
`flash-ext-oidc`.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```java
|
||||
FlashApp.create(8080)
|
||||
.install(new McpExtension(McpConfig.builder("my-mcp-server")
|
||||
.toolsPackage("com.example.tools")
|
||||
.build()))
|
||||
.start();
|
||||
```
|
||||
|
||||
```java
|
||||
@Tool(name = "get_weather", description = "Get current weather for a city",
|
||||
args = @ToolArg(name = "city", description = "City name", required = true))
|
||||
public class GetWeatherTool extends McpTool {
|
||||
|
||||
private WeatherService weatherService;
|
||||
|
||||
@Override
|
||||
protected void onInit() {
|
||||
weatherService = require(WeatherService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToolResponse call(ToolArguments args) {
|
||||
return ToolResponse.success(new TextContent(weatherService.fetch(args.getString("city"))));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Operating Model
|
||||
|
||||
- **One class per tool/resource/prompt** — mirrors `RequestHandler`: a no-arg constructor,
|
||||
`onInit()` to cache services from `FlashContext`, one hot-path method
|
||||
(`call`/`read`/`render`). No CDI, no field injection, no reflection on the hot path.
|
||||
- **Boot-time precompilation** — `tools/list`/`resources/list`/`prompts/list` JSON payloads
|
||||
(including JSON Schema) are built once at boot and spliced verbatim into responses. See
|
||||
`tools-resources-prompts.md`.
|
||||
- **Transport**: Streamable HTTP, `POST`-only, stateless in this revision — see `transport.md`
|
||||
for exactly what that means and why.
|
||||
- **Security**: optional, policy-driven OAuth2 via `flash-ext-oidc` — see `security.md`.
|
||||
- **JSON**: this extension owns its JSON handling independently of `flash-ext-jackson` — see
|
||||
`jackson-interop.md` for why, and how a future opt-in reuse could work.
|
||||
|
||||
## Documents
|
||||
|
||||
- [`tools-resources-prompts.md`](tools-resources-prompts.md) — defining tools, resources, prompts
|
||||
- [`transport.md`](transport.md) — Streamable HTTP scope, session/SSE limitations, Origin validation
|
||||
- [`security.md`](security.md) — `McpSecurity` policy, OAuth2 resolution, RFC 9728 / RFC 8707
|
||||
- [`jackson-interop.md`](jackson-interop.md) — why this extension does not depend on `flash-ext-jackson`
|
||||
Reference in New Issue
Block a user