bowtie-mcp
Officialby bowtieworks
README.md
# Bowtie MCP Server
[](https://github.com/bowtieworks/bowtie-mcp/actions/workflows/ci.yml)
[](https://pypi.org/project/bowtie-mcp/)
[](https://pypi.org/project/bowtie-mcp/)
[](LICENSE)
An [MCP](https://modelcontextprotocol.io) server for the [Bowtie](https://bowtie.works) control plane. Manage your Bowtie cluster — policies, devices, DNS, users, and more — using natural language through your LLM of choice or any MCP-capable client.
## Install
```bash
pip install bowtie-mcp
```
Or run without installing using [uvx](https://docs.astral.sh/uv/):
```bash
uvx bowtie-mcp
```
## Quick Start
### Claude Code
```bash
claude mcp add bowtie \
-e BOWTIE_HOST="https://bt0.example.com" \
-e BOWTIE_USERNAME="admin@example.com" \
-e BOWTIE_PASSWORD="your-password" \
-- uvx bowtie-mcp
```
### Claude Desktop
Add to your `claude_desktop_config.json`:
```json
{
"mcpServers": {
"bowtie": {
"command": "uvx",
"args": ["bowtie-mcp"],
"env": {
"BOWTIE_HOST": "https://bt0.example.com",
"BOWTIE_USERNAME": "admin@example.com",
"BOWTIE_PASSWORD": "your-password"
}
}
}
}
```
### Cursor / Windsurf
Add to `.cursor/mcp.json` or your editor's MCP config:
```json
{
"mcpServers": {
"bowtie": {
"command": "uvx",
"args": ["bowtie-mcp"],
"env": {
"BOWTIE_HOST": "https://bt0.example.com",
"BOWTIE_USERNAME": "admin@example.com",
"BOWTIE_PASSWORD": "your-password"
}
}
}
}
```
### HTTP Streaming Mode
For clients that connect over HTTP instead of spawning a local stdio process, start the server in one of FastMCP's HTTP transports:
```bash
uvx bowtie-mcp --transport streamable-http --port 8080
```
This binds to `127.0.0.1:8080` and exposes the recommended Streamable HTTP endpoint at `http://127.0.0.1:8080/mcp`.
Legacy SSE is also available:
```bash
uvx bowtie-mcp --transport sse --port 8080
```
The SSE endpoint is `http://127.0.0.1:8080/sse`. During the handshake, FastMCP tells the client to post subsequent messages to the matching `http://127.0.0.1:8080/messages/` endpoint.
## Authentication
The server authenticates to your Bowtie controller using admin credentials — the same approach used by the [Bowtie Terraform provider](https://registry.terraform.io/providers/bowtieworks/bowtie/latest).
| Variable | Required | Description |
|---|---|---|
| `BOWTIE_HOST` | Yes | Controller HTTPS endpoint (e.g., `https://bt0.example.com`) |
| `BOWTIE_USERNAME` | Yes | Admin email address |
| `BOWTIE_PASSWORD` | Yes | Admin password |
| `BOWTIE_MCP_SKIP_CONFIRMATION` | No | Set to `true` to skip write confirmation prompts |
Credentials are used by the local MCP server process to authenticate with your controller. They are never sent to or visible by the LLM.
## What You Can Do
Ask your LLM things like:
- *"List all pending devices and approve the ones from the engineering team"*
- *"Create a policy that gives the sales team access to the CRM on 10.0.5.0/24 port 443"*
- *"Why can't device X reach the production database?"*
- *"Audit our policies for anything overly permissive"*
- *"Set up DNS for internal.example.com pointing at 10.0.0.53"*
### Available Tools
**Read** (30+ tools) — List and inspect users, devices, device groups, user groups, policies, resources, resource groups, DNS configs, sites, collections, block lists, threat categories, controllers, route exclusions, and API keys.
**Write** (25+ tools) — Create, update, and delete all of the above. All write operations require explicit confirmation before executing (see below).
**Guided Workflows** (4 prompts):
| Prompt | Description |
|---|---|
| `onboard-team` | Create a user group, resources, resource group, and access policy |
| `audit-policies` | Review all policies for overly permissive rules |
| `troubleshoot-access` | Diagnose why a user/device can or can't reach a destination |
| `review-pending-devices` | Batch approve or reject pending devices |
### Write Confirmation
All write tools use a two-step confirmation pattern. The first call returns a preview of the planned change. Call again with `confirm=true` to execute. This prevents accidental mutations.
Tool responses are returned as structured JSON-compatible objects rather than pre-serialized JSON strings, so MCP clients can inspect fields directly.
Set `BOWTIE_MCP_SKIP_CONFIRMATION=true` to bypass this for automation or CI workflows.
## Development
```bash
git clone https://github.com/bowtieworks/bowtie-mcp.git
cd bowtie-mcp
pip install -e ".[dev]"
pytest
```
See [CONTRIBUTING.md](CONTRIBUTING.md) for more details.
## License
[MIT](LICENSE)
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues