As developers, we often rely on Model Context Protocol (MCP) to facilitate powerful AI-based workflows. Although MCP is primarily designed for AI assistants, being able to manually inspect and debug MCP servers from the command line is a lifesaver during development. This guide will walk you through setting up your environment, listing available tools, making test calls, and troubleshooting MCP servers using jq
and standard Unix commands on macOS.
Prerequisites
Before diving in, make sure you have the following:
- An MCP server to test (refer to any example or your own server setup)
jq
installed (brew install jq
on macOS)- A basic understanding of JSON and command-line operations
- Create a /Code folder path
- Install (or use) Node.js and npx: Most modern Node.js installations come with npx by default. To confirm, run: npx –version If it prints a version number, you’re good to go.

What is MCP?
MCP (Model Context Protocol) uses JSON-RPC 2.0 for message exchange. By default, it works over stdio or SSE (Server-Sent Events). For quick command-line tests, we’ll focus on the stdio interface, piping JSON requests into the server’s stdin
and reading its responses from stdout
. Each MCP request generally follows this structure:
{
"jsonrpc": "2.0",
"method": "method/name",
"id": 1,
"params": {}
}
Listing Available Tools
One of the first things you’ll likely want to do is list out the tools provided by your MCP server. In this example, we’ll demonstrate using a filesystem-based MCP server. Run the following command from your macOS terminal in your /Code path as mentioned above in prerequisite sub-listing:
echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | npx -y @modelcontextprotocol/server-filesystem ~/Code | jq

The command sends a JSON-RPC request to list available tools and pipes the response into jq
for pretty-printing. You should see a list of tools, each with its name and input schema.
Testing Individual Tools
Once you’ve identified a specific tool, you can test it by constructing a JSON-RPC request with tools/call
. For instance, to invoke a tool called read_file
that reads a file from a given path, you can run:
echo '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"read_file","arguments":{"path":"/Users/sortollimited/readme.md"}},"id":2}' | npx -y @modelcontextprotocol/server-filesystem ~/Code | jq
This request instructs the server to call the read_file
tool with the path
argument set to /Users/sortollimited/readme.md
.
Exploring Resources
MCP servers can sometimes expose “resources” in addition to tools. You can list them similarly by invoking resources/list
:
echo '{"jsonrpc":"2.0","method":"resources/list","id":3}' | npx -y @modelcontextprotocol/server-filesystem ~/Code | jq
The response should detail any resources your MCP server has registered.
Useful jq
Filters
Here are a few jq
filters to make life easier when analyzing JSON responses:
- Get only tool names:
... | jq '.result.tools[].name'
- Detailed info about a specific tool (e.g.,
read_file
):... | jq '.result.tools[] | select(.name == "read_file")'
- Extract the input schema of a tool:
... | jq '.result.tools[] | select(.name == "read_file") | .inputSchema'
- Get call response text content:
... | jq '.result.content[].text'
Creating Shell Helper Functions
To streamline your MCP interactions, consider defining helper functions in your .zshrc
or .bashrc
. For example:
# List MCP tools
mcp_tools() {
local server_command=("${@}")
echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | "${server_command[@]}" | jq
}
# Call an MCP tool
mcp_call() {
local tool="$1"
local args="$2"
shift 2
local server_command=("${@}")
echo "{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"id\":1,\"params\":{\"name\":\"$tool\",\"arguments\":$args}}" | "${server_command[@]}" | jq
}
# List MCP resources
mcp_resources() {
local server_command=("${@}")
echo '{"jsonrpc":"2.0","method":"resources/list","id":1}' | "${server_command[@]}" | jq
}
After adding these, reload your shell and use them like so:
# List available tools
mcp_tools npx -y @modelcontextprotocol/server-filesystem ~/Code
# Read a file (quotes around JSON arguments)
mcp_call read_file '{"path":"/Users/YourUsername/Code/blog/README.md"}' npx -y @modelcontextprotocol/server-filesystem ~/Code
# List resources
mcp_resources npx -y @modelcontextprotocol/server-filesystem ~/Code
Here’s an example of filtering the results further with jq
:
# Retrieve just the text content of a file
mcp_call "read_file" '{"path":"/Users/YourUsername/Code/blog/README.md"}' npx -y @modelcontextprotocol/server-filesystem ~/Code | jq -r '.result.content[].text'
# Only list tool names
mcp_tools npx -y @modelcontextprotocol/server-filesystem ~/Code | jq -r '.result.tools[].name'
Debugging Tips
Validate JSON Schema
To ensure you’re calling the tools correctly, you can extract and store the input schema of any tool:
echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | npx -y @modelcontextprotocol/server-filesystem ~/Code | jq '.result.tools[].inputSchema' > schema.json
Monitor Server Logs
Run the MCP server in one terminal and watch logs in another:
# Terminal 1
npx -y @modelcontextprotocol/server-filesystem ~/Code 2>server.log
# Terminal 2
tail -f server.log
Test Error Handling
To see how your server handles invalid paths or missing files, try:
mcp_call read_file '{"path":"/nonexistent"}' npx -y @modelcontextprotocol/server-filesystem ~/Code
Conclusion
Debugging an MCP server doesn’t have to be complicated. By using echo
, jq
, and a few shell functions on your macOS system, you can:
- Inspect all the tools your server provides
- Call those tools with specific parameters
- List resources and schemas
- Monitor server logs for errors
These techniques will help you quickly validate your MCP implementation before integrating it with AI assistants like Claude Desktop. As a developer, you’ll appreciate the simplicity and power of using standard command-line tools for debugging and experimentation. Happy coding!