Skip to main content

murl - MCP Curl

Tests

A curl-like CLI tool for interacting with Model Context Protocol (MCP) servers.

POSIX Agent Standard Compliant: This tool implements Level 2 (Agent-Optimized) compliance, making it natively compatible with AI agents.

murl logo

What is MCP?

MCP (Model Context Protocol) is an open standard developed by Anthropic for AI models to access external data sources, tools, and services. It provides a universal way for large language models (LLMs) to interact with various resources securely and efficiently.

Quick Start

Try with Public Demo Server (No Setup Required)

Test murl immediately with a public MCP server:

# Install murl
curl -sSL https://raw.githubusercontent.com/turlockmike/murl/master/install.sh | bash
# Or using pip: pip install mcp-curl

# List tools on the public Fetch server
murl https://remote.mcpservers.org/fetch/mcp/tools

# Fetch a webpage and convert to markdown
murl https://remote.mcpservers.org/fetch/mcp/tools/fetch -d url=https://example.com

Public demo servers:

  • Fetch Server: https://remote.mcpservers.org/fetch/mcp - Simple server for fetching web content
  • DeepWiki: https://mcp.deepwiki.com/mcp - GitHub repository documentation

Quick Local Setup with mcp-proxy

Get started with murl in minutes using a local MCP server:

# Step 1: Install murl
curl -sSL https://raw.githubusercontent.com/turlockmike/murl/master/install.sh | bash
# Or using pip: pip install mcp-curl

# Step 2: Install mcp-proxy to expose MCP servers over HTTP
pip install mcp-proxy

# Step 3: Start a local time server example (in one terminal)
mcp-proxy --port 3000 uvx mcp-server-time

# Step 4: Test with murl (in another terminal)
# List available tools
murl http://localhost:3000/tools

# Call the get_current_time tool
murl http://localhost:3000/tools/get_current_time

# Call with a timezone argument
murl http://localhost:3000/tools/get_current_time -d timezone=America/New_York

What's happening:

  • mcp-proxy wraps any stdio-based MCP server and exposes it over HTTP
  • uvx mcp-server-time is a simple MCP server that provides time-related tools
  • murl connects to the HTTP endpoint and makes MCP requests

Try other MCP servers:

# Filesystem server (access files)
mcp-proxy --port 3001 uvx mcp-server-filesystem /path/to/directory

# Sequential thinking server
mcp-proxy --port 3002 npx -y @modelcontextprotocol/server-sequential-thinking

Installation

Install murl with a single command:

curl -sSL https://raw.githubusercontent.com/turlockmike/murl/master/install.sh | bash

This will automatically download and install murl from source.

Using pip

Install murl from PyPI:

pip install mcp-curl

To upgrade to the latest version:

pip install --upgrade mcp-curl

Upgrade

To upgrade murl to the latest version:

murl --upgrade

This command downloads and runs the installation script to update murl to the latest release from GitHub.

From Source

git clone https://github.com/turlockmike/murl.git
cd murl
pip install -e .

Usage

murl provides a curl-like interface for interacting with MCP servers over HTTP. It abstracts the JSON-RPC 2.0 protocol, making it easy to call MCP methods using intuitive REST-like paths.

Basic Syntax

murl <url> [options]

Where <url> is the MCP server endpoint with a virtual path (e.g., http://localhost:3000/tools).

Options

  • -d, --data <key=value> - Add data to the request. Can be used multiple times.
  • -H, --header <key: value> - Add custom HTTP headers (e.g., for authentication).
  • -v, --verbose - Enable verbose output (prints request/response details to stderr).
  • --agent - Enable agent-compatible mode (pure JSON output, structured errors). See Agent Mode below.
  • --version - Show detailed version information (includes Python version and installation path).
  • --upgrade - Upgrade murl to the latest version from GitHub releases.
  • --help - Show help message.

Agent Mode

murl implements the POSIX Agent Standard (Level 2) for AI agent compatibility. Use the --agent flag to enable agent-optimized behavior:

Key Features:

  • Pure JSON output: Compact JSON to stdout (no pretty-printing)
  • JSON Lines (NDJSON): List operations output one JSON object per line
  • Structured errors: JSON error objects to stderr with error codes
  • Non-interactive: No prompts or progress indicators
  • Semantic exit codes:
    • 0 = Success
    • 1 = General error (connection, timeout, server error)
    • 2 = Invalid arguments (malformed URL, invalid data format)
    • 100 = MCP server error (reported via JSON code field, not exit code)

Examples:

# Get agent-optimized help
murl --agent --help

# List tools (JSON Lines output)
murl --agent http://localhost:3000/tools

# Call a tool with compact JSON output
murl --agent http://localhost:3000/tools/echo -d message=hello

# Process NDJSON output with jq (one JSON object per line)
murl --agent http://localhost:3000/tools | jq -c '.'

# Handle errors programmatically
if ! result=$(murl --agent http://localhost:3000/tools/invalid 2>&1); then
  echo "Error: $result" | jq -r '.message'
fi

Agent Mode vs Human Mode:

Feature Human Mode Agent Mode (--agent)
JSON Output Pretty-printed (indented) Compact (no spaces)
List Output JSON array JSON Lines (NDJSON)
Error Output Friendly message to stderr Structured JSON to stderr
Exit Codes 0, 1, or 2 (2 for invalid arguments) Semantic (0, 1, 2)

Examples

List Available Tools

murl http://localhost:3000/tools

This sends a tools/list request to the MCP server.

Call a Tool with Arguments

murl http://localhost:3000/tools/echo -d message=hello

This sends a tools/call request with the tool name "echo" and arguments {"message": "hello"}.

Call a Tool with Multiple Arguments

murl http://localhost:3000/tools/weather -d city=Paris -d metric=true

Arguments are automatically type-coerced (strings, numbers, booleans).

Call a Tool with JSON Data

murl http://localhost:3000/tools/config -d '{"settings": {"theme": "dark"}}'

You can pass complex JSON objects directly.

List Available Resources

murl http://localhost:3000/resources

This sends a resources/list request.

Read a Resource

murl http://localhost:3000/resources/path/to/file

This sends a resources/read request with the file path. The path is automatically converted to a file:// URI.

List Available Prompts

murl http://localhost:3000/prompts

This sends a prompts/list request.

Get a Prompt

murl http://localhost:3000/prompts/greeting -d name=Alice

This sends a prompts/get request with the prompt name "greeting" and arguments.

Add Authorization Headers

murl http://localhost:3000/tools -H "Authorization: Bearer token123"

Custom headers can be added for authentication or other purposes.

Verbose Mode

murl http://localhost:3000/tools -v

Verbose mode prints the JSON-RPC request payload and HTTP headers to stderr, useful for debugging.

URL Mapping

murl automatically maps REST-like paths to MCP JSON-RPC methods:

URL Path MCP Method Parameters
/tools tools/list {}
/tools/<name> tools/call {name: "<name>", arguments: {...}}
/resources resources/list {}
/resources/<path> resources/read {uri: "file:///<path>"} (three slashes)
/prompts prompts/list {}
/prompts/<name> prompts/get {name: "<name>", arguments: {...}}

Piping Output

murl outputs raw JSON to stdout, making it pipe-friendly:

# Use with jq to format output
murl http://localhost:3000/tools | jq .

# Extract specific fields
murl http://localhost:3000/tools | jq '.[0].name'

Development

Setup Development Environment

# Clone the repository
git clone https://github.com/turlockmike/murl.git
cd murl

# Install in development mode with dev dependencies
pip install -e ".[dev]"

Running Tests

pytest

Running Tests with Coverage

pytest --cov=murl --cov-report=html

How It Works

murl works by:

  1. Parsing the URL to extract the base endpoint and the MCP virtual path
  2. Mapping the virtual path to the appropriate MCP JSON-RPC method
  3. Parsing data flags (-d) into method parameters with type coercion
  4. Constructing a JSON-RPC 2.0 request with the method and parameters
  5. Sending an HTTP POST request to the base endpoint with the JSON-RPC payload
  6. Extracting the result from the JSON-RPC response and printing it as JSON

Using murl with MCP Servers

murl supports the Streamable HTTP transport protocol used by modern MCP servers. This allows murl to work with MCP servers that implement HTTP-based transport.

Streamable HTTP Support

As of the latest version, murl includes comprehensive support for the MCP Streamable HTTP transport protocol:

  • Sends Accept: application/json, text/event-stream header
  • Handles both immediate JSON responses and Server-Sent Events (SSE) streams
  • Supports session-based SSE for compatibility with mcp-proxy
  • Automatically tries session-based SSE first, then falls back to regular HTTP POST
  • Compatible with MCP servers implementing the Streamable HTTP specification

Direct HTTP MCP Servers

murl works best with MCP servers that expose a direct HTTP JSON-RPC endpoint. For example, if you have a server running at http://localhost:3000 that implements MCP over HTTP:

# List available tools
murl http://localhost:3000/tools

# Call a tool with arguments
murl http://localhost:3000/tools/my_tool -d param1=value1 -d param2=value2

# List resources
murl http://localhost:3000/resources

# Get a prompt
murl http://localhost:3000/prompts/my_prompt -d arg1=value

Using murl with mcp-proxy

Many MCP servers are implemented as stdio (standard input/output) programs. To use these with murl, you can expose them via HTTP using mcp-proxy:

# Install mcp-proxy
pip install mcp-proxy

# Start mcp-proxy to expose a stdio MCP server on HTTP port 3000
mcp-proxy --port 3000 python my_mcp_server.py

# Or for a Node.js MCP server
mcp-proxy --port 3000 node path/to/mcp-server.js

Once mcp-proxy is running, you can use murl to interact with your stdio MCP server:

# List available tools
murl http://localhost:3000/tools

# Call a tool with arguments
murl http://localhost:3000/tools/my_tool -d param1=value1 -d param2=value2

# List resources
murl http://localhost:3000/resources

# Get a prompt
murl http://localhost:3000/prompts/my_prompt -d arg1=value

How it works: murl automatically detects mcp-proxy's session-based SSE architecture and handles it transparently:

  1. Connects to the SSE endpoint to get a session ID
  2. Posts the request to the session-specific endpoint
  3. Reads the response from the SSE stream
  4. Each murl invocation creates and closes its own ephemeral session

For more information about MCP transport protocols, see the official MCP documentation.

Requirements

  • Python 3.10 or higher
  • click - For CLI argument parsing
  • mcp - Model Context Protocol SDK

License

MIT License - see LICENSE file for details

Releasing

For maintainers: To create a new release, update the version in pyproject.toml and murl/__init__.py, then create and push a git tag:

git tag v0.2.1
git push origin v0.2.1

This will automatically trigger a GitHub Actions workflow that builds the package and creates a GitHub release with the artifacts.

Metadata

Release files for mcp-curl 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcp-curl 0.3.2
File Size Uploaded Provenance
mcp_curl-0.3.2.tar.gz 24.3 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for mcp-curl 0.3.2
File Interpreter ABI Platform
mcp_curl-0.3.2-py3-none-any.whl Python 3 none any Details

Total release size: 41.2 kB

Release files / mcp_curl-0.3.2.tar.gz

Download URL mcp_curl-0.3.2.tar.gz
Size 24.3 kB
Tags Source
SHA-256 checksum
How to use checksums
c5ad9b2e05cb8c0502cce013525e238239365356e73b14e445a554879fcf5e7d
BLAKE2b-256 checksum
How to use checksums
bee78307ea4e605679318fbf14cbe0faf898db14423bc48c009deedd1d97e3b0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 20, 2026.

Transparency log

Release files / mcp_curl-0.3.2-py3-none-any.whl

Download URL mcp_curl-0.3.2-py3-none-any.whl
Size 16.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
64c80d4f33325ddc4a8e1ac019e5fdb1b2f974c3f85a4e58b0143b8a63cd8a98
BLAKE2b-256 checksum
How to use checksums
172e7258c50f49743b2a7e9613da00749a82ac7286ceeb56376af79f61efca96
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 20, 2026.

Transparency log

Security for mcp-curl 0.3.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for mcp_curl-0.3.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 20, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page