Skip to main content
Glama
litportnet

Litport MCP server

Official
README.md
# Litport MCP server

A [Model Context Protocol](https://modelcontextprotocol.io) server for the
[Litport](https://litport.net) account API: inspect proxy tokens, usage, pools, geo targeting, and
build ready-to-use proxy connection URLs, directly from a coding agent or chat client.

The server is **read-only**. None of its tools can create, modify, delete, or disable a token, and
none of them can spend account balance — only `web/app/views/users/ports.pug`'s dashboard export and
the Litport dashboard itself do that.

## Install and configure

Create an API key at [litport.net/users/settings](https://litport.net/users/settings), then add the
server to your MCP client's config with `LITPORT_API_KEY` in its `env` block.

### Claude Code

```sh
claude mcp add litport -e LITPORT_API_KEY=lit_your_key_here -- npx -y @litportnet/litport-mcp
```

Or in `.mcp.json`:

```json
{
  "mcpServers": {
    "litport": {
      "command": "npx",
      "args": ["-y", "@litportnet/litport-mcp"],
      "env": {
        "LITPORT_API_KEY": "lit_your_key_here"
      }
    }
  }
}
```

### Claude Desktop

Add the same block to `claude_desktop_config.json` under `mcpServers`:

```json
{
  "mcpServers": {
    "litport": {
      "command": "npx",
      "args": ["-y", "@litportnet/litport-mcp"],
      "env": {
        "LITPORT_API_KEY": "lit_your_key_here"
      }
    }
  }
}
```

### Cursor

Add the same block to `.cursor/mcp.json`, or use Cursor's Settings → MCP → Add new MCP Server with
command `npx -y @litportnet/litport-mcp` and `LITPORT_API_KEY` in the environment variables field.

## Credential exposure — two options

Proxy tokens carry a `username`/`password` pair. Putting every password from `list_tokens` into the
model's context by default is unnecessary exposure for a browse operation, so the server ships two
ways to reach a real password:

| Option | Behavior |
| --- | --- |
| Default (`LITPORT_MCP_REVEAL_CREDENTIALS` unset) | `list_tokens` masks each token's `password` (`null`, with `passwordSet: true`), and adds a `hint` pointing at `get_token_credentials` or `build_proxy_url`. `get_token_credentials` and `build_proxy_url` always return the real password for the one token requested. |
| `LITPORT_MCP_REVEAL_CREDENTIALS=1` | `list_tokens` returns every password unmasked, alongside everything else. |

Either way, nothing is ever permanently unreachable — the default just keeps bulk listings out of the
model's context until a specific token is named.

## Tools

| Tool | Calls the API? | Description |
| --- | --- | --- |
| `list_tokens` | yes | List proxy tokens, paginated by cursor; masks passwords by default. |
| `get_token_credentials` | yes | Get one token by id, including its real password. |
| `get_token_usage` | yes | Get bandwidth usage for a token, optionally by domain and/or hourly charges. |
| `list_pools` | yes | List PPG pools and the hubs they connect through. |
| `list_targeting_options` | yes | List available countries, regions, or cities for one or more pools. |
| `get_account` | yes | Get account balance and plan. |
| `explain_proxy_error` | no (local) | Look up an `X-Proxy-Error-Code` or SOCKS5 reply: what happened, whether to retry, what to do. |
| `build_proxy_url` | yes | Compose a ready-to-use proxy connection URL for a token, with pool/geo/session targeting. |
| `search_docs` | yes (public) | Search the Litport documentation index for pages matching a query. |
| `get_doc` | yes (public) | Fetch a Litport documentation page as markdown. |

All ten tools are annotated `readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true`.

### build_proxy_url and the two token types

A **pay-per-GB** token is request-selected: `build_proxy_url` appends the pool, geo and session
segments to the username and picks the port matching the chosen protocol. A token with a saved pool
takes no `pool` argument and refuses a conflicting one; a token without a saved pool requires `pool`,
because the pool sets the price.

An **unlimited** token is assigned exactly one endpoint, so it takes no pool, geo or session
arguments — passing them is refused by name rather than silently producing a username the proxy
rejects. If its hub is no longer in service, the tool says so instead of returning a broken URL.

Parameters are validated against the published rules before anything is returned, so a malformed
country slug or an out-of-range session lifetime is reported without spending a request.

## Environment variables

| Variable | Required | Description |
| --- | --- | --- |
| `LITPORT_API_KEY` | yes | Your Litport account API key (`lit_…`/`ltp_…`). |
| `LITPORT_API_URL` | no | Override the API base URL. Defaults to `https://litport.net`. |
| `LITPORT_MCP_REVEAL_CREDENTIALS` | no | Set to `1` to have `list_tokens` return real passwords. |

## Development

```sh
npm install
npm test               # node --test test/
npm run generate-contracts   # regenerate src/contracts.generated.js from the web app
```

`src/contracts.generated.js` is generated from the web application's canonical contract modules and
is never hand-edited.

## License

MIT

## Contracts

`src/contracts.generated.js` vendors the proxy error reference and pay-per-GB parameter rules from
the Litport web application, so `explain_proxy_error` and `build_proxy_url` answer without a network
call. It is generated, not hand-edited, and a parity check in the application fails if the two ever
disagree.