https://github.com/kpavlov/tachyon
💫 Tachyon MCP Runtime for JVM - a Java Model Context Protocol server with Streamable HTTP, native Netty transports, tasks, resources, prompts, resumable sessions, and stateless deployment support.
https://github.com/kpavlov/tachyon
ai ai-agent-tools ai-agents ai-agents-mcp java java-21 java-25 java-26 llm-tools mcp model-context-protocol netty server
Last synced: about 4 hours ago
JSON representation
💫 Tachyon MCP Runtime for JVM - a Java Model Context Protocol server with Streamable HTTP, native Netty transports, tasks, resources, prompts, resumable sessions, and stateless deployment support.
- Host: GitHub
- URL: https://github.com/kpavlov/tachyon
- Owner: kpavlov
- License: apache-2.0
- Created: 2026-06-15T16:59:19.000Z (18 days ago)
- Default Branch: main
- Last Pushed: 2026-07-02T00:13:43.000Z (1 day ago)
- Last Synced: 2026-07-02T01:23:33.060Z (1 day ago)
- Topics: ai, ai-agent-tools, ai-agents, ai-agents-mcp, java, java-21, java-25, java-26, llm-tools, mcp, model-context-protocol, netty, server
- Language: Java
- Homepage: https://deepwiki.com/kpavlov/tachyon
- Size: 645 KB
- Stars: 21
- Watchers: 0
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Notice: NOTICE
- Agents: AGENTS.md
Awesome Lists containing this project
- awesome-java - Tachyon
README
[](https://repo1.maven.org/maven2/dev/tachyonmcp/tachyon-server/)
[](http://java.com)
[](https://github.com/kpavlov/tachyon/actions/workflows/build.yml)
[](https://github.com/modelcontextprotocol/conformance)
[](https://codecov.io/gh/kpavlov/tachyon)
[](https://deepwiki.com/kpavlov/tachyon)
**Tachyon MCP** is a Java 21 [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server built on [Netty](https://netty.io). Implements the **2025-11-25** Streamable HTTP transport, protocol extensions, and stateless mode.
**TL;DR**
1. Add dependency:
```xml
dev.tachyonmcp
tachyon-server
1.0.0-beta.3
```
2. Create MCP server:
```java
import dev.tachyonmcp.server.TachyonServer;
import dev.tachyonmcp.server.features.tools.AbstractSyncToolHandler;
import dev.tachyonmcp.server.features.tools.ToolArgs;
import dev.tachyonmcp.server.features.tools.ToolDescriptor;
import dev.tachyonmcp.server.features.tools.ToolResult;
import dev.tachyonmcp.server.session.McpContext;
import tools.jackson.databind.node.JsonNodeFactory;
void main() {
var schema = JsonNodeFactory.instance.objectNode();
schema.put("type", "object");
schema.putObject("properties").putObject("city").put("type", "string");
TachyonServer.builder()
.name("weather-mcp")
.tool(new AbstractSyncToolHandler(
ToolDescriptor.builder("get_forecast")
.description("Get weather forecast")
.inputSchema(schema)
.build()) {
@Override
public ToolResult handle(McpContext ctx, ToolArgs args) {
return ToolResult.text("☀️ 22°C");
}
})
.session(cfg -> cfg.stateless(true))
.port(8080)
.start();
}
```
## Documentation
| Guide | Description |
|---|---|
| [Quickstart](docs/quickstart.md) | Build a working server in 5 minutes |
| [Tools](docs/tools.md) | Sync/async handlers, input schema, `ToolResult` |
| [Resources](docs/resources.md) | Static URIs, dynamic handlers, URI templates |
| [Tasks](docs/tasks.md) | Long-running operations, state machine, `TasksExtension` |
| [Extensions](docs/extensions.md) | Custom protocol extensions, negotiation |
| [Kotlin DSL](docs/kotlin.md) | Coroutine-first DSL, `TachyonServer { }`, scope reference |
| [Kotlin module](tachyon-server-kotlin/README.md) | `tachyon-server-kotlin` module overview |
## Agent Skill
Add agent skill to write better code using this SDK:
```shell
npx skills add kpavlov/tachyon --skill tachyon-mcp
```
The skill includes compilable Java and Kotlin example sources under `.agents/skills/tachyon-mcp/resources/`.
They are linked into `e2e/src/skill/` and compiled during `mvn test` to keep them valid.
Check out [Skills CLI](https://github.com/vercel-labs/skills) for more options.
## Features
### Core Protocol (46/46 conformance tests passing)
- JSON-RPC 2.0 — request/response/error/notification
- Streamable HTTP — POST, GET (SSE), DELETE, OPTIONS
- Lifecycle — initialize → initialized → ACTIVE
- Pagination — cursor-based across all list methods
- Session state machine — INITIALIZING → ACTIVE → CLOSED
- CORS & origin validation
- DNS rebinding protection
- Accept header strict validation (406)
- Pending request timeout (60s)
- Extensions ([SEP-2133](https://modelcontextprotocol.io/seps/2133-extensions))
### Tools
- `tools/list` — paginated with `nextCursor`
- `tools/call` — returns `CallToolResult` with `isError`
- `outputSchema` in listing
- `annotations` field
- `execution.taskSupport` (forbidden/optional/required)
- Synchronous & asynchronous handler interfaces
- Tool name validation ([SEP-986](https://modelcontextprotocol.io/seps/986-specify-format-for-tool-names))
- `notifications/tools/list_changed` on add/remove
- Inline notifications + logging during tool call
- Input JSON Schema 2020-12 validation ([SEP-1613](https://modelcontextprotocol.io/seps/1613-establish-json-schema-2020-12-as-default-dialect-f))
### Resources
- `resources/list` — paginated
- `resources/read` — text & blob content
- `resources/templates/list` — URI templates
- `resources/subscribe` / `unsubscribe`
- `notifications/resources/list_changed`
- `notifications/resources/updated` to subscribers
- Dynamic content via `ResourceHandler` interface
### Prompts
- `prompts/list` — paginated with `nextCursor`
- `prompts/get` — invokes prompt resolver
- `notifications/prompts/list_changed`
### Tasks
- `tasks/list`, `tasks/get`, `tasks/cancel`, `tasks/result`
- State machine enforcement — SUBMITTED → WORKING → INPUT_REQUIRED → COMPLETED/FAILED/CANCELLED, plus REJECTED/AUTH_REQUIRED
- `notifications/tasks/status` broadcast on every transition
- Task Janitor for stale tasks
- `execution.taskSupport` per tool (forbidden/optional/required)
- `TasksExtension` ([SEP-1686](https://modelcontextprotocol.io/seps/1686-tasks)) — negotiable extension exposing `create_task` tool + `task://{id}` resource template
- Extension-gated tool visibility (hidden from un-negotiated clients)
### Logging & Observability
- `logging/setLevel` per session
- `notifications/message` emitted above threshold
- Progress notifications
### Client Communication
- `sampling/createMessage` — server → client request
- Elicitation — ✅ form mode; ❌ url mode
- `notifications/cancelled` — bidirectional
- `notifications/tasks/status` from client
### Transport & I/O
- Netty 4.2
- io_uring / epoll / kqueue / nio auto-detection
- Platform-thread event loops + virtual-thread handlers
- TCP_NODELAY, SO_KEEPALIVE
- Channel writability backpressure (`setAutoRead`)
- Configurable idle timeouts (reader/writer)
### Session Management
- SSE resumability via Last-Event-ID
- **Stateless mode** — skip sessions for serverless
- IN_MEMORY session store (ConcurrentHashMap)
- Session Janitor — 5s sweep, 30s TTL
- SSE disconnect ≠ session removal (supports reconnect)
- Event log replay on reconnection
---
## Installation
**Requirements**: JDK 21+
### Build from source
```bash
git clone https://github.com/kpavlov/tachyon.git
cd tachyon
mvn install -pl tachyon-server -DskipTests
```
## Quick Start
See [docs/quickstart.md](docs/quickstart.md) for a full walkthrough with Java and Kotlin examples, curl test, and next-step links.
### TasksExtension (SEP-1686)
```java
var handle = TachyonServer.builder()
.extension(TasksExtension.instance()) // exposes create_task tool + task://{id} resource
.port(8080)
.start();
```
Clients that include `"extensions": {"io.modelcontextprotocol/tasks": {}}` in their `initialize` capabilities receive the extension's tool and resource template. Clients that don't negotiate it see standard `tasks/*` methods. See [docs/tasks.md](docs/tasks.md).
### Protocol isolation
Handler interfaces (`ToolHandler`, `ResourceHandler`, `PromptHandler`) and descriptor types use stable domain types. When Tachyon upgrades to a new protocol version, only the internal mapper layer changes; handler implementations are unaffected. Domain types track the 2026-07-28 spec shape where it improves on 2025-11-25 (e.g. `Annotations.lastModified`, `ResourceLink` in `ContentBlock`).
## Performance
- **Native transports** — io_uring > epoll > kqueue > NIO auto-detect
- **Write buffer watermarks** — 32 KB low / 128 KB high, backpressure wired
- **Batch flushing** — `ctx.write()` accumulates, single `ctx.flush()` on boundary
- **Minimal allocations** — `McpEndpointHandler` is `@Sharable`, no per-request handler creation
- **Virtual threads** — handlers offloaded from event loop, no manual thread pools
- **JSON-RPC** — Jackson streaming codec, no ObjectMapper.
## Gaps & Limitations
- [ ] **Rate limiting** — Not yet implemented
- [ ] **2026-07-28 draft protocol version** — High priority
- [ ] **Stale session on re-initialize** — 30s TTL lingering, affects reconnect only
---
## FAQ
### Can I deploy to AWS Lambda?
Yes. Use `.session(cfg -> cfg.stateless(true))` to skip session persistence. Each invocation processes one request independently.
### Does it support HTTP/2?
Not yet. The current transport targets HTTP/1.1.
### How do I write a tool?
See [docs/tools.md](docs/tools.md) — covers lambda and class-based handlers, input schema, and `ToolResult` factories.
### How do I expose a resource?
See [docs/resources.md](docs/resources.md) — covers static URIs, dynamic handlers, URI templates, and subscriptions.
## License
**Tachyon MCP** is available under the terms of the [Apache 2.0](LICENSE).