An open API service indexing awesome lists of open source software.

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.

Awesome Lists containing this project

README

          


[![Maven Central](https://img.shields.io/maven-central/v/dev.tachyonmcp/tachyon-server)](https://repo1.maven.org/maven2/dev/tachyonmcp/tachyon-server/)
[![Java 21+](https://img.shields.io/badge/Java-21+-orange.svg?logo=jvm)](http://java.com)
[![Build](https://github.com/kpavlov/tachyon/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/kpavlov/tachyon/actions/workflows/build.yml)
[![Conformance: v0.1.16](https://img.shields.io/badge/Conformance-v0.1.16-green?logo=modelcontextprotocol)](https://github.com/modelcontextprotocol/conformance)
[![codecov](https://codecov.io/gh/kpavlov/tachyon/graph/badge.svg?token=WUMD9A8T2T)](https://codecov.io/gh/kpavlov/tachyon)

[![Ask DeepWiki](https://deepwiki.com/badge.svg)](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).