tachyon
Health Uyari
- License รขโฌโ License: Apache-2.0
- Description รขโฌโ Repository has a description
- Active repo รขโฌโ Last push 0 days ago
- Low visibility รขโฌโ Only 5 GitHub stars
Code Gecti
- Code scan รขโฌโ Scanned 6 files during light audit, no dangerous patterns found
Permissions Gecti
- Permissions รขโฌโ No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
๐ซ Modern MCP Runtime for JVM
Tachyon MCP โ A Java 25 Model Context Protocol (MCP) server built on Netty 4.2.
Fully implements MCP spec 2025-11-25 Streamable HTTP transport, session lifecycle, native I/O transports, and a stateless mode for serverless deployments.
TL;DR
import dev.tachyonmcp.server.TachyonMcpServer;
import dev.tachyonmcp.server.features.tools.AbstractSyncToolHandler;
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");
TachyonMcpServer.builder()
.name("weather-mcp")
.tool(new AbstractSyncToolHandler(
ToolDescriptor.builder("get_forecast")
.description("Get weather forecast")
.inputSchema(schema)
.build()) {
@Override
public Object handle(McpContext ctx, Object args) {
return ToolResult.text("โ๏ธ 22ยฐC");
}
})
.stateless(true)
.port(8080)
.bind();
}
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)
- SSE resumability via Last-Event-ID
โ Tools
-
tools/listโ paginated withnextCursor -
tools/callโ returnsCallToolResultwithisError -
outputSchemain listing -
annotationsfield -
execution.taskSupport(forbidden/optional/required) - Synchronous & asynchronous handler interfaces
- Name validation (1โ128 chars)
-
notifications/tools/list_changedon add/remove - Inline notifications + logging during tool call
โ Resources
-
resources/listโ paginated -
resources/readโ text & blob content -
resources/templates/listโ URI templates -
resources/subscribe/unsubscribe -
notifications/resources/list_changed -
notifications/resources/updatedto subscribers - Dynamic content via
ResourceHandlerinterface
โ Prompts
-
prompts/listโ paginated withnextCursor -
prompts/getโ invokes prompt resolver -
notifications/prompts/list_changed
โ Tasks
-
tasks/list,tasks/get,tasks/cancel,tasks/result - State machine enforcement โ SUBMITTED โ WORKING โ COMPLETED/FAILED/CANCELLED
-
notifications/tasks/statusbroadcast on every transition - Task Janitor for stale tasks
-
execution.taskSupportper tool (forbidden/optional/required) -
TasksExtensionโ negotiable extension exposingcreate_tasktool +task://{id}resource template - Extension-gated tool visibility (hidden from un-negotiated clients)
โ Logging & Observability
-
logging/setLevelper session -
notifications/messageemitted above threshold - Progress notifications
โ Client Communication
-
sampling/createMessageโ server โ client request - Elicitation โ form mode
-
notifications/cancelledโ bidirectional -
notifications/tasks/statusfrom 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
- 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 25+
Maven
<dependency>
<groupId>dev.tachyonmcp</groupId>
<artifactId>tachyon-server</artifactId>
<version>1.0.0-alpha.1</version>
</dependency>
Build from source
git clone https://github.com/kpavlov/tachyon.git
cd tachyon
mvn install -pl tachyon-mcp-server -DskipTests
Quick Start
Minimal server with tool
import dev.tachyonmcp.server.TachyonMcpServer;
import dev.tachyonmcp.server.features.tools.AbstractSyncToolHandler;
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");
TachyonMcpServer.builder()
.name("weather-mcp")
.tool(new AbstractSyncToolHandler(
ToolDescriptor.builder("get_forecast")
.description("Get weather forecast")
.inputSchema(schema)
.build()) {
@Override
public Object handle(McpContext ctx, Object args) {
return ToolResult.text("โ๏ธ 22ยฐC");
}
})
.stateless(true) // start in stateless node (no sessions)
.port(8080) // bind to 1270.0.1:8080
.bind();
}
With TasksExtension (negotiable)
var handle = TachyonMcpServer.builder()
.extension(new TasksExtension()) // exposes create_task tool + task://{id} resource
.port(8080)
.bind();
Clients that include "extensions": {"io.modelcontextprotocol/tasks": {}} in theirinitialize capabilities receive the extension's tool and resource template.
Clients that don't negotiate the extension see standard MCP tasks via tasks/list / tasks/get.
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, singlectx.flush()on boundary - Minimal allocations โ
McpEndpointHandleris@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 (Medium) โ Not yet implemented
- URL elicitation mode / -32042 error (Medium) โ Form mode works, URL mode missing
- 2026-07-28 draft protocol version (Low) โ Not negotiable; version-gated features ready
- Stale session on re-initialize (Low) โ 30s TTL lingering, affects reconnect only
FAQ
Can I deploy to AWS Lambda?
Yes. Use stateless(true) to skip session persistence. Each invocation processes one request independently.
Does it support HTTP/2?
Not yet. The current pipeline targets HTTP/1.1; HTTP/2 upgrade is a pipeline configuration change comming soon.
How do I write a custom tool?
Extend AbstractSyncToolHandler or AbstractAsyncToolHandler, passing a ToolDescriptor:
class MyTool extends AbstractSyncToolHandler {
MyTool() {
super(ToolDescriptor.builder("my_tool")
.description("Does something useful")
.inputSchema(buildSchema())
.build());
}
@Override
public Object handle(McpContext ctx, Object args) throws Exception {
return CallToolResult.ofText("done");
}
private static JsonNode buildSchema() {
var s = JsonNodeFactory.instance.objectNode();
s.put("type", "object");
return s;
}
}
How do I implement a custom resource?
server.resources().add(
ResourceDescriptor.of("custom://data"),
(ctx, req) -> new TextResourceContents("content", req.uri(), "text/plain", null));
License
Tachyon MCP is available under the terms of the Apache 2.0.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi