MCP server by berrydev-ai
gojq-mcp
A dual-mode JSON query tool that operates both as an MCP (Model Context Protocol) server and a standalone CLI executable using jq syntax via the gojq library.
Features
- 🔍 Execute jq queries on JSON files with full jq syntax support
- 📁 Multi-file support: Query multiple files with glob patterns using
inputs - ✅ Comprehensive validation: file existence, readability, and JSON validity
- 🔄 Dual mode operation: Run as MCP server or CLI tool
- 🔐 Bearer token authentication: Secure HTTP and SSE transports
- ⚙️ YAML configuration: Configure transport, prompts, and instructions
- 📡 Real-time file monitoring: Automatic client notifications on file changes
- 🌐 Multiple transports: stdio, HTTP streaming, and SSE
- 🧪 Well-tested: 30+ comprehensive test cases across all packages
- 📦 Zero configuration: Works out of the box with sensible defaults
Table of Contents
- gojq-mcp
Installation
Download binary
See releases for the latest binary builds.
The current release is v1.0.4.
# Download the latest binary
wget https://github.com/berrydev-ai/gojq-mcp/releases/download/v1.0.4/gojq-mcp-darwin-arm64
# Move the binary to your PATH
mv ./gojq-mcp-darwin-arm64 /usr/loca/bin/gojq-mcp
# Try it out
gojq-mcp -h
From Source
# Clone the repository
git clone https://github.com/berrydev-ai/gojq-mcp.git
cd gojq-mcp
# Build the binary
make build
# or
go build -o dist/gojq-mcp .
Using Go Install
go install github.com/berrydev-ai/gojq-mcp@latest
Usage
For comprehensive usage examples, configuration details, and advanced query patterns, see the USAGE_GUIDE.md.
MCP Server Mode
The default mode runs as an MCP server using stdio transport, perfect for integration with MCP clients like Claude Desktop.
Start the server:
./dist/gojq-mcp
Configure in Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
stdio
{
"mcpServers": {
"gojq-mcp": {
"command": "gojq-mcp",
}
}
}
streaming http
{
"mcpServers": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://my-server.com:8080/mcp"
]
}
}
Using with other MCP clients:
{
"mcpServers": {
"gojq": {
"command": "/absolute/path/to/dist/gojq-mcp",
"transport": "stdio"
}
}
}
CLI Mode
The CLI mode lets you run jq queries directly on local JSON files, ideal for one-off filtering and exploration.
Pass file paths and query using -f and -q flags:
Query a single file:
gojq-mcp -f ./examples/data/sample.json -q '.users[] | .name'
Query multiple specific files:
gojq-mcp -f ./examples/data/multiple-files/2025-01/01.json \
-f ./examples/data/multiple-files/2025-01/02.json \
-q '[inputs.transactions[]] | map(.amount) | add'
Query files using glob patterns:
# Query all JSON files in a directory
gojq-mcp -f './examples/data/multiple-files/2025-01/*.json' \
-q '[inputs.transactions[]] | map(.amount) | add'
# Query across multiple months
gojq-mcp -f './examples/data/multiple-files/*/*.json' \
-q '[inputs.transactions[] | select(.category == "services")] | length'
Features:
- Supports glob patterns for matching multiple files
- Uses
inputsfunction for multi-file queries - Automatic file validation (existence, readability, JSON validity)
- Output printed to stdout
See examples/data/sample.json and examples/data/multiple-files/ for sample data.
HTTP and SSE Transports
Start the server with HTTP or SSE transport for web-based integrations:
# HTTP streaming mode
gojq-mcp -t http -p ./examples/data -a :8080
# SSE mode with authentication
gojq-mcp -t sse -p ./examples/data -a :8080 -token your-secret-token
# With configuration file
gojq-mcp -p ./examples/data -c examples/config.http.yaml
Configuration Files
Create a YAML configuration file to customize server behavior:
# config.yaml
data_path: ./examples/data
transport: http
port: 8080
instructions: |
Custom instructions for the LLM client.
Describe your data, common queries, and tips.
prompts:
- name: analyze_transactions
description: "Analyze transaction data"
arguments:
- name: month
description: "Month to analyze (e.g., 2025-01)"
required: true
Start the server with your config:
gojq-mcp -c config.yaml
See USAGE_GUIDE.md for complete configuration examples and best practices.
MCP Tool Interface
Tool: run_jq
Query JSON files using jq filter syntax with support for single and multiple files.
Parameters:
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| jq_filter | string | ✅ Yes | The jq filter to execute (e.g., .users[] \| .name) |
| file_patterns | array[string] | ✅ Yes | Array of file patterns (relative to data path, supports globs) |
Return Value:
- Success: JSON-formatted string containing query results
- Error: Descriptive error message
Single File Example:
{
"jq_filter": ".users[] | select(.age > 30)",
"file_patterns": ["sample.json"]
}
Response:
[
{
"name": "Bob",
"age": 35,
"email": "bob@example.com"
}
]
Multi-File Example with Glob:
{
"jq_filter": "[inputs.transactions[]] | map(.amount) | add",
"file_patterns": ["multiple-files/2025-01/*.json"]
}
Response:
225.50
Multi-File Example with Specific Files:
{
"jq_filter": "[inputs.transactions[] | select(.category == \"services\")] | length",
"file_patterns": [
"multiple-files/2025-01/01.json",
"multiple-files/2025-01/02.json"
]
}
Key Features:
- 🌐 Glob pattern support: Use wildcards to match multiple files
- 🔗 Multi-file queries: Use
inputsto process multiple files - 🔒 Path security: All paths are restricted to the configured data directory
- ✅ Automatic validation: Files are validated before processing
Error Handling
The tool provides detailed error messages for:
- File not found:
"file does not exist: filename.json" - Directory instead of file:
"path is a directory, not a file: dirname" - Permission denied:
"file filename.json is not readable: permission denied" - Invalid JSON:
"file filename.json does not contain valid JSON: invalid character..." - Invalid jq filter:
"invalid jq filter: unexpected token..." - Query execution error:
"jq execution error: ..." - No matching files:
"no files found matching the provided patterns" - Path outside data directory:
"access denied: path X is outside data directory"
Examples
Basic Queries (Single File)
# Get a single field
.name
# Access nested field
.user.address.city
# Array access
.users[0].name
# Map over array
.users[] | .name
# Filter array
.users[] | select(.age > 30)
# Transform to new array
[.users[] | .email]
Advanced Queries (Single File)
# Multiple filters
.users[] | select(.age > 25) | select(.active == true) | .name
# Using built-in functions
.users | length
# Get object keys
keys
# Type checking
.age | type
# Arithmetic operations
.transactions[] | .amount | add
Multi-File Queries
When working with multiple files, use the inputs function to access all files:
# Combine all transactions from multiple files
[inputs.transactions[]]
# Sum amounts across all files
[inputs.transactions[]] | map(.amount) | add
# Filter across all files
[inputs.transactions[] | select(.amount > 100)]
# Count specific items across all files
[inputs.transactions[] | select(.category == "services")] | length
# Get unique categories across all files
[inputs.transactions[].category] | unique
# Average amount across all files
[inputs.transactions[]] | map(.amount) | add / length
Real-World Examples
CLI Mode:
# Find all users over 30
gojq-mcp -f examples/data/sample.json -q '.users[] | select(.age > 30)'
# Total revenue for January 2025
gojq-mcp -f 'examples/data/multiple-files/2025-01/*.json' \
-q '[inputs.transactions[]] | map(.amount) | add'
# Count service transactions across all months
gojq-mcp -f 'examples/data/multiple-files/*/*.json' \
-q '[inputs.transactions[] | select(.category == "services")] | length'
MCP Tool Mode:
{
"tool": "run_jq",
"arguments": {
"jq_filter": "[inputs.transactions[]] | group_by(.category) | map({category: .[0].category, total: map(.amount) | add})",
"file_patterns": ["multiple-files/2025-01/*.json"]
}
}
Sample Data
examples/data/sample.json- Users dataset with names, ages, and emailsexamples/data/multiple-files/2025-01/- January transaction dataexamples/data/multiple-files/2025-02/- February transaction data
Best Practices
For detailed usage examples, troubleshooting tips, and advanced configuration, see the USAGE_GUIDE.md.
For MCP Server Development
- Use relative paths: File patterns are relative to the configured data directory
- Leverage glob patterns: Use wildcards to match multiple files efficiently
- Handle errors gracefully: Check error responses from the tool
- Test queries incrementally: Start with simple queries and build complexity
- Use the identity filter (
.) to inspect data structure first - Enable file watching: Get real-time notifications when data files change
- Secure HTTP/SSE: Always use bearer tokens for HTTP and SSE transports
For jq Queries
Single-File Queries:
- Start simple: Test with
.to see full structure - Use
keys: Discover available fields withkeysfunction - Pipe operations: Build complex queries by chaining with
| - Select carefully: Use
select()for filtering arrays - Check types: Use
typefunction to verify data types
Multi-File Queries:
- Use
inputsfunction: Access all files in multi-file queries - Wrap in arrays: Use
[inputs.field[]]to collect results from all files - Aggregate with built-ins: Use
add,unique,group_byfor cross-file analysis - Filter before collecting:
[inputs.items[] | select(.condition)]is more efficient - Test with small sets: Try queries on a few files before expanding to all
For Configuration
- Start with YAML config: Use configuration files for complex setups
- Set custom instructions: Guide LLM clients with relevant context
- Define prompts: Create reusable prompt templates for common tasks
- Override with CLI: Use CLI flags to test different configurations
- Version control configs: Store configuration files in your repository
For Integration
- Restart MCP client after configuration changes
- Use absolute binary paths in MCP server configuration
- Verify data directory: Ensure the data path exists and contains JSON files
- Check logs if the server doesn't appear in your MCP client
- Test with Inspector: Use
@modelcontextprotocol/inspectorto debug MCP integration - Monitor file changes: Watch stderr for file change notifications
- Keep dependencies updated with
go get -uandgo mod tidy
For Security
- Restrict data directory: Only expose necessary JSON files
- Use authentication: Enable bearer tokens for HTTP/SSE transports
- Validate queries: Be aware that jq queries can be resource-intensive
- Monitor access: Log queries in production environments
- Keep tokens secret: Store bearer tokens in environment variables or secure vaults
Contributing
Contributions are welcome! For detailed development guidelines, testing instructions, and release procedures, see DEVELOPMENT.md.
Quick start for contributors:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Resources
- USAGE_GUIDE.md - Comprehensive usage guide with examples
- DEVELOPMENT.md - Development guide for contributors
- jq Manual - Complete jq syntax reference
- MCP Documentation - Model Context Protocol specification
- gojq Documentation - gojq library details