MCPHub LabRegistrymcp-server-bash-sdk
muthuishere

mcp server bash sdk

Built by muthuishere โ€ข 504 stars

What is mcp server bash sdk?

A high-performance MCP server implementation for mcp-server-bash-sdk that bridges the gap between the Model Context Protocol and external services. It allows Large Language Models to interact with your data and tools with low latency and native support.

How to use mcp server bash sdk?

1. Ensure you have an MCP-compatible client (like Claude Desktop) installed. 2. Configure your server with: npx @modelcontextprotocol/mcp-server-bash-sdk 3. Restart your client and verify the new tools are available in the system catalog.
๐Ÿ›ก๏ธ Scoped (Restricted)
npx @modelcontextprotocol/mcp-server-bash-sdk --scope restricted
๐Ÿ”“ Unrestricted Access
npx @modelcontextprotocol/mcp-server-bash-sdk

Key Features

Native MCP Protocol Support
High-performance Data Streaming
Type-safe Tool Definitions
Seamless Environment Integration

Optimized Use Cases

Connecting external databases to AI workflows
Automating workflow tasks via natural language
Augmenting developer productivity with specialized tools

mcp server bash sdk FAQ

Q

What is an MCP server?

MCP is an open standard that enables developers to build secure, two-way integrations between AI models and local or remote data sources.

Q

Is this server ready for production?

Yes, this server follows standard MCP security patterns and tool-restricted access.

Official Documentation

View on GitHub

๐Ÿš MCP Server in Bash

MCP Release Platforms License Discord

A lightweight, zero-overhead implementation of the Model Context Protocol (MCP) server in pure Bash โ€” targeting the current 2026-07-28 revision.

๐Ÿ“– Documentation site ยท ๐Ÿงฉ Examples ยท ๐Ÿง  Architecture decisions ยท ๐Ÿ”ฌ Spikes

Why? Most MCP servers are just API wrappers with schema conversion. This implementation provides a zero-overhead alternative to Node.js, Python, or other heavy runtimes.

Why now? The 2026-07-28 revision made MCP stateless: no initialize handshake, no sessions, no server-initiated requests. One line in, one line out โ€” which is exactly the shape of a shell read loop. Bash went from an awkward fit to a natural one.


๐Ÿ“‹ Features

  • โœ… MCP 2026-07-28 โ€” stateless, per-request version negotiation
  • โœ… Both standard transports: stdio and Streamable HTTP, from the same server file
  • โœ… server/discover, tools/list, tools/call
  • โœ… Dynamic tool discovery via function naming convention
  • โœ… External configuration via JSON files
  • โœ… Output validated against the official published JSON Schema

๐Ÿ”ง Requirements

  • Bash 3.2 or newer (3.2 is what macOS ships as /bin/bash)
  • jq for JSON processing (brew install jq / apt install jq / apk add jq)
  • (HTTP transport only) socat preferred, or netcat โ€” see the note under Transports
  • (optional) Python with jsonschema, only to run the schema conformance test

Supported platforms

Verified by running the real test suites on each, not by inspection โ€” ./scripts/test-linux.sh all reproduces the Linux rows on any machine with Docker.

PlatformShellUnitHTTP
macOSbash 3.2 (/bin/bash) and 5.x31/3119/19
Debian / Ubuntubash 5.231/3119/19
Alpine (musl + busybox)bash 5.331/3119/19

Docker is needed only to verify other platforms โ€” never to run a server.


๐Ÿš€ Quick Start

  1. Clone the repo
git clone https://github.com/muthuishere/mcp-server-bash-sdk
cd mcp-server-bash-sdk
  1. Make scripts executable
chmod +x mcpserver_core.sh moviemcpserver.sh
  1. Try it out โ€” every request carries its protocol version in params._meta:
echo '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}' | ./moviemcpserver.sh

echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_movies","arguments":{},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}' | ./moviemcpserver.sh
  1. Or run it as a local HTTP endpoint
./moviemcpserver.sh --http        # http://127.0.0.1:3000/mcp
  1. Run the tests
./test_mcpserver_core.sh                          # 31 unit tests
./test_mcpserver_core.sh test_discover_shape      # a single test
./test_conformance.sh                             # validate against the official schema
./test_http_transport.sh                          # 19 HTTP transport tests
./scripts/test-linux.sh all                       # run everything on Debian, Alpine and Ubuntu

๐Ÿ—๏ธ Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   stdio   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  MCP Host   โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚  Your server (moviemcpserver.sh)     โ”‚
โ”‚ (AI System) โ”‚           โ”‚                                      โ”‚
โ”‚             โ”‚   HTTP    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚             โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚  โ”‚ Transport                      โ”‚  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜           โ”‚  โ”‚  run_mcp_server (stdio)        โ”‚  โ”‚
                          โ”‚  โ”‚  mcpserver_http.sh (--http)    โ”‚  โ”‚
                          โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
                          โ”‚                  โ–ผ                   โ”‚
                          โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
                          โ”‚  โ”‚ Protocol  mcpserver_core.sh    โ”‚  โ”‚
                          โ”‚  โ”‚   process_request()            โ”‚  โ”‚
                          โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
                          โ”‚                  โ–ผ                   โ”‚
                          โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
                          โ”‚  โ”‚ Business logic  tool_* funcs   โ”‚  โ”‚
                          โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
                          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€-โ”˜
                                             โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚ Config JSON ยท external APIs  โ”‚
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Both transports call the same process_request, so they cannot drift in protocol behaviour.

  • mcpserver_core.sh: JSON-RPC framing, MCP dispatch, version negotiation, result envelopes
  • mcpserver_http.sh: the Streamable HTTP binding โ€” headers, status codes, Origin, listener
  • moviemcpserver.sh / examples/gitserver.sh: business logic โ€” your tool_* functions
  • assets/: discovery document and tool list
  • spec/: the vendored official schema the conformance test validates against
  • examples/: four runnable servers and a build-your-own walkthrough
  • docs/adr/: why the SDK is shaped this way ยท docs/spikes/: the experiments behind those decisions

๐Ÿ”Œ Creating Your Own MCP Server

Tool Function Guidelines

  1. Naming Convention: prefix every tool function with tool_, matching the name in your tools JSON
  2. Parameters: each function takes a single parameter $1 containing the arguments as JSON
  3. Success: echo the result, return 0
  4. Failure: echo an explanatory message, return 1 โ€” the caller receives a successful response with isError: true, so the model can read the reason and retry. Tool failures are not transport errors.
  5. Automatic Discovery: tools are dispatched by function name; the tools JSON controls what clients are told exists

Implementation Steps

  1. Create your business logic file (e.g., weatherserver.sh)
#!/bin/bash
# Weather API implementation

# Override configuration paths BEFORE sourcing the core
MCP_CONFIG_FILE="$(dirname "${BASH_SOURCE[0]}")/assets/weatherserver_config.json"
MCP_TOOLS_LIST_FILE="$(dirname "${BASH_SOURCE[0]}")/assets/weatherserver_tools.json"
MCP_LOG_FILE="$(dirname "${BASH_SOURCE[0]}")/logs/weatherserver.log"

source "$(dirname "${BASH_SOURCE[0]}")/mcpserver_core.sh"

API_KEY="${MCP_API_KEY:-default_key}"

# Tool: Get current weather for a location
tool_get_weather() {
  local args="$1"
  local location=$(echo "$args" | jq -r '.location')

  if [[ -z "$location" || "$location" == "null" ]]; then
    echo "Missing required parameter: location"   # reaches the model as isError
    return 1
  fi

  curl -s "https://api.example.com/weather?location=$location&apikey=$API_KEY"
  return 0
}

# stdio by default; --http serves the same tools over Streamable HTTP.
case "${1:-}" in
  --http)            shift; run_mcp_http_server "$@" ;;
  handle-connection) run_mcp_http_server handle-connection ;;
  *)                 run_mcp_server "$@" ;;
esac

For the --http mode also source "$(dirname "${BASH_SOURCE[0]}")/mcpserver_http.sh" next to the core.

Four runnable examples are in examples/, each covering a different problem:

ExampleWhat it shows
gitserver.shShelling out safely โ€” argument validation, structured output
weatherserver.shWrapping a third-party API โ€” secrets in env, network failures, trimming the response
fileserver.shSaying no โ€” read-only filesystem access with a real path-traversal boundary
moviemcpserver.shThe minimum, over canned data
  1. Create assets/weatherserver_tools.json
{
  "tools": [
    {
      "name": "get_weather",
      "description": "Get current weather for a location",
      "inputSchema": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "City name or coordinates"
          }
        },
        "required": ["location"]
      }
    }
  ]
}

Keep the array order stable โ€” the spec asks servers to return tools deterministically so clients (and LLM prompt caches) can cache them.

  1. Create assets/weatherserver_config.json โ€” this is now the server/discover body, not an initialize result:
{
  "supportedVersions": ["2026-07-28"],
  "serverInfo": {
    "name": "WeatherServer",
    "version": "1.0.0"
  },
  "capabilities": {
    "tools": {
      "listChanged": false
    }
  },
  "ttlMs": 3600000,
  "cacheScope": "public",
  "instructions": "This server provides weather information."
}
  1. Make your file executable
chmod +x weatherserver.sh

๐Ÿ”€ Transports

Both are the spec's standard bindings, and both run from the same server file.

stdio

What an editor or agent launches as a subprocess. This is the default and the one to use unless you specifically need HTTP.

./moviemcpserver.sh

Streamable HTTP

2026-07-28 removed sessions, the GET stream and SSE resumability, so this binding is now just POST a message, get JSON back โ€” which is why it fits in a shell script at all.

./moviemcpserver.sh --http                    # http://127.0.0.1:3000/mcp
MCP_HTTP_PORT=8080 ./moviemcpserver.sh --http
VariableDefaultPurpose
MCP_HTTP_PORT3000listening port
MCP_HTTP_BIND127.0.0.1interface โ€” leave it on loopback
MCP_HTTP_PATH/mcpendpoint path
MCP_ALLOWED_ORIGINShttp://localhost,http://127.0.0.1Origin allowlist; anything else gets 403

Every POST must carry MCP-Protocol-Version and Mcp-Method, plus Mcp-Name for tools/call / resources/read / prompts/get, and each must match the request body โ€” a mismatch is 400 with -32020. That is a security control, not ceremony: an intermediary may route on the header while the server executes the body.

โš ๏ธ This is a local endpoint, not a web server. It binds loopback, has no TLS and no auth. Install socat (brew install socat) and it forks per connection; without it the netcat fallback serves one connection at a time, with a brief window between connections where the port is refused. To expose it beyond localhost, put a real reverse proxy in front. See ADR-0006 and spike 02.


๐Ÿ–ฅ๏ธ Using with an MCP client

"mcp": {
    "servers": {
        "my-weather-server": {
            "type": "stdio",
            "command": "/path/to/your/weatherserver.sh",
            "args": [],
            "env": {
                "MCP_API_KEY": "your-api-key"
            }
        }
    }
}

โš ๏ธ The client must speak MCP 2026-07-28. This SDK implements that revision only and rejects older ones with -32022 (ADR-0002 explains the trade-off). Editors still on 2025-06-18 / 2025-11-25 will need a shim until they upgrade.


๐Ÿšซ Limitations

  • HTTP is a local endpoint: no TLS, no auth, and without socat it serves one connection at a time
  • No SSE response mode, so no notifications/progress streaming and no subscriptions/listen
  • No concurrency on stdio: one client, one process, ~30 requests/second
  • No resources, prompts, MRTR input requests, or the tasks extension
  • Clients older than 2026-07-28 are rejected

For AI assistants and local tool execution, these aren't blocking issues.


๐Ÿงญ Design notes

This SDK is documented as much by why as by how:

  • Architecture decisions โ€” seven ADRs, each recording what was rejected and why. ADR-0001 chose stdio-only and is now superseded in scope by ADR-0006; the reversal is recorded rather than edited away, because the protocol changed underneath it.
  • Spikes โ€” runnable experiments behind every number here. They are how the two platform bugs were found: read -N missing from macOS's bash 3.2, and Linux capping a single argv entry at 128 KB where macOS does not.

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

Blog : https://medium.com/@muthuishere/why-i-built-an-mcp-server-sdk-in-shell-yes-bash-6f2192072279

Community

Questions, ideas, or built something with this? Join AgentNexus โ€” a Discord for people building with AI agents and open tools. This project lives in #mcp-bash-sdk.


Built and maintained by deemwar โ€” we build messaging and browser automation, and the plumbing that keeps it delivering when it silently stops.

Need help with this, or something like it in production? io@deemwar.com

Global Ranking

6.6
Trust ScoreMCPHub Index

Based on codebase health & activity.

Manual Config

{ "mcpServers": { "mcp-server-bash-sdk": { "command": "npx", "args": ["mcp-server-bash-sdk"] } } }