Metadata-Version: 2.5
Name: shell2mcp
Version: 0.1.1
Summary: Serve a folder as a local MCP server with Pi's coding tools (read, bash, edit, write, grep, find, ls). Localhost only, optional cloudflared tunnel.
Author: theabbie
License-Expression: MIT
License-File: LICENSE
Keywords: agent,cloudflared,mcp,model-context-protocol,shell,tools
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# shell2mcp

Serve a folder as an [MCP](https://modelcontextprotocol.io) server that offers the same coding tools as the
[Pi](https://pi.dev) agent: `read`, `bash`, `edit`, `write`, `grep`, `find` and `ls`. Tool names and parameter
schemas match Pi's, so a model that knows Pi's tools can use them as is. Pure Python standard library, no dependencies.

By itself it listens on **127.0.0.1 only**. Nothing leaves your machine unless you add `--tunnel` or run your own tunnel.

## Install and run

```bash
pip install shell2mcp          # or: uvx shell2mcp
shell2mcp                      # serve the current folder on 127.0.0.1:8765 (a free port if that is taken)
```

The MCP URL is printed on stdout (everything else goes to stderr), for example
`http://127.0.0.1:8765/3f9c.../mcp`. The random path segment is the only access control, so treat the URL as a secret.

```
shell2mcp [--root DIR] [--port N] [--secret S] [--read-only] [--tunnel] [--version]
```

| Option | Meaning |
|---|---|
| `--root DIR` | folder the tools may touch (default: current directory) |
| `--port N` | local port, `0` for any free port (default 8765, or a free port if 8765 is taken; an explicit busy port is an error) |
| `--secret S` | fixed URL path secret instead of a random one |
| `--read-only` | only expose `read`, `grep`, `find`, `ls` |
| `--tunnel` | also publish through a cloudflared quick tunnel and print the public URL |

## With cloudflared

Built in:

```bash
shell2mcp --tunnel                 # prints https://<random>.trycloudflare.com/<secret>/mcp
URL=$(shell2mcp --tunnel | head -1)   # the URL is the only thing on stdout
```

Or run the tunnel yourself, since the server is a plain local HTTP endpoint:

```bash
shell2mcp --port 8765 &
cloudflared tunnel --url http://127.0.0.1:8765
# MCP URL: https://<random>.trycloudflare.com/<secret>/mcp  (the secret is printed by shell2mcp)
```

Add that URL as a remote MCP server (Streamable HTTP, no auth) in any MCP client.

## Tools

| Tool | What it does |
|---|---|
| `read` | read a text file with `offset`/`limit` (2000 lines or 50KB max) |
| `bash` | run a command in the root, 60 s default and 120 s maximum timeout, minimal environment |
| `edit` | exact-text replacements: `edits[{oldText,newText}]`, each must be unique and non-overlapping |
| `write` | create or overwrite a file, creating parent folders |
| `grep` | regex or literal search with `glob`, `ignoreCase`, `context`, `limit` |
| `find` | glob file search |
| `ls` | list a directory |

Paths are relative to `--root`; absolute paths and `..` that leave it are rejected.

## Security

`bash` runs real commands. The folder restriction applies to the file tools, but a shell command can still read
other files your user can read. Only tunnel it on a machine and account you are happy to expose, prefer a
throwaway folder or container, use `--read-only` when you can, and stop it when you are done. Everything the model
reads is sent to whichever model provider the MCP client uses.

## License

MIT
