socket-tools-mcp

Crates.iosocket-tools-mcp
lib.rssocket-tools-mcp
version0.1.2
created_at2026-01-25 18:41:14.596943+00
updated_at2026-01-25 19:43:28.952506+00
descriptionMCP server for multi-turn socket session management
homepage
repositoryhttps://github.com/sethhall/socket-tools-mcp
max_upload_size
id2069296
size159,899
Seth Hall (sethhall)

documentation

README

Socket Tools MCP Server

A Rust-based Model Context Protocol server that gives AI agents the ability to open TCP and TLS connections, send/receive data across multiple interactions, and manage session lifecycle.

Rust License MCP

Table of Contents

Features

  • Multi-turn sessions - Open a connection once, interact multiple times
  • TCP and TLS support - Plain TCP or encrypted TLS with certificate validation
  • Session management - Automatic TTL-based cleanup, max session limits
  • Binary data support - Send/receive binary via hex encoding (hex:DEADBEEF)
  • Human-readable session IDs - Easy to track sessions like tcp_example_80_0
  • Flexible response formats - Choose between concise (default) or detailed output

Installation

Prerequisites

  • Rust 1.85+ (2024 edition)
  • Cargo

Install with Cargo

cargo install socket-tools-mcp

The binary will be installed to ~/.cargo/bin/socket-tools-mcp.

Configuration

Add to your MCP client configuration:

Claude Code

Add to ~/.claude/settings.json (user scope) or .mcp.json (project scope):

{
  "mcpServers": {
    "socket-tools": {
      "command": "~/.cargo/bin/socket-tools-mcp"
    }
  }
}

With environment variables:

{
  "mcpServers": {
    "socket-tools": {
      "command": "~/.cargo/bin/socket-tools-mcp",
      "env": {
        "RUST_LOG": "debug"
      }
    }
  }
}

OpenCode

Add to ~/.config/opencode/opencode.json (global) or opencode.json in your project:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "socket-tools": {
      "type": "local",
      "command": ["~/.cargo/bin/socket-tools-mcp"]
    }
  }
}

With environment variables:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "socket-tools": {
      "type": "local",
      "command": ["~/.cargo/bin/socket-tools-mcp"],
      "environment": {
        "RUST_LOG": "debug"
      }
    }
  }
}

Note: OpenCode requires "type": "local" and uses "command" as an array. Claude Code uses "mcpServers" with "command" as a string.

Usage

HTTP Request (one call)

Use initial_data for simple request/response:

socket_open(
  host="example.com", 
  port=80, 
  initial_data="GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"
)
-> {session_id: "tcp_example_80_0", response: "HTTP/1.1 200 OK...", bytes_received: 1256}

HTTPS with TLS

socket_open(host="api.github.com", port=443, tls=true)
-> {session_id: "tls_api_443_0", tls_version: "TLSv1_3"}

Multi-step Interaction

For protocols requiring multiple exchanges:

1. socket_open(host="redis.local", port=6379)
   -> {session_id: "tcp_redis_6379_0"}

2. socket_write(session_id="tcp_redis_6379_0", data="PING\r\n")
   -> {bytes_sent: 6}

3. socket_read(session_id="tcp_redis_6379_0")
   -> {data: "+PONG\r\n", bytes_received: 7}

4. socket_close(session_id="tcp_redis_6379_0")

Binary Protocol

socket_write(session_id="...", data="hex:2a310d0a24340d0a50494e470d0a")
socket_read(session_id="...")

Tools

socket_open

Open a TCP or TLS connection. Returns a human-readable session_id for subsequent operations.

Parameter Type Required Description
host string yes Hostname or IP (e.g., example.com, 192.168.1.1)
port integer yes Port number (80=HTTP, 443=HTTPS, 6379=Redis)
tls boolean no Use TLS encryption. Required for HTTPS (port 443)
insecure boolean no Skip cert verification (dev only, self-signed certs)
timeout integer no Connection timeout in ms (default: 10000)
sni string no Override TLS server name (SNI). Use when connecting to IP addresses or load balancers
alpn array no ALPN protocols to negotiate (e.g., ["h2", "http/1.1"] for HTTP/2)
client_cert string no Path to PEM file with client certificate chain (for mTLS)
client_key string no Path to PEM file with client private key (for mTLS)
initial_data string no Data to send immediately and get response in one call
response_format string no concise (default) or detailed (includes hex)

When to use:

  • Starting any network interaction (HTTP, databases, custom protocols)
  • Use initial_data to combine connect + send + receive in one call

Example (concise response):

// Request
{"host": "example.com", "port": 80, "initial_data": "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"}

// Response
{"session_id": "tcp_example_80_0", "response": "HTTP/1.1 200 OK\r\n...", "bytes_received": 1256}

Example (detailed response with TLS):

// Request
{"host": "api.github.com", "port": 443, "tls": true, "response_format": "detailed"}

// Response
{
  "session_id": "tls_api_443_0",
  "host": "api.github.com",
  "port": 443,
  "tls_info": {"protocol_version": "TLSv1_3", "cipher_suite": "TLS13_AES_256_GCM_SHA384"}
}

Example (HTTP/2 with ALPN):

{"host": "api.github.com", "port": 443, "tls": true, "alpn": ["h2", "http/1.1"]}

Example (connect to IP with SNI override):

{"host": "93.184.216.34", "port": 443, "tls": true, "sni": "example.com"}

Example (mutual TLS / client certificate auth):

{"host": "secure.internal", "port": 443, "tls": true, "client_cert": "/path/to/cert.pem", "client_key": "/path/to/key.pem"}

socket_write

Send data to the socket. Returns immediately after sending (non-blocking).

Parameter Type Required Description
session_id string yes Session ID from socket_open (e.g., tcp_example_80_0)
data string yes Data to send. Prefix with hex: for binary

When to use: Any multi-step interaction. Follow with socket_read to get response.

Data format:

  • Text sent as-is. Include \r\n for protocols that need line endings.
  • Binary: prefix with hex: (e.g., hex:deadbeef)

socket_read

Read and accumulate data from socket until idle or max timeout.

Parameter Type Required Description
session_id string yes Session ID from socket_open
timeout integer no Idle timeout in ms (default: 1000). Returns when no new data for this duration.
max_timeout integer no Max total time in ms (default: 30000). Safety limit for streaming servers.
response_format string no concise (default) or detailed

Behavior:

  • Accumulates data as it arrives
  • Returns when no new data for timeout ms (response complete)
  • Returns early if max_timeout reached, with truncated: true

Example response:

{"data": "HTTP/1.1 200 OK...", "bytes_received": 1256}

With truncation (streaming server):

{"data": "...", "bytes_received": 65536, "truncated": true}

socket_close

Close a socket session and free resources. Safe to call multiple times.

Parameter Type Required Description
session_id string yes Session ID to close

Notes: Sessions auto-close after 60s of inactivity. Max 100 concurrent sessions.

Session Management

  • Sessions automatically expire after 60 seconds of inactivity
  • Maximum 100 concurrent sessions (configurable at compile time)
  • Each operation (write, read) refreshes the session TTL
  • Expired sessions are cleaned up every 10 seconds

Logging

Set the RUST_LOG environment variable for debug output:

RUST_LOG=debug ./socket-tools-mcp
RUST_LOG=socket_tools_mcp=trace ./socket-tools-mcp

Logs are written to stderr to avoid interfering with the JSON-RPC stdio transport.

Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create a new branch: git checkout -b feature-name
  3. Make your changes
  4. Run checks:
    cargo fmt
    cargo clippy -- -W clippy::all
    cargo build --release
    
  5. Push your branch: git push origin feature-name
  6. Create a pull request

Guidelines

  • Follow the existing code style
  • Add tests for new functionality
  • Update documentation as needed
  • Keep commits focused and atomic

License

This project is licensed under the Apache License 2.0.

Commit count: 14

cargo fmt