> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryinvesti.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connecting an MCP server that runs on your computer

> How to give the analyst access to an MCP server running on your own computer, and the two easier routes to try first.

Investi connects to MCP servers over the internet: you give it an `https` URL and Investi calls that URL from its own servers on every chat turn. A server running on your own computer isn't reachable that way, for two reasons:

1. **How it talks.** Most local servers are designed to be launched as a program on your machine (the `command` and `args` config you see in most GitHub READMEs). Investi runs in the cloud and can't start programs on your computer; it can only call servers over HTTP.
2. **Where it lives.** Even a local server that speaks HTTP lives at `localhost`, an address that only means something on your own machine. Investi rejects `http://localhost:8000/mcp` outright; it requires `https` and an address that's reachable from the internet.

There are three ways around this, and most people want the first one.

## Start here: which path is yours?

| What you actually want                                                                               | Path                                                                                                                                                               |
| ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| "I want Investi to use Notion / Linear / GitHub / Stripe / Gmail / Slack"                            | [Path A](#path-a-use-a-server-somebody-else-already-hosts): paste a URL. Minutes, nothing installed, no terminal.                                                  |
| "I found an MCP server on GitHub and want its abilities" (web search, docs lookup, an API wrapper)   | [Path A](#path-a-use-a-server-somebody-else-already-hosts) first; a hosted copy may exist. Otherwise [Path B](#path-b-deploy-the-server-instead-of-tunnelling-it). |
| "I wrote my own MCP server" / "the one I want isn't hosted anywhere, but it only calls a public API" | [Path B](#path-b-deploy-the-server-instead-of-tunnelling-it): deploy it once, from a GitHub repo.                                                                  |
| "I want Investi to read my own files, my local database, or an app running on my machine"            | [Path C](#path-c-bridge-and-tunnel-your-own-machine): bridge and tunnel. About ten minutes, and you'll need to be comfortable with a terminal.                     |

The question that decides it: does the server need *your machine specifically*? If it just calls somebody's API, running it on your laptop buys you nothing and costs you a tunnel, an always-on computer, and a security risk. Path C is the last resort, for when the data or the program genuinely lives on your computer.

## Path A: use a server somebody else already hosts

Nothing to install, nothing to keep running, works when your laptop is closed.

**1. Check for an official remote server.** Notion, Linear, GitHub, Stripe, Sentry, Atlassian, Cloudflare and many others publish a hosted MCP URL, usually in their docs under "MCP" or "AI integrations". Paste it into Investi and, if it asks you to sign in, use the **Connect** button. This is the best option when it exists: no third party in the middle.

**2. Or use a connector gateway.** These services already run connectors to thousands of apps and give you a single URL. Nothing is deployed and no code is involved:

| Service                              | How you connect it                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Zapier MCP](https://zapier.com/mcp) | The most non-technical route by a wide margin: a guided dashboard where you pick apps and the specific actions to allow, then connect. No terminal, no config files. URL: `https://mcp.zapier.com/api/v1/connect`. Try the **Connect** button first; if Investi reports the provider doesn't support automatic registration, follow Zapier's "connection token" instructions and add that token under **Headers** instead. |
| [Composio](https://composio.dev)     | One URL for 1,000+ apps: `https://connect.composio.dev/mcp`, with auth set to **Headers** and the header `x-consumer-api-key` set to your API key.                                                                                                                                                                                                                                                                         |
| [Pipedream](https://pipedream.com)   | Similar model, at `https://remote.mcp.pipedream.net/v3`.                                                                                                                                                                                                                                                                                                                                                                   |
| [Smithery](https://smithery.ai)      | A registry that also hosts many community servers, so it's the place to look for a specific GitHub server rather than a big app connector.                                                                                                                                                                                                                                                                                 |

Before you pick one: you're trusting that service with whatever it touches, including any accounts you connect through it. That's a reasonable trade for a documentation search tool and a poor one for your email. These are third parties Investi has no relationship with. Treat them the way you'd treat any service you hand an API key to, and prefer an official vendor URL when one exists.

**What Path A can't do:** run a server that nobody hosts (that's Path B), or reach files and programs on your computer (that's Path C).

## Path B: deploy the server instead of tunnelling it

If the server is just code, whether you wrote it or found it on GitHub, and it doesn't need anything on your computer, deploy it once and you're done forever. No tunnel, no bridge, no laptop that has to stay awake, and a URL that doesn't move. This is strictly better than Path C whenever it's an option.

| Where                                                                                                           | Good for                                                         | How it works                                                                                                                                                                                                                                                                                                                                                    |
| --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [FastMCP Cloud](https://fastmcp.cloud)                                                                          | Python servers (anything built on FastMCP or the MCP Python SDK) | Sign in with GitHub, point it at your repo and the file holding your server, and it builds and deploys to `https://your-project.fastmcp.app/mcp`, redeploying on every push. Free during beta, with a free personal tier planned after. The quickest path if your server is Python.                                                                             |
| [Smithery](https://smithery.ai)                                                                                 | Any language                                                     | Add a `Dockerfile` and a `smithery.yaml` to your repo, connect it at [smithery.ai/new](https://smithery.ai/new), and it builds and hosts it on pushes to `main`. It can also just publish a URL you host elsewhere.                                                                                                                                             |
| [Cloudflare Workers](https://developers.cloudflare.com/agents/model-context-protocol/guides/remote-mcp-server/) | TypeScript servers                                               | Cloudflare maintains a template: `npm create cloudflare@latest -- my-mcp-server --template=cloudflare/ai/demos/remote-mcp-authless`, then `npx wrangler deploy`, giving you `https://<worker>.<account>.workers.dev/mcp`. Generous free tier. Note that the stateful `McpAgent` class needs Durable Objects (paid), while the stateless template above is free. |
| A VPS, Railway, Render, or Cloud Run                                                                            | Anything, full control                                           | Run the server in HTTP mode behind a real domain and put a token in front of it. More work, no platform in the middle.                                                                                                                                                                                                                                          |

Whichever you pick, don't leave it open to the world. A deployed MCP server on a public URL is reachable by anyone who finds it, exactly like a tunnel is. Use the platform's auth if it has one (FastMCP Cloud and Smithery both do), or require a token header of your own and add it in Investi under **Headers**, the same idea as [step 3](#step-3-require-a-secret-header) below.

## Path C: bridge and tunnel your own machine

You have two problems to fix, so the setup has two layers. A *bridge* makes your server speak HTTP, and a *tunnel* gives it an address on the internet:

```
stdio MCP server  ──(supergateway)──>  http://localhost:8765/mcp
                                              │
                                        (ngrok tunnel)
                                              ↓
                     https://your-name.ngrok-free.dev/mcp  ──>  Investi
```

Before you start, know what you're signing up for: two terminal windows that stay open, a computer that has to stay awake, and a server of yours exposed to the internet. Read the [security section](#security) first. If the server can read your files or run commands, skipping step 3 leaves a hole in your machine.

### Step 1: get your server speaking HTTP on a local port

#### If your server already supports HTTP

Many servers accept a transport flag. Run it in Streamable HTTP mode on a spare port and note the path it serves (usually `/mcp`):

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
# the exact flags vary by server; check its README
my-mcp-server --transport streamable-http --port 8765
```

Confirm it's up, then go to step 2:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -i http://localhost:8765/mcp
```

#### If your server is stdio-only (the common case)

Use [supergateway](https://github.com/supercorp-ai/supergateway), a small free tool that wraps a launch-a-program server in an HTTP endpoint. Take the launch command from the server's README and pass it as one quoted string to `--stdio`.

A README config like this:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/notes"]
    }
  }
}
```

becomes this, with `command` and `args` joined by spaces:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
npx -y supergateway \
  --stdio "npx -y @modelcontextprotocol/server-filesystem /Users/me/notes" \
  --outputTransport streamableHttp \
  --port 8765
```

Your server is now at `http://localhost:8765/mcp`. Leave this terminal running.

Two notes:

* Add `--stateful --sessionTimeout 60000` if your server keeps state between tool calls (a browser session, a database connection). The default starts a fresh copy of the server for every request, which is more robust but slower and forgetful.
* Python servers work the same way: `--stdio "uvx mcp-server-git"`.

### Step 2: put it on the internet with ngrok

A tunnel takes what's running on a port on your machine and gives it a public web address. We recommend [ngrok](https://ngrok.com) for this. Its free tier gives you a stable URL that doesn't change between restarts, and endpoints that stay online indefinitely. Both matter here, because the URL is saved in your Investi settings, and a URL that rotates means reconnecting every day. It also lets you require a secret on every request (step 3) without writing any code. See [other tunnel providers](#other-tunnel-providers) for Tailscale and Cloudflare.

1. **Install and authenticate** (a free account is required):

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
brew install ngrok            # or download from ngrok.com/downloads
ngrok config add-authtoken <your-token-from-the-dashboard>
```

2. **Find your permanent domain.** The free plan assigns your account one dev domain, like `detract-congress-reviver.ngrok-free.dev`. It's shown in the ngrok dashboard, and in the `Forwarding` line the first time you run a tunnel.

3. **Start the tunnel**, pinned to that domain so the URL is identical every time:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
ngrok http 8765 --url https://your-name.ngrok-free.dev
```

Your MCP endpoint is now `https://your-name.ngrok-free.dev/mcp`. Don't connect it yet. Right now anyone who guesses that URL has your tools.

Free-tier ceilings are 20,000 requests and 1 GB of traffic per month, and 3 online endpoints. Ordinary chat use stays well inside that.

### Step 3: require a secret header

The tunnel URL is public and unauthenticated by default. If you've exposed a filesystem or shell server, anyone who finds the URL can read and write your files. Fix it by making ngrok reject every request that doesn't carry a secret you choose.

Generate a token:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
openssl rand -hex 32
```

Save this as `mcp-policy.yml`, pasting your token in place of `<YOUR-TOKEN>`:

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
on_http_request:
  - expressions:
      - "!getReqHeader('X-Investi-Token').exists(v, v == '<YOUR-TOKEN>')"
    actions:
      - type: deny
        config:
          status_code: 401
```

Restart the tunnel with the policy attached:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
ngrok http 8765 \
  --url https://your-name.ngrok-free.dev \
  --traffic-policy-file mcp-policy.yml
```

Verify that the lock works. This must return `401`:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -s -o /dev/null -w '%{http_code}\n' https://your-name.ngrok-free.dev/mcp
```

Requests without the header are now rejected at ngrok's edge, before they ever reach your machine.

### Step 4: connect it in Investi

In Investi, add an MCP server with:

| Field            | Value                                  |
| ---------------- | -------------------------------------- |
| **URL**          | `https://your-name.ngrok-free.dev/mcp` |
| **Auth**         | Headers                                |
| **Header name**  | `X-Investi-Token`                      |
| **Header value** | the token from step 3                  |

Investi probes the server immediately (up to 15 seconds) and shows the result:

* **Connected**: you'll see the tool list. You're done; the analyst can use those tools on every turn.
* **Needs auth**: the token is missing or doesn't match. Re-check step 3.
* **Error**: the URL is unreachable or isn't an MCP endpoint. See [troubleshooting](#troubleshooting).

Your token is encrypted at rest and never shown again; you'll see a "credentials stored" state instead. You can connect up to 20 MCP servers.

## Keeping it running

Both processes, the bridge and the tunnel, must stay up. Close either terminal, put the laptop to sleep, or change networks, and the server goes offline.

That's a soft failure, not a broken chat: Investi health-checks each server at the start of every turn, skips any that are down (marking them `error`), and tells you which ones it skipped. When your machine comes back, the server reconnects itself on the next turn and flips back to `connected`, with no re-testing needed. Only a `needs_auth` state requires you to do something.

For something you use daily, run both as background services rather than in terminals: ngrok has a [background service](https://ngrok.com/docs/agent/#background-service) mode, and on macOS `launchd` (or `pm2` for the bridge) will keep the gateway alive across reboots.

The real fix, if this becomes permanent: stop tunnelling. If the server didn't actually need your files after all, go to [Path A](#path-a-use-a-server-somebody-else-already-hosts) or [Path B](#path-b-deploy-the-server-instead-of-tunnelling-it). Then there's no laptop in the path, no bridge to babysit, and no request quota. A tunnel is the right tool for trying something out, not for infrastructure you depend on.

## Other tunnel providers

We walk through ngrok because it's the only free option that gives you both a URL that survives a restart and a way to check a secret before traffic reaches your machine. If you'd rather use something else, here's the honest comparison. Note that swapping the tunnel means solving the token problem yourself.

| Option                                            | URL stability                | Can check a token?             | Verdict                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------------------------------- | ---------------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **ngrok** (free)                                  | Stable dev domain            | Yes, via Traffic Policy        | What this guide uses.                                                                                                                                                                                                                                                                                                                                                                                       |
| **Tailscale Funnel**                              | Stable `*.ts.net`            | No                             | Easiest install (a normal desktop app) and no request quota, so it's tempting. But Funnel deliberately has no authentication layer, and requests for one are still open feature requests. You'd have to put Caddy or nginx in front of your server to check the token, which is more work than ngrok, not less. Fine if you already run Tailscale and don't mind that. Ports are limited to 443/8443/10000. |
| **Cloudflare named tunnel**                       | Stable, your own domain      | Yes, via Access service tokens | Genuinely solid and free, and service tokens are header-based so they work with Investi. The catch is the prerequisite: you must own a domain with its DNS on Cloudflare, plus tunnel and Access setup. Good if that's already true of you.                                                                                                                                                                 |
| **Cloudflare quick tunnel** (`trycloudflare.com`) | New random URL every restart | No                             | Avoid for MCP, even though it's the most commonly recommended option online. Quick tunnels don't support Server-Sent Events, which MCP's Streamable HTTP transport relies on, and the rotating URL means reconnecting in Investi constantly.                                                                                                                                                                |

## Troubleshooting

Match the message Investi shows against this table.

| Message                                                              | Cause                                                                                 |
| -------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| "The MCP URL must use https."                                        | You pasted the `http://localhost` URL. Use the tunnel's `https` URL.                  |
| "The MCP host resolves to a non-public address."                     | The URL points at a private or loopback address. Same fix.                            |
| "The MCP host could not be resolved."                                | Tunnel isn't running, or the domain is mistyped.                                      |
| "The server did not respond within 15s."                             | The bridge isn't running, or the tunnel points at the wrong port.                     |
| "The server returned HTTP 404."                                      | Wrong path. Streamable HTTP servers usually serve `/mcp`; append it.                  |
| "The server returned HTTP 502."                                      | The tunnel is up but nothing is listening on that local port.                         |
| Needs auth / "rejected the connection as unauthenticated (HTTP 401)" | Header name or token doesn't match the policy. They're case-sensitive.                |
| "Connection failed: ..."                                             | Reachable, but not speaking MCP. Often the server's root URL instead of its MCP path. |
| A tool call times out                                                | A single tool call gets 60 seconds. Slow local work (large file scans) can exceed it. |

Two more, specific to this setup:

* **An HTML page or a JSON parse error instead of a tool list.** ngrok's free tier shows a browser warning page on some traffic. It doesn't normally affect MCP clients, but if you hit it, add a second header in Investi: `ngrok-skip-browser-warning: 1`.
* **Using SSE instead of Streamable HTTP.** Investi picks the transport from the URL: a path ending in `/sse` means the older SSE transport, anything else means Streamable HTTP. So the URL's path has to match how your server is actually running: `/mcp` for `--outputTransport streamableHttp`, `/sse` for supergateway's default SSE mode.

## Security

On Path A, the thing to weigh is who you're trusting: an official vendor URL is about as safe as using that vendor's app, while a connector gateway is a third party sitting between Investi and your accounts. Prefer the official URL when one exists, and where a gateway lets you choose which actions to expose (Zapier does), enable only the ones you need.

On Path B, remember that deploying doesn't make a server private. Turn on the platform's authentication or require your own token header. An open URL is an open URL whether it's a tunnel or a Worker.

Path C is the one that deserves real care, because you're handing an AI agent live access to your computer:

* **Never run the tunnel without the token check** from step 3. An open tunnel to a filesystem server is a remote-access hole in your machine.
* **Scope the server as narrowly as it allows.** Point a filesystem server at one project directory, not your home folder. Prefer read-only modes.
* **Think about what the tools can destroy.** `write_file`, `move_file`, and anything shell-shaped can cause real damage if the analyst misfires. Investi prefixes MCP tool names with the server name (`filesystem_write_file`) in the chat so you can see exactly which server a call went to.
* **Rotate the token** by editing `mcp-policy.yml`, restarting the tunnel, and updating the header in Investi.
* **Disconnect when you're done experimenting.** Deleting the server in Investi also deletes the stored credentials; stop the tunnel too.

Investi never sees your MCP server's own upstream API keys. Those stay in the environment where you launch the server.
