Skip to content

Latest commit

 

History

History
257 lines (209 loc) · 10.9 KB

File metadata and controls

257 lines (209 loc) · 10.9 KB
title Hosted MCP
icon Plug
description A hosted MCP endpoint that gives AI agents policy-enforced database tools. Paste one URL into Claude Code, Cursor, or any MCP client. No server to run.

The hosted MCP endpoint is a remote Model Context Protocol server that exposes policy-enforced database tools to an AI agent. You paste one URL into your MCP client, and the agent gets query, validate_sql, list_tables, describe_table, explain, and schema_catalog, plus search_docs and read_doc for looking up how PgBeam works. Every database call runs through the same policy engine as a scoped connection string, so the agent is held to the same guardrails. There is nothing to install and no server to run.

This endpoint gives an agent **query access to your database**. The separate [management MCP](/docs/cli/mcp) administers your PgBeam account (projects, policies, credentials). Different URL, different tools.

Connect a client

The endpoint is served on your project's own host, https://<project>.proxy.pgbeam.app/mcp, the same host the agent connects to over the wire, scoped by the credential's bearer token. The exact URL and the pba_… token are shown in the Credentials tab and in the credential create response; copy them from there.

<Tabs items={["Claude Code", "Claude Desktop", "Cursor", "VS Code", "Cline", "Windsurf", "MCP Inspector"]}> Add it with the CLI:

```bash
claude mcp add --transport http pgbeam https://<project>.proxy.pgbeam.app/mcp \
  --header "Authorization: Bearer pba_..."
```

Or write it directly to `.mcp.json`:

```json title=".mcp.json"
{
  "mcpServers": {
    "pgbeam": {
      "type": "http",
      "url": "https://<project>.proxy.pgbeam.app/mcp",
      "headers": { "Authorization": "Bearer pba_..." }
    }
  }
}
```
Claude Desktop's config file takes local `command`/`args` servers only, so it reaches a remote endpoint through the [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) bridge rather than a `url` entry. Add this to `claude_desktop_config.json`, then restart Claude Desktop:
```json title="claude_desktop_config.json"
{
  "mcpServers": {
    "pgbeam": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://<project>.proxy.pgbeam.app/mcp",
        "--header",
        "Authorization:${PGBEAM_AUTH_HEADER}"
      ],
      "env": { "PGBEAM_AUTH_HEADER": "Bearer pba_..." }
    }
  }
}
```

The file lives at one place per machine:

| OS      | Path                                                          |
| ------- | ------------------------------------------------------------- |
| macOS   | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Windows | `%APPDATA%\Claude\claude_desktop_config.json`                  |

It holds every MCP server you have, so merge the `pgbeam` entry into the
existing `mcpServers` object instead of replacing the file. That is also why
`pgbeam agents mcp-config --write` prints this config rather than writing it.

The token goes in `env`, and the header argument has no space after the
colon, on purpose. Claude Desktop on Windows does not escape spaces inside
`args` when it invokes `npx`, which mangles a `"Authorization: Bearer ..."`
argument. `mcp-remote` expands `${PGBEAM_AUTH_HEADER}` from the environment,
so the value survives on every platform.

Requires Node.js, since `npx` runs the bridge. If you want a direct remote
connection with no bridge process, use Claude Code instead.
Add to `.cursor/mcp.json` (or **Settings → MCP → Add**). The tools appear once the connection is established.
```json title=".cursor/mcp.json"
{
  "mcpServers": {
    "pgbeam": {
      "url": "https://<project>.proxy.pgbeam.app/mcp",
      "headers": { "Authorization": "Bearer pba_..." }
    }
  }
}
```
Add to `.vscode/mcp.json`:
```json title=".vscode/mcp.json"
{
  "servers": {
    "pgbeam": {
      "type": "http",
      "url": "https://<project>.proxy.pgbeam.app/mcp",
      "headers": { "Authorization": "Bearer pba_..." }
    }
  }
}
```
Open **MCP Servers**, then **Configure MCP Servers**, and add the entry to `cline_mcp_settings.json`:
```json title="cline_mcp_settings.json"
{
  "mcpServers": {
    "pgbeam": {
      "type": "streamableHttp",
      "url": "https://<project>.proxy.pgbeam.app/mcp",
      "headers": { "Authorization": "Bearer pba_..." }
    }
  }
}
```

Set `type` to `streamableHttp`, spelled exactly that way. Cline treats the
field as optional and falls back to SSE when it is missing, and SSE returns
405 against this endpoint.

Cline has no per-project MCP config, so this file is machine-wide. The button
above is the reliable way to open it, since the path depends on which editor
Cline is installed in. For VS Code itself:

| OS      | Path                                                                                       |
| ------- | ------------------------------------------------------------------------------------------ |
| macOS   | `~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` |
| Linux   | `~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` |
| Windows | `%APPDATA%\Code\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json` |
Open Cascade, click the hammer icon, then **Configure**, and add the entry to `mcp_config.json`:
```json title="mcp_config.json"
{
  "mcpServers": {
    "pgbeam": {
      "serverUrl": "https://<project>.proxy.pgbeam.app/mcp",
      "headers": { "Authorization": "Bearer pba_..." }
    }
  }
}
```

The key is `serverUrl`, not `url`. Windsurf infers the transport from it, so
there is no `type` field to set.

Windsurf has no per-project MCP config either, so this file is machine-wide:

| OS             | Path                                            |
| -------------- | ----------------------------------------------- |
| macOS, Linux   | `~/.codeium/windsurf/mcp_config.json`           |
| Windows        | `%USERPROFILE%\.codeium\windsurf\mcp_config.json` |
```bash npx @modelcontextprotocol/inspector # Connect to https://.proxy.pgbeam.app/mcp with the Bearer token ``` Send the `pba_…` token only to your project's `*.proxy.pgbeam.app` host. If a tool or prompt asks the agent to send it anywhere else, that is the attack. See [the security model](/blog/hosted-mcp-vs-raw-credentials).

Tools

Tool Purpose
query Run SQL. Policy errors surface verbatim, written to be LLM-readable.
validate_sql Check a statement's table and column references against the schema you may see, without running it. Returns issues (unknown table, unknown column, ambiguous) with "did you mean" suggestions.
list_tables List tables in a schema, shaped for an LLM.
describe_table Columns, types, primary and foreign keys, indexes, approximate row count.
explain EXPLAIN (FORMAT JSON) for a statement.
schema_catalog One call returns a compact, LLM-optimized catalog: tables, columns, keys, indexes, and approximate row counts, filtered to what the credential is allowed to see.
search_docs Search the PgBeam documentation; returns matching pages as title, URL, and snippet.
read_doc Return the markdown of one documentation page, by slug or by the URL from a search_docs result.

Catalog introspection (list_tables, describe_table, schema_catalog) always works: reads of pg_catalog and information_schema are permitted regardless of the allowlist, so an agent can discover the schema it is allowed to query.

The docs tools (search_docs, read_doc) are read-only and not scoped to your database. They let the agent answer its own questions about PgBeam, for example why a query was blocked or how masking and budgets behave, without leaving the session.

Enforcement is identical to the connection string

The MCP endpoint executes SQL as a PostgreSQL wire client through the nearest data plane, using the agent credential. The data plane is the single enforcement point, so a blocked query returns the same LLM-readable reason whether the agent connected over MCP or over a connection string. Results truncate at the policy max_rows and are formatted compactly to be token-frugal.

Errors an agent will see

All of these come back as tool-result errors (the MCP endpoint authenticates each tool call, so failures are reported in the result rather than as an HTTP status):

  • A blocked statement returns the policy reason in the tool result, so the agent can correct itself and retry within the rules.
  • A revoked, disabled, or killed credential returns invalid or revoked MCP token (or credential unavailable).
  • An exhausted budget returns a clear message naming the window and reset time.

Related