The CLI · v1.0.0

Your server.
Their agent.

Start a local MCP server on your machine. Give a teammate a session ticket. Their MCP client connects through MCPWire and calls the tools you expose.

Host machineEncrypted connectionGuest agent
On this page

Run the CLI

You need Node.js 18 or newer and an MCP server that speaks JSON-RPC over stdio. Run directly with npx or install globally:

Terminal · Run with npx
npx -y @mcpwire/cli

Running npx -y @mcpwire/cli prints the help menu. You can also install globally via npm install -g @mcpwire/cli to use the mcpwire command directly.

The two main subcommands are share on the host and join on the guest.

Getting started · Filesystem example

Share a folder from your machine

Create a small test file. The email is intentional: you’ll see what redaction changes on the guest side.

Host · prepare a test folder
mkdir -p "$HOME/mcpwire-demo"
printf 'Revenue: 42\nContact: root@corp.example.com\n' \
  > "$HOME/mcpwire-demo/report.txt"

Start the share command and leave this terminal running:

Host · share two filesystem tools
npx -y @mcpwire/cli share \
  --name shared-files \
  --allow "read_file,list_directory" \
  --redact-secrets \
  --ttl 30m \
  -- npx -y @modelcontextprotocol/server-filesystem@2.0.1 \
  "$HOME/mcpwire-demo"

Everything after -- is the command that launches your MCP server. The folder path is on the host. Only read_file and list_directory are exposed.

After DHT discovery is ready, MCPWire prints a wire:// ticket containing 64 hexadecimal characters and a client config fragment. Keep the ticket private. A new share process creates a new ticket.

Keep the host running. The server starts when a guest connects, with a separate child process for each peer. It inherits the host’s environment and working directory. Disconnecting a peer stops its child process; Ctrl+C stops the share.

Connect their agent

The guest only needs Node.js 18+. Add this entry to an MCP client that supports stdio servers, such as Claude Desktop or Cursor:

Guest · MCP client configuration
{
  "mcpServers": {
    "shared-files": {
      "command": "npx",
      "args": [
        "-y",
        "@mcpwire/cli",
        "join",
        "wire://PASTE_THE_HOST_TICKET_HERE"
      ]
    }
  }
}

Paste the full ticket from the host into wire://.... Merge the entry into an existing mcpServers object rather than replacing other servers. Reload the client’s MCP configuration.

The client launches join and sends MCP messages through its stdin/stdout. Running join in a terminal alone doesn’t open a chat or list tools. Diagnostics go to stderr.

Try a tool call

The guest’s tool list should contain exactly these names:

tools/list · exposed names
read_file
list_directory

Ask the agent to list the host’s demo folder, then read report.txt. Use the host’s absolute path, for example /Users/alex/mcpwire-demo/report.txt. The guest’s home directory is unrelated.

read_file · arguments (replace the path)
{
  "path": "/Users/alex/mcpwire-demo/report.txt"
}
read_file · returned text
Revenue: 42
Contact: [REDACTED_BY_MCPWIRE]

This is the returned text from a real filesystem call through the tunnel. A forced write_file call is rejected before reaching the server:

Blocked call · JSON-RPC error
{
  "code": -32601,
  "message": "[MCPWire Firewall] Tool 'write_file' is not allowed by host."
}

The filesystem and SQLite examples were checked with a real MCP SDK client through separate CLI host and guest processes, using a local DHT bootstrap node. That verifies the protocol and controls; connectivity between two networks still depends on their network conditions.

Choose your controls

Put share flags before --. Protection is opt-in: omitting the flags leaves all tools available, with no redaction, approval prompt, expiry, or call limit.

Share flags and defaults
FlagDefaultBehavior
--allow <list>All tools not deniedExpose only these comma-separated tool names. An explicit empty string exposes no tools.
--deny <list>NoneBlock these tool names. Deny takes precedence over allow.
--redact-secretsOffReplace recognized secrets in outbound responses. --redact is an alias.
--confirmOffAsk the host before forwarding an allowed tool call. Requires an interactive terminal.
--ttl <duration>No expiryClose the session after a duration such as 30m, 90s, or 1h30m. A bare number means seconds.
--max-calls <n>No limitSet a positive call budget across the session’s peers. Blocked calls do not consume it.
--record <file>OffWrite JSONL session events to this path, replacing any existing file.
--name <name>Derived from the server commandSet the server key in the printed client configuration.

Tool names are the boundary

--allow filters tools/list and blocks disallowed tools/call requests. Tool names must match the server exactly. --deny wins if a name appears in both lists. --allow "" exposes no tools.

This does not validate tool arguments, restrict SQL statements, filter other MCP methods such as resources or prompts, or sandbox the server process. Use the server’s own path restrictions and credentials to limit what it can access.

Approve calls in your terminal

Add --confirm to the host command. Answer y to allow a call, n to deny it, or a to allow that tool without further prompts for this share session. Disallowed tools remain blocked. Without an interactive host terminal, approval requests are denied.

Redact recognized patterns

--redact-secrets scrubs recognized token, key, email, and payment-card patterns from outbound responses, replacing matches with [REDACTED_BY_MCPWIRE]. Pattern matching can miss sensitive data. It does not scrub inbound arguments or local logs, and it does not stop an allowed tool from using host credentials.

End the session

The TTL starts after the host announces its ticket, even if nobody connects. The call budget counts forwarded tool calls across peers, including calls that return errors. Discovery and blocked calls don’t consume it. At the budget, the final allowed responses are sent before the session closes. TTL expiry or Ctrl+C can interrupt work still running.

Share SQLite tools

With uvx available on the host, share the SQLite server against your database. The archived server requires MCP Python SDK v1, so keep the mcp<2 constraint:

Host · SQLite
npx -y @mcpwire/cli share \
  --name shared-sqlite \
  --allow "read_query,list_tables,describe_table" \
  --redact-secrets \
  --ttl 30m \
  -- uvx --with 'mcp<2' mcp-server-sqlite --db-path "$HOME/app.db"

Connect the guest using the new ticket, then call read_query with:

read_query · arguments
{
  "query": "SELECT 42 AS revenue, 'root@corp.example.com' AS contact"
}
read_query · returned text
[{'revenue': 42, 'contact': '[REDACTED_BY_MCPWIRE]'}]

The returned row contains revenue 42 and contact [REDACTED_BY_MCPWIRE]. A write_query request is blocked by the tool allowlist.

Allowing a tool named read_query is not a SQL security policy. MCPWire does not inspect the query. For sensitive data, enforce database permissions or use a server that enforces read-only access.

Find commands and tool names for other servers

Record a session

Add these flags to a host share command before -- to cap tool calls and write a local recording:

Additional share flags
--max-calls 20 --record ./session.wirelog

A wirelog is one JSON event per line: session metadata, peer connections, requests, response timings, blocks, redactions, and the session ending. It records argument previews and response metadata, not full response bodies. Open it in Session replay to inspect the timeline locally in your browser.

The file includes the ticket, server command, and unredacted argument previews. Treat recordings as sensitive. The parent directory must exist, and starting a recording overwrites a file at the same path.

When something doesn’t connect

Join times out after 30 seconds
Check that the host process is still running, its TTL and call budget haven’t expired, and the full current ticket was copied. Both machines need DHT/network connectivity. Restrictive firewalls or NAT configurations can prevent a connection.
The client connects, then immediately closes
Check the host terminal for a child-process error. The server executable must be on the host’s PATH, its dependencies installed, and its arguments valid. A ticket can be printed before the server is launched.
No tools, or a tool is blocked
Check the server’s exact tool names and the host’s allow/deny lists. An empty allowlist exposes nothing. A deny entry always takes precedence. Use the command builder to assemble a policy.
File not found or access denied
Use an absolute path from the host’s filesystem, inside the folder passed to the filesystem server. Client configuration paths, by contrast, refer to the guest’s machine.
A connection dropped during a call
Calls are not automatically replayed. Reconnect the MCP client while the host session is active. Check whether an operation completed before retrying a tool with side effects. A restarted host requires a new ticket.

Use a custom DHT bootstrap node

For a controlled network or test environment, point both host and guest processes at existing DHT bootstrap nodes:

Environment · set on both sides
export MCPWIRE_BOOTSTRAP="127.0.0.1:49737"

This loopback address only works for processes on the same machine with a node already listening there. Across machines, use a mutually reachable host and port. Comma-separated nodes are supported. This setting does not create a bootstrap node or provide a relay.

Pick your next server.

Find its launch command, requirements, and tool names.

Server guides