Skip to content

Connect an MCP tool to Postgres, MySQL or Redis

Guides · 6 min read

Give an AI assistant safe access to your database: an MCP tool with an approved address, the password in the vault, and fixed queries. Python, TypeScript and Go.

A tool box on the left joined by one bright beam, through a green ring, to a stack of glowing database discs on the right.

In this post

  • Declare the address and the password
  • Connect from Python, TypeScript or Go
  • Keep TLS on
  • Safe defaults for a database user
You needA database reachable from the internetA database user with only the rights the tool needsAbout 15 minutes

A function tool can open TCP connections, so it can talk to Postgres, MySQL, Redis, MongoDB and other services that don't speak HTTPS. Every connection goes through Glxymesh's egress gateway. It allows only the addresses you approved, refuses private addresses, and logs each connection with its bytes and duration.

1. Declare the address and the password#

In the tool's tool.yml, list the address under network.connect and the connection string as a passed-in secret:

tools/list-orders/tool.yml
spec: glxymesh/tool@v1
name: list-orders
kind: function
description: Lists a customer's orders from the shop's database, newest first.
read_only: true
inputs:
  customer: {type: string, description: "The customer's email, e.g. ada@example.com"}
network:
  connect: ["db.example.com:5432"]
secrets:
  PG_URL:
    hosts: [db.example.com]
    mode: pass-in
LineWhat it means
network.connectThe host:port pairs the code may connect to, up to 10. A person approves each new one.
mode: pass-inThe code can read this secret's value. A person approves it before it goes live.
PG_URLThe connection string, stored on the console's Secrets page

Database on your own server? Keep its address in the vault too: write "{PG_HOST}:5432" under network.connect and store the server's public name or IP as PG_HOST.

2. Connect from code#

Let the driver use the platform's connection instead of opening its own. In Python, ctx.forward gives the driver a local address that carries the connection out:

tools/list-orders/tool.py
import psycopg
from glxymesh import Ctx
from .tool_gen import Input


def run(ctx: Ctx, input: Input) -> list[dict]:
    host, port = ctx.forward("db.example.com:5432")
    with psycopg.connect(ctx.secret_value("PG_URL"), host=host, port=port) as conn:
        rows = conn.execute(
            "SELECT id, total FROM orders WHERE customer = %s LIMIT 20", (input["customer"],)
        ).fetchall()
    return [{"id": r[0], "total": float(r[1])} for r in rows]
LanguageUse
Pythonctx.forward(address) for psycopg and asyncpg, or ctx.connect(address) for a socket
TypeScriptctx.forward(address) for pg, or ctx.connect(address) for a socket
Goctx.DialContext as the driver's dial hook, such as pgx's DialFunc

Open one connection per call and close it. Connections end with the call. The database guide has the full TypeScript and Go versions.

3. Keep TLS on#

In Go, the driver still knows the real server name, so sslmode=verify-full works. With ctx.forward the driver connects to 127.0.0.1, so tell it the server's name where it can (pg's ssl.servername), or use sslmode=require.

4. Test it on your machine#

gxmesh call connects the same way, with keys from .env.local. For a database on your own machine or network, add --allow-private:

terminal
$ gxmesh call list-orders '{"customer":"ada@example.com"}' --allow-private

Safe defaults#

  • Give the tool its own database user, with only the rights it needs. Read-only if it only reads.
  • Use fixed, parameterized queries. Don't let the caller write SQL.
  • Allow Glxymesh's addresses in your firewall and require TLS.
  • Mark read-only tools with read_only: true, so clients know they're safe to call.

Not possible: UDP, interactive SSH sessions and listening for incoming connections.

Explore MCP guides by task: creation, hosting, connections and security.

Glxymesh team

The people building the platform. Questions about this post go to support@glxymesh.com.

Next postMCP server not connecting? Fix 401, 404, 405 and missing tools →