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

# Uplink

> Expose a local MCP server as a Smithery connection without deploying it.

**Uplink** exposes an MCP server running on any machine as a regular Smithery connection. The CLI holds a secure tunnel open and forwards every request from Smithery to the local process, so agents and apps reach it through the same REST surface as any hosted server.

Uplink is useful when:

* You're developing an MCP server and want to test it against a real agent before publishing.
* The server needs something only a specific machine can reach — a browser, a local database, an SSH key, a code editor.
* You want to run a private tool for yourself or your team without hosting it.

## Quick Start

Uplink uses `smithery mcp add`. If the URL resolves to `localhost` (or `127.0.0.1`), or you pass a command in place of a URL, the CLI opens an uplink tunnel in the background and registers the connection against your namespace.

<Tabs>
  <Tab title="Smithery package" icon="package">
    ```bash theme={null}
    # Pull a hosted Smithery package and run it locally — no setup required
    smithery mcp add smithery/mouseless
    ```

    [`smithery/mouseless`](https://github.com/smithery-ai/mouseless) is our computer-use MCP. The CLI launches it on your machine and exposes it through Smithery.
  </Tab>

  <Tab title="Local HTTP server" icon="globe">
    ```bash theme={null}
    # Point at an MCP server already running locally
    smithery mcp add http://localhost:9090/mcp --id chrome
    ```
  </Tab>

  <Tab title="Stdio command" icon="terminal">
    ```bash theme={null}
    # Let the CLI spawn and manage a stdio MCP server
    smithery mcp add --id chrome -- npx -y @chromedevtools/chrome-devtools-mcp
    ```
  </Tab>
</Tabs>

The CLI stays running and prints live status:

```
Uplink connected → my-app/chrome (status: connected)
```

While the CLI is running, `my-app/chrome` behaves like any other Smithery connection.

## Call it like any other connection

Reach the uplinked server through the standard Smithery surface — no special transport handling required:

<Tabs>
  <Tab title="CLI" icon="terminal">
    ```bash theme={null}
    smithery tool list chrome
    smithery tool call chrome navigate '{"url": "https://smithery.ai"}'
    ```
  </Tab>

  <Tab title="TypeScript" icon="braces">
    ```typescript theme={null}
    import Smithery from '@smithery/api';
    import { createConnection } from '@smithery/api/mcp';
    import { createMCPClient } from '@ai-sdk/mcp';

    const smithery = new Smithery();

    const { transport } = await createConnection({
      client: smithery,
      namespace: 'my-app',
      connectionId: 'chrome',
    });

    const mcpClient = await createMCPClient({ transport });
    const tools = await mcpClient.tools();
    ```
  </Tab>
</Tabs>

## How it works

```mermaid theme={null}
flowchart LR
    subgraph Local[Your machine]
        direction TB
        M[Local MCP server]
        C[Smithery CLI]
    end
    subgraph Smithery
        G[Connect gateway]
    end
    subgraph App[Your application]
        A[Agent / client]
    end
    C -- persistent WebSocket --> G
    M -- stdio or HTTP --> C
    A -- MCP --> G
    G -- tunneled --> C
```

When `smithery mcp add` sees a localhost URL or a trailing command, it:

1. Registers a connection on your namespace marked as uplink-backed.
2. Opens a persistent WebSocket to Smithery scoped to that connection.
3. Connects to your local HTTP server, or spawns the command as a subprocess, and bridges JSON-RPC between the WebSocket and the local process.

Incoming requests flow over the WebSocket to your local MCP server and back. The tunnel is transparent to the MCP spec: stateful sessions, progress notifications, server-initiated messages (sampling, elicitation, roots), and streamed responses all pass through. Auth, permissions, service tokens, and session handling are identical to hosted connections — uplink is a transport detail underneath the existing surface.

## Connection lifecycle

An uplink connection reports one of:

| Status         | Description                                                                                     |
| -------------- | ----------------------------------------------------------------------------------------------- |
| `connected`    | Tunnel is live; requests are being forwarded                                                    |
| `disconnected` | No CLI is attached (never paired, exited, or lost its WebSocket). Cached tool lists are dropped |
| `error`        | The tunnel or the local process errored                                                         |

When the CLI exits, the connection stays in the namespace but its `serverInfo` is cleared, so callers don't see a stale tool list. Re-running `smithery mcp add` with the same `--id` reattaches the tunnel.

## One tunnel per connection

Each connection can carry only one live tunnel at a time. Running `smithery mcp add` for the same `--id` from a second machine fails with a conflict. Pass `--force` to take over:

```bash theme={null}
smithery mcp add http://localhost:9090/mcp --id chrome --force
```

Use `--force` deliberately — the previous CLI is disconnected immediately, and any requests it was mid-handling fail.

## Security

* Traffic is end-to-end TLS from Smithery to the CLI. The local MCP server speaks plain stdio or loopback HTTP to the CLI as it normally would.
* Uplink forwards arbitrary traffic to a process on the host machine. Only uplink servers you trust, and treat any trailing command as you would any other local executable.

## Limitations

* **One tunnel per connection.** See [above](#one-tunnel-per-connection).
* **Availability follows the host.** If the CLI is offline, the connection reports `disconnected` and calls fail fast. Uplink is a development and personal-automation primitive, not a hosting solution — publish your server to Smithery when you're ready for production.
* **Latency includes your network.** Every request makes a round trip to the host machine.
