Metadata-Version: 2.4
Name: torreable
Version: 0.2.0
Summary: Publish static websites as Tor hidden services via MCP
Project-URL: Homepage, https://github.com/DOsinga/torreable
Project-URL: Repository, https://github.com/DOsinga/torreable
Author-email: Douwe Osinga <douwe.osinga@gmail.com>
License: MIT
Keywords: hidden-service,mcp,tor
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.10
Requires-Dist: aiohttp
Requires-Dist: mcp
Requires-Dist: stem
Description-Content-Type: text/markdown

# Torreable

Publish static websites as Tor hidden services (.onion sites) via MCP.

## Requirements

- Python 3.10+
- Tor running with control port enabled

### Installing Tor

**macOS:**
```bash
brew install tor
brew services start tor
```

**Linux:**
```bash
apt install tor
systemctl start tor
```

Make sure Tor has a control port. Add to `/etc/tor/torrc` or `~/.torrc`:
```
ControlPort 9051
```

## Installation

### Click the button to install:

[![Install in Goose](https://block.github.io/goose/img/extension-install-dark.svg)](https://block.github.io/goose/extension?cmd=uvx&arg=torreable&id=torreable&name=Torreable&description=Publish%20static%20websites%20as%20Tor%20hidden%20services%20via%20MCP)

### Or install manually:

Go to `Advanced settings` -> `Extensions` -> `Add custom extension`. Name to your liking, use type `STDIO`, and set the `command` to `uvx torreable`. Click "Add Extension".

## Tools

| Tool | Description |
|------|-------------|
| `create_site(name, directory)` | Register a static site |
| `preview(name)` | Local preview at localhost |
| `publish(name)` | Publish to Tor network |
| `unpublish(name)` | Take offline, keep address |
| `destroy(name)` | Delete site and address |
| `list_sites()` | Show all sites and status |

## How it works

1. Sites are stored in `~/.torreable/sites/`
2. Each site keeps its Tor private key, so the .onion address persists
3. Publishing starts a local HTTP server and creates an ephemeral Tor hidden service
4. Sites are only reachable while torreable is running

## Example

```
> create_site("myblog", "/path/to/blog/dist")
Created site 'myblog' -> /path/to/blog/dist

> preview("myblog")
Preview running at http://localhost:52431

> publish("myblog")
Published at http://abc123...xyz.onion

> unpublish("myblog")
Unpublished 'myblog'. Address abc123...xyz.onion preserved for later.
```
