Skip to content

Instantly share code, notes, and snippets.

@owulveryck
Created May 7, 2025 15:25
Show Gist options
  • Save owulveryck/2bba83a4aa977d2195c387f025c5abe7 to your computer and use it in GitHub Desktop.
Save owulveryck/2bba83a4aa977d2195c387f025c5abe7 to your computer and use it in GitHub Desktop.
sample mcp server in shell

A sample server that says something... it works on MacOS. It needs to be adapted to work on other OS.

This is simply a tool to demonstrate how MCP works with JSON-RPC

#!/bin/zsh
initialize() {
local id=$(jq -r '.id' <<< "$current_json")
echo '{"jsonrpc":"2.0","id":'${id}',"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"mcpSampleShell","version":"1.0.0"}}}'
}
tool_list() {
local id=$(jq -r '.id' <<< "$current_json")
echo '{"jsonrpc":"2.0","id":'${id}',"result":{"tools":[{"description":"say out loud a text","inputSchema":{"type":"object","properties":{"text":{"description":"The text to say","type":"string"}},"required":["text"]},"name":"say"}]}}'
}
void() {
local id=$(jq -r '.id' <<< "$current_json")
echo '{"jsonrpc":"2.0","id":'${id}',"result":{}}'
}
tool_call() {
# Ensure the name is cURL
if jq -e '.params.name == "say"' <<< "$current_json" > /dev/null; then
local id=$(jq -r '.id' <<< "$current_json")
text=$(jq -r '.params.arguments.text' <<< "$current_json")
/usr/bin/say -v "Alex" $text -o /tmp/temp.aiff && /usr/bin/afplay /tmp/temp.aiff && rm /tmp/temp.aiff
echo '{"jsonrpc":"2.0","id":'${id}',"result":{"content":[{"type":"text","text":"success"} ] } }'
echo '{"jsonrpc":"2.0","id":'${id}',"result":{"content":[{"type":"text","text":"success"} ] } }' >> /tmp/call
fi
}
current_json=""
while read line; do
current_json=${current_json}${line}
# Check if this is a valid json
echo ${current_json} | jq . 2>/dev/null >/dev/null || continue
if ! jq -e '.jsonrpc == "2.0"' <<< "$current_json" > /dev/null; then
echo "bad jsonrpc call ${current_json}" >&2
current_json=""
continue
fi
echo $current_json >> /tmp/call
method=$(jq -r '.method' <<< "$current_json")
case "$method" in
"initialize")
initialize
;;
"tools/list")
tool_list
;;
"tools/call")
tool_call
;;
"resources/templates/list")
void
;;
*)
void
echo "Unknown method: $method" >> /tmp/call
;;
esac
current_json=""
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment