# zig-mcp-server
**Repository Path**: mirrors_jedisct1/zig-mcp-server
## Basic Information
- **Project Name**: zig-mcp-server
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-05-10
- **Last Updated**: 2026-07-11
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Zig MCP Server
A high-performance implementation of the MCP protocol in Zig
[](https://opensource.org/licenses/MIT)
---
The Zig MCP Server is a memory-efficient implementation of the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) specification. It provides both a standalone server executable and a library that can be embedded into your Zig applications.
## Features
- **Built-in HTTP Server**:
- Threaded connection handling with configurable thread pool
- Connection limiting to prevent resource exhaustion
- Graceful shutdown support
- Connection timeout management
- Server metrics collection
- Health check endpoint
- **Memory Efficient**: Uses arena allocators and stack buffers for optimized memory usage
- **Multiple Transports**: Supports both stdio and HTTP transports
- **Tool System**: Easy API to implement and add custom tools
- **MCP 0.4.0 Compatible**: Fully compatible with the latest MCP specification
- **Pure Zig**: No external dependencies required
- **Reusable Module**: Can be used as a library in other Zig applications
- **WebAssembly Support**: Runs on function-as-a-service cloud services based on WebAssembly, such as Fastly Compute
## Requirements
- Zig 0.14.0 or later (tested with Zig 0.15.0-dev)
## Building
```bash
# Standard build
zig build
# Optimized for release
zig build -Doptimize=ReleaseSmall
```
## Running
### Using the Command Line
```bash
# Run with stdio transport (default)
./zig-out/bin/mcp_server
# Run with HTTP transport
./zig-out/bin/mcp_server --transport http --port 7777
# Run with custom thread count and connection limits
./zig-out/bin/mcp_server --transport http --threads 4 --max-connections 500 --timeout 60000
```
### Using the Makefile
```bash
# Build the project
make build
# Run with stdio transport
make run
# Run with HTTP transport
make run-http
```
## Usage
### Standalone Server
The standalone server provides ready-to-use MCP functionality with minimal setup.
#### Built-in Tools
This MCP server comes with the following example tools out of the box:
- `echo`: Echoes back any provided parameters
- `reverse`: Takes a string input and returns its reverse
#### Command-line Options
```
Usage: mcp_server [options]
Options:
--port, -p Port to listen on (default: 7777)
--host, -h Host to bind to (default: 127.0.0.1)
--transport, -t Transport to use (stdio, http) (default: stdio)
--threads, -j Number of worker threads (default: CPU core count)
--max-connections, -c Maximum concurrent connections (default: 1000)
--timeout, -T Connection timeout in milliseconds (default: 30000, 0 = no timeout)
--help Print this help message
Server Endpoints:
/jsonrpc Main JSON-RPC endpoint (POST)
/health Health check endpoint (GET)
```
#### Advanced Usage
##### Threading Model
The HTTP transport uses a thread pool for handling concurrent connections. By default, it uses a number of threads equal to the available CPU cores, but you can adjust this with the `--threads` option.
##### Connection Limiting
To prevent resource exhaustion, you can limit the number of concurrent connections using the `--max-connections` option. When this limit is reached, new connections will be rejected.
##### Non-blocking Mode
Use the `--non-blocking` option to run the HTTP server in non-blocking mode. This starts a dedicated thread for the server, allowing the main thread to perform other tasks. This is especially useful when using the library in applications that need to do other work while the server is running.
##### Connection Timeouts
Each connection has a configurable timeout (default: 30 seconds) after which inactive connections are automatically closed. Set to 0 to disable timeouts completely.
##### Graceful Shutdown
The server supports graceful shutdown, which allows in-flight requests to complete before the server exits. This prevents abruptly terminating active connections during shutdown.
##### Server Metrics and Health Checks
The HTTP server provides metrics tracking, including:
- Total connections handled
- Active connections
- Bytes sent and received
- Request success/failure rates
A basic health endpoint at `/health` returns server status information.
## Client Examples
The server can be used with any client that implements the MCP protocol. We provide several example clients for demonstration.
### Python Client
Run the server first:
```bash
./zig-out/bin/mcp_server --transport http
```
Then run the Python client:
```bash
# Install required dependencies
pip install requests
# Run the example client
python examples/mcp_client.py --transport http --url "http://127.0.0.1:7777/jsonrpc"
```
The Python client demonstrates:
- Establishing a connection to the MCP server
- Protocol initialization and handshake
- Listing available tools
- Invoking tools with parameters
- Handling responses and errors
### JavaScript Client
For a Node.js client example:
```bash
# Make the script executable
chmod +x test_client.js
# Run the client (automatically starts the server in stdio mode)
./test_client.js
```
This JavaScript client shows:
- Communication over stdio transport
- Asynchronous MCP operation
- Proper request/response handling
### Building Your Own Client
The MCP protocol is based on JSON-RPC 2.0, making it easy to implement clients in any language. Key points to follow:
1. **Initialization**: Send an `initialize` request with your client capabilities
2. **Tool Discovery**: Use `mcp/tools/list` to discover available tools
3. **Tool Invocation**: Use `mcp/tools/invoke` with the tool name and parameters
4. **Shutdown**: Send a `shutdown` request when done
### Building for WebAssembly
The server can be compiled to WebAssembly for deployment in serverless environments:
```bash
zig build -Dtarget=wasm32-wasi -Doptimize=ReleaseSmall
```
When compiled for WebAssembly, the following restrictions apply:
1. **Stdio Transport Only**: The HTTP transport is automatically disabled in WebAssembly builds
2. **Command-line Options**: Most command-line options are unavailable (only `--help` works)
3. **Simplified API**: The API is automatically simplified to only include stdio-related fields
This makes the WebAssembly binary smaller and more focused for running in WebAssembly environments like Fastly Compute or other WASI-compatible serverless platforms where HTTP handling is typically provided by the host environment.
## Library Integration
Zig MCP Server is designed to be easily embedded in your Zig applications as a library.
### Adding the Dependency
#### In your build.zig file
```zig
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// Add the zig-mcp dependency
const zig_mcp_dep = b.dependency("zig-mcp", .{
.target = target,
.optimize = optimize,
});
// Get the module from the dependency
const zig_mcp_mod = zig_mcp_dep.module("zig-mcp");
// Create your application
const exe = b.addExecutable(.{
.name = "my_mcp_app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// Add the zig-mcp module to your application
exe.addModule("zig-mcp", zig_mcp_mod);
b.installArtifact(exe);
}
```
#### In your build.zig.zon file
```zig
.{
.name = .your_app_name,
.version = "0.1.0",
.fingerprint = 0x..., // Replace with actual fingerprint
.dependencies = .{
.@"zig-mcp" = .{
.url = "https://github.com/jedisct1/zig-mcp-server/archive/refs/tags/v0.1.0.tar.gz",
.hash = "12345...", // Replace with actual hash
},
},
}
```
### Basic Integration Example
Here's a simple example showing how to integrate the MCP server into your application:
```zig
const std = @import("std");
const zig_mcp = @import("zig-mcp");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// Define your tools
const tools = [_]zig_mcp.mcp.Tool{
.{
.name = "hello",
.description = "Greeting tool",
.handler = &helloHandler,
},
};
// Configure server settings with HTTP transport
const settings = zig_mcp.mcp.Settings{
.transport = .http,
.host = "127.0.0.1",
.port = 7777,
.tools = &tools,
.max_connections = 100, // Max 100 concurrent connections
.thread_count = 4, // 4 worker threads
.connection_timeout_ms = 30000, // 30 second connection timeout
.non_blocking_http = true, // Run in non-blocking mode
};
// Create and start MCP server
var server = try zig_mcp.mcp.Server.init(allocator, settings);
defer server.deinit();
std.debug.print("MCP Server starting\n", .{});
try server.start();
std.debug.print("Server running in background, you can continue with other tasks...\n", .{});
// Since we're using non-blocking mode, the main thread can do other work
var i: usize = 0;
while (i < 5) : (i += 1) {
std.time.sleep(5 * std.time.ns_per_s); // Sleep for 5 seconds
std.debug.print("Main thread still active...\n", .{});
}
std.debug.print("Main application shutting down\n", .{});
// Explicitly request a graceful shutdown before the defer
server.shutdown();
std.debug.print("Server shutdown requested, waiting for completion...\n", .{});
// Allow some time for the shutdown to complete
std.time.sleep(1 * std.time.ns_per_s);
}
// Tool handler implementation
fn helloHandler(ctx: *zig_mcp.jsonrpc.Context, params: std.json.Value) !std.json.Value {
const allocator = ctx.allocator();
// Extract name parameter if present
const name = if (params.object.get("name")) |n|
if (n == .string) n.string else "world"
else
"world";
// Build response
var result = std.json.Value{ .object = std.json.ObjectMap.init(allocator) };
const greeting = try std.fmt.allocPrint(allocator, "Hello, {s}!", .{name});
try result.object.put("greeting", std.json.Value{ .string = greeting });
return result;
}
```
### Advanced Integration
#### Custom Tool Development
Creating custom tools is straightforward:
1. Implement a handler function with the `zig_mcp.mcp.ToolHandlerFn` signature
2. Add it to the tools list when configuring your server
3. Optionally include a JSON Schema definition for tool parameters
```zig
fn myComplexTool(ctx: *zig_mcp.jsonrpc.Context, params: std.json.Value) !std.json.Value {
const allocator = ctx.allocator();
// Extract and validate parameters
const value1 = params.object.get("value1") orelse return zig_mcp.jsonrpc.Error.invalidParams;
const value2 = params.object.get("value2") orelse return zig_mcp.jsonrpc.Error.invalidParams;
if (value1 != .integer or value2 != .integer) {
return zig_mcp.jsonrpc.Error.invalidParams;
}
// Business logic
const result_value = value1.integer * value2.integer;
// Format and return result
var result = std.json.Value{ .object = std.json.ObjectMap.init(allocator) };
try result.object.put("calculated_value", std.json.Value{ .integer = result_value });
return result;
}
```
#### Transport Configuration
Choose the appropriate transport for your application:
- **HTTP Transport**: Ideal for networked applications, supports high concurrency
- **Stdio Transport**: Perfect for CLI tools and direct integration with LLM systems
#### Memory Management
The server uses an arena allocator for each request, automatically handling cleanup after each request/response cycle to prevent memory leaks.
## Current Status and Future Work
This project is under active development. The server has been improved with threading support, connection limiting, and timeouts, but several areas still need work:
1. **Stability Improvements**: Address potential panics during connection handling
2. **Stress Testing**: Verify behavior under high load and concurrent connections
3. **Secure Transport**: Add TLS support for secure connections
4. **Robust HTTP Parser**: Improve the HTTP parser to handle all edge cases
5. **Complete Error Handling**: Better error handling and recovery mechanisms
6. **Enhanced Logging**: More comprehensive logging system with different verbosity levels
7. **Connection Pooling**: For better performance with HTTP keep-alive
8. **Automated Tests**: Expand test coverage, especially for concurrency