Tachyon MCP 1.0 is officially live!
I originally built Tachyon because I needed a clean way to expose services from my JVM applications to AI agents. It runs on Java 21+, serves MCP over Streamable HTTP, and fully supports both the 2025-11-25 and 2026-07-28 MCP specifications. Under the hood, the core API is written in Java, but it comes with a first-class Kotlin DSL for suspending handlers.
Tachyon is already out in the wild powering agents over at Kerno.io. It also serves as the reference test backend for James Ward’s zio-http-mcp library: its interoperability tests validate client behavior against Tachyon using both protocol versions to ensure everything works flawlessly.
Why I built it
I wanted a rock-solid foundation for running AI agents inside Kotlin applications. Naturally, I started with the official Kotlin SDK, but I hit a few roadblocks for my specific use case.
First, I needed to support the latest MCP protocol updates while keeping backward compatibility with MCP 2025-11-25. Crucially, I wanted both versions to map to the exact same application code. That requirement pushed me to build Tachyon from the ground up, keeping the protocol mapping completely separate from the actual tool, resource, and prompt handlers.
Second, I wanted a lightweight way to add MCP support to existing apps without being forced to drag in frameworks like Spring or Quarkus just to existing project. Tachyon can run completely standalone or spin up and down right alongside your host application.
For the tech stack, I chose Netty for high-performance transport and Jackson for JSON handling. Writing the core API in Java kept it universally accessible, while the Kotlin adapters bring native support for suspending handlers and a clean DSL.
A quick Java tool example
Here is all the code you need to spin up a complete Java server with a single tool:
1import dev.tachyonmcp.api.annotations.McpTool;
2import dev.tachyonmcp.core.server.TachyonServer;
3
4public final class GreetingServer {
5 public static final class GreetingService {
6 @McpTool(description = "Say hello to someone")
7 public String greet(String name) {
8 return "Hello, " + name + "!";
9 }
10 }
11
12 public static void main(String[] args) {
13 var server = TachyonServer.builder()
14 .name("greeting-server")
15 .annotations(a -> a.register(new GreetingService()))
16 .host("127.0.0.1")
17 .port(8080)
18 .build();
19
20 Runtime.getRuntime().addShutdownHook(new Thread(server::close));
21 server.start();
22 }
23}Tachyon automatically figures out the input schema right from the method signature and handles converting the returned string into MCP text content. Just make sure to compile with the -parameters flag so the argument names are preserved. If you want to take it for a spin, the quickstart guide walks through Maven and Gradle setups, plus how to test it using curl or the MCP Inspector.
To keep things fast, synchronous handlers run on virtual threads rather than blocking Netty’s event loop. This means your tools can safely call blocking database drivers or HTTP clients using standard Java control flow. If your dependencies return a CompletionStage, you can use the async API, and if you are using Kotlin, you can just use native suspending functions.
You can also use Records to define your tool arguments and results. Tachyon infers their schemas and handles structured output automatically, falling back to JSON text if needed. If annotations aren’t your style, you can also register tools programmatically.
Handling multiple protocol versions
The two supported versions of MCP handle interactions quite differently. MCP 2025-11-25 relies on an initial handshake. By contrast, the newer 2026-07-28 version requires every single request to carry its protocol version and client capabilities, relying on server/discover for discovery. You can read more about the reasoning behind this shift in SEP-2575: Make MCP Stateless.
There is also SEP-2243: HTTP Header Standardization, which introduces standard routing headers so API gateways can inspect the method and target without having to parse the heavy request body.
Tachyon’s protocol mappers abstract all of these differences away. The exact same tool, resource, or prompt handler serves both versions without any extra work on your end. The runtime successfully passes the official MCP conformance suites for both versions, and it runs on every commit to make sure everything stays compliant.
Long-running tasks
Real-world workflows—like generating complex reports or running multi-step booking processes—often outlive the single request that triggered them. Sometimes, they even need to pause and wait for more user input before they can cross the finish line.
Tachyon’s Tasks extension implements SEP-2663: Tasks Extension, while staying fully compatible with the older SEP-1686: Tasks behavior used by 2025-11-25 clients.
The actual execution lives inside your application or workflow engine. You just implement a TaskConnector to handle lookups, cancellations, and new inputs, and Tachyon takes care of the rest—protocol mapping, caching task snapshots, and pushing out notifications.
When a tool kicks off a job, it immediately returns a snapshot. Later, tasks/get calls query your connector for the absolute source of truth, and callbacks can push real-time updates to the client. Crucially, if a client disconnects, the background task keeps running uninterrupted.
By keeping execution decoupled from the runtime, you can easily plug in your existing job queues. Check out the Temporal example in the repo to see how to expose durable, distributed workflows this way.
Agent Skills
If you want an agent to use your tools effectively, it needs to understand the context—like the specific rules or steps required to book an appointment. SEP-2640: Skills Extension is now Final, defining how to serve Agent Skills over MCP using standard resources.
Tachyon’s Skills extension makes it easy to serve these packages, bundle them with a SKILL.md, scripts, and reference docs. You can load these packages straight from the filesystem or the classpath (even tucked away inside a JAR). Files are exposed via skill:// resources, and clients can discover and navigate them using skills/list, skills/get, and resources/directory/read.
Both tasks and skills are built on top of Tachyon’s core extension API, which implements SEP-2133: Extensions. You can use this exact same API to build your own custom extensions, register new methods, and advertise custom capabilities.
I have also included a dedicated coding-agent skill in the repo to help agents write Tachyon servers for you:
1npx skills add tachyonmcp/tachyon --skill tachyon-mcpDeployment and testing
By default, the server is completely stateless. However, if you need resumable SSE streams and Last-Event-ID replay, you can easily enable sessions. While you can use durable stores to handle recovery after a restart, active sessions are kept in-memory, meaning you’ll need sticky routing to ensure requests for an active session hit the correct instance.
Take a look at the configuration guide for details on tuning sessions, handling SSE backpressure, managing graceful shutdowns, and setting up security features like Origin checks, DNS-rebinding protection, and request limits. It also uses Jackson 3 for JSON parsing out of the box, but you can plug in your own serializer if needed.
We also have optional modules to help you integrate with your existing setup:
- Spring Boot: Automatically scans for annotated beans and hooks into the standard application lifecycle.
- Annotation adapters: Lets you reuse services you’ve already written for mcp-java, LangChain4j, or Spring AI.
- OpenTelemetry: Tracks MCP spans and execution metrics (capturing arguments and results is opt-in for privacy).
- Testkit: Binds servers to random free ports in your tests and gives you protocol clients with clean JSON-RPC assertions.
Every single Java and Kotlin code snippet in our documentation is compiled and verified by the test suite, and end-to-end tests cover all documented server behaviors.
Current status and docs
With the 1.0 release, Tachyon fully supports tools, resources, prompts, completions, subscriptions, progress tracking, and cancellations over Streamable HTTP. Note that HTTP/2 and authorization aren’t supported just yet.
Keep in mind that some APIs are still marked as @ExperimentalApi, meaning they could shift slightly in future releases as I gather more feedback.
You can find all the documentation at https://tachyonmcp.dev. The full source code, tests, and runnable examples are available in the GitHub repository under the Apache 2.0 license.
Go give Tachyon a try, I’d love to hear what you’re building and any friction points you run into. Opening an issue with a quick minimal reproduction code snippet is always incredibly helpful!
