Install
$ agentstack add mcp-soklet-soklet ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
[](https://central.sonatype.com/artifact/com.soklet/soklet) [](https://github.com/soklet/soklet/actions/workflows/ci.yml) [](https://javadoc.soklet.com) [](CHANGELOG.md)
What Is It?
A small HTTP/1.1 server and route handler for Java, well-suited for building RESTful APIs, broadcasting Server-Sent Events, and providing Model Context Protocol (MCP) functionality. Zero dependencies. Dependency Injection friendly. Optionally powered by JEP 444: Virtual Threads.
Soklet codes like a library, not a framework.
Note: this README provides a high-level overview of Soklet. For details, please refer to the official documentation at https://www.soklet.com.
Why?
The Java web ecosystem is missing an HTTP server solution that is dependency-free but offers support for [Server-Sent Events (SSE)](/docs/server-sent-events) and [Model Context Protocol (MCP)](/docs/mcp) along with hooks for dependency injection and annotation-based request handling. Soklet aims to fill this void.
Soklet provides the plumbing to build "transactional" REST APIs as well as agentic systems that vend results via HTTP response streaming or SSE, and expose tools, prompts, and resources via MCP. It does not make technology choices on your behalf (but an example of how to build a full-featured API is available). It does not natively support Reactive Programming or similar methodologies. It does give you the foundation to build your system, your way.
Soklet is commercially-friendly Open Source Software, proudly powering production systems since 2015.
Design Goals
- Main focus: routing HTTP/1.1 requests to Java methods
- Near-instant startup
- Zero dependencies
- Immutability/thread-safety
- Small, comprehensible codebase - auditable end-to-end by a human or AI agent
- No runtime classpath scanning or autoconfiguration (explicit behavior, statically analyzable)
- Contract/interface-driven: bring your own implementations for almost anything
- Thorough, high-quality documentation
- Extensive support for automated unit and integration testing
- Fine-grained telemetry and metrics collection
- Best-in-class support for Server-Sent Events
- First-class support for Model Context Protocol (MCP)
- Servlet Integration for legacy code
Design Non-Goals
- SSL/TLS (your load balancer should provide TLS termination)
- HTTP/2, HTTP/3 (also handled by your load balancer)
- WebSockets
- Dictate which technologies to use (Guice vs. Dagger, Gson vs. Jackson, etc.)
- "Batteries included" authentication and authorization
Do Zero-Dependency Libraries Interest You?
Similarly-flavored commercially-friendly OSS libraries are available.
- Pyranid - makes working with JDBC pleasant
- Lokalized - natural-sounding translations (i18n) via expression language
License
Installation
Soklet is a single JAR, available on Maven Central.
JDK 17+ is required (or JDK 21+ for Server-Sent Events and MCP).
Maven
com.soklet
soklet
3.4.0
Gradle
repositories {
mavenCentral()
}
dependencies {
implementation 'com.soklet:soklet:3.4.0'
}
Direct Download
If you don't use Maven or Gradle, you can drop soklet-3.4.0.jar directly into your project. No other dependencies are required.
Code Sample
Here we demonstrate building and running a single-file Soklet application with nothing but the soklet-3.4.0.jar and the JDK. There are no other libraries or frameworks, no Servlet container, no Maven or Gradle build process - no special setup is required.
Soklet systems can be structurally as simple as a "hello world" app.
While a real production system will have more moving parts, this demonstrates that you can build server software without ceremony or dependencies.
package com.soklet.example;
public class App {
// Canonical example
@GET("/")
public String index() {
return "Hello, world!";
}
// Echoes back the path parameter, which must be a LocalDate
@GET("/echo/{date}")
public LocalDate echo(@PathParameter LocalDate date) {
return date;
}
// Formats request body locale for display and customizes the response.
// Example: fr-CA ⇒ francês (Canadá)
@POST("/language")
public Response languageFor(@RequestBody Locale locale) {
Locale systemLocale = Locale.forLanguageTag("pt-BR");
String contentLanguage = systemLocale.toLanguageTag();
return Response.withStatusCode(200)
.body(locale.getDisplayName(systemLocale))
.headers(Map.of("Content-Language", Set.of(contentLanguage)))
.cookies(Set.of(
ResponseCookie.withName("lastRequest")
.value(Instant.now().toString())
.httpOnly(true)
.secure(true)
.maxAge(Duration.ofMinutes(5))
.sameSite(SameSite.LAX)
.build()
))
.build();
}
// Start the server and listen on :8080
public static void main(String[] args) throws Exception {
// Use out-of-the-box defaults
SokletConfig config = SokletConfig.withHttpServer(
HttpServer.fromPort(8080)
).build();
try (Soklet soklet = Soklet.fromConfig(config)) {
soklet.start();
System.out.println("Soklet started, press [enter] to exit");
soklet.awaitShutdown(ShutdownTrigger.ENTER_KEY);
}
}
}
Here we use raw javac to build and java to run.
This example requires JDK 17+ to be installed on your machine (or see this example of using Docker for Soklet apps). If you need a JDK, Amazon provides Corretto - a free-to-use-commercially, production-ready distribution of OpenJDK that includes long-term support.
Build
javac -parameters -cp soklet-3.4.0.jar -processor com.soklet.SokletProcessor -d build src/com/soklet/example/App.java
Run
java -cp soklet-3.4.0.jar:build com/soklet/example/App
Test
# Hello, world
% curl -i 'http://localhost:8080/'
HTTP/1.1 200 OK
Content-Length: 13
Content-Type: text/plain; charset=UTF-8
Date: Sun, 21 Mar 2024 16:19:01 GMT
Hello, world!
# Acceptable path parameter
% curl -i 'http://localhost:8080/echo/2024-12-31'
HTTP/1.1 200 OK
Content-Length: 10
Content-Type: text/plain; charset=UTF-8
Date: Sun, 21 Mar 2024 16:19:01 GMT
2024-12-31
# Illegal path parameter
% curl -i 'http://localhost:8080/echo/abc'
HTTP/1.1 400 Bad Request
Content-Length: 21
Content-Type: text/plain; charset=UTF-8
Date: Sun, 21 Mar 2024 16:19:01 GMT
HTTP 400: Bad Request
# Language request body
% curl -i -X POST 'http://localhost:8080/language' -d 'fr-CA'
HTTP/1.1 200 OK
Content-Language: pt-BR
Content-Length: 18
Content-Type: text/plain; charset=UTF-8
Date: Sun, 21 Mar 2024 16:19:01 GMT
Set-Cookie: lastRequest=2024-04-21T16:19:01.115336Z; Max-Age=300; Secure; HttpOnly; SameSite=Lax
francês (Canadá)
Building Real-World Apps
Of course, real-world apps have more moving parts than a "hello world" example.
The Toy Store App showcases how you might build a robust production system with Soklet.
Feature highlights include:
- Authentication and role-based authorization
- Basic CRUD operations
- Dependency injection via Google Guice
- Relational database integration via Pyranid
- Context-awareness via ScopedValue (JEP 481)
- Internationalization via the JDK and Lokalized
- JSON requests/responses via Gson
- Logging via SLF4J / Logback
- Metrics collection via
MetricsCollector - Automated unit and integration tests via JUnit
- Ability to run in Docker
What Else Does It Do?
Request Handling
Soklet maps HTTP requests to plain Java methods known as Resource Methods (ResourceMethod). Annotate them with @GET, @POST, @PUT, @PATCH, @DELETE, @HEAD, @OPTIONS, or @SseEventSource for SSE. MCP endpoints are declared separately with @McpServerEndpoint and handler annotations like @McpTool, @McpPrompt, and @McpResource. Soklet discovers them at compile time via the SokletProcessor annotation processor, avoiding classpath scans at startup. See the Request Handling docs for details.
Access To Request Data
Resource Methods (ResourceMethod) can accept a Request parameter and inspect HttpMethod values.
@GET("/example")
public void example(Request request /* param name is arbitrary */) {
// Here, it would be HttpMethod.GET
HttpMethod httpMethod = request.getHttpMethod();
// Just the path, e.g. "/example"
String path = request.getPath();
// The raw path and query, e.g. "/example?test=123"
String rawPathAndQuery = request.getRawPathAndQuery();
// Request body as bytes, if available
Optional body = request.getBody();
// Request body marshaled to a string, if available.
// Charset defined in "Content-Type" header is used to marshal.
// If not specified, UTF-8 is assumed
Optional bodyAsString = request.getBodyAsString();
// Query parameter values by name
Map> queryParameters = request.getQueryParameters();
// Shorthand for plucking the first query param value by name
Optional queryParameter = request.getQueryParameter("test");
// Header values by name (names are case-insensitive)
Map> headers = request.getHeaders();
// Shorthand for plucking the first header value by name (case-insensitive)
Optional header = request.getHeader("Accept-Language");
// Parsed W3C trace context from traceparent/tracestate, if present
Optional traceContext = request.getTraceContext();
// Request cookies by name (names are case-insensitive)
Map> cookies = request.getCookies();
// Shorthand for plucking the first cookie value by name (case-insensitive)
Optional cookie = request.getCookie("cookie-name");
// Form parameters by name (application/x-www-form-urlencoded)
Map> fps = request.getFormParameters();
// Shorthand for plucking the first form parameter value by name
Optional fp = request.getFormParameter("fp-name");
// Is this a multipart request?
boolean multipart = request.isMultipart();
// Multipart fields by name
Map> mpfs = request.getMultipartFields();
// Shorthand for plucking the first multipart field by name
Optional mpf = request.getMultipartField("file-input");
// CORS information, if available
Optional cors = request.getCors();
// Ordered locales via Accept-Language parsing
List locales = request.getLocales();
// Charset as specified by "Content-Type" header, if available
Optional charset = request.getCharset();
// Content type component of "Content-Type" header, if available
Optional contentType = request.getContentType();
}
Value Conversions
Soklet converts textual request inputs to Java types using a ValueConverterRegistry populated with ValueConverter. Conversions are applied to parameters annotated with @QueryParameter, @PathParameter, @RequestHeader, @RequestCookie, @FormParameter, and @Multipart. Supply your own registry (or additional converters) via SokletConfig to support custom types.
Request Body Parsing
Configure a RequestBodyMarshaler however you like - here we accept JSON:
SokletConfig config = SokletConfig.withHttpServer(
HttpServer.fromPort(8080)
).requestBodyMarshaler(new RequestBodyMarshaler() {
// This example uses Google's GSON
static final Gson GSON = new Gson();
@NonNull
@Override
public Optional marshalRequestBody(
@NonNull Request request,
@NonNull ResourceMethod resourceMethod,
@NonNull Parameter parameter,
@NonNull Type requestBodyType
) {
// Let GSON turn the request body into an instance
// of the specified type.
//
// Note that this method has access to all runtime information
// about the request, which provides the opportunity to, for example,
// examine annotations on the method/parameter which might
// inform custom marshaling strategies.
return Optional.of(GSON.fromJson(
request.getBodyAsString().orElseThrow(),
requestBodyType
));
}
}).build();
Then, apply:
public record Employee (
UUID id,
String name
) {}
// Accepts a JSON-formatted Record type as input
@POST("/employees")
public void createEmployee(@RequestBody Employee employee) {
System.out.printf("TODO: create %s\n", employee.name());
}
Response Writing
To control how response data is surfaced to clients (e.g. JSON), provide handler functions (ResourceMethodHandler and ThrowableHandler) to Soklet as shown below.
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: soklet
- Source: soklet/soklet
- License: Apache-2.0
- Homepage: https://www.soklet.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.