tachyon

mcp
Guvenlik Denetimi
Uyari
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.

SUMMARY

๐Ÿ’ซ Modern MCP Runtime for JVM

README.md

Maven Central
Build
Conformance 46 of 46
Ask DeepWiki

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 with nextCursor
  • tools/call โ€” returns CallToolResult with isError
  • outputSchema in listing
  • annotations field
  • execution.taskSupport (forbidden/optional/required)
  • Synchronous & asynchronous handler interfaces
  • Name validation (1โ€“128 chars)
  • notifications/tools/list_changed on 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/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 โ†’ COMPLETED/FAILED/CANCELLED
  • notifications/tasks/status broadcast on every transition
  • Task Janitor for stale tasks
  • execution.taskSupport per tool (forbidden/optional/required)
  • TasksExtension โ€” 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
  • 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

  • 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 their
initialize 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, 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 (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)

Sonuc bulunamadi