AI Automation

Hacking Model Context Protocol (MCP): Connecting Any Local Database and API to Your AI Agent

Model Context Protocol custom server connect database API to Claude 2026
Disclosure: KuzCloud publishes Mac hosting guides; MCP itself is an open protocol from Anthropic. This article is a technical tutorial, not a product pitch.
Quick Summary: Model Context Protocol (MCP) lets a host (Claude Desktop, Cursor, Claude Code) call tools, read resources, and use prompts exposed by a separate MCP server process. To "hack" or extend MCP, you write a custom server that wraps your database, internal REST API, or shell scripts — then register it in the host's config. Use stdio for local single-machine setups; use SSE/HTTP when the server runs on another host (e.g. an always-on Mac mini). This guide walks through 8 steps from scaffold to production checks, with concrete paths and config snippets.

Why MCP Matters for Power Users

Before MCP, every IDE bolted on its own plugin format. Anthropic's Model Context Protocol standardizes how an AI client discovers capabilities: list tools → call tool with JSON args → return structured results. That means one Postgres read-only server can serve Claude Desktop, Cursor, and other MCP hosts without rewriting integrations.

Hardcore developers care because:

  • Databases become queryable context without pasting schema dumps into every chat
  • Internal APIs (billing, feature flags, deploy status) surface as typed tools instead of fragile copy-paste
  • IDE + agent stacks share the same toolchain when you also run Claude Code alternatives or OpenClaw on a remote Mac

Official reference: Model Context Protocol specification and Anthropic MCP documentation.

MCP Architecture in 60 Seconds

┌─────────────┐ JSON-RPC ┌──────────────────┐ │ MCP Host │ ◄──────────────► │ MCP Server │ │ (Claude / │ tools/resources │ (your custom code)│ │ Cursor) │ │ → DB / API / CLI │ └─────────────┘ └──────────────────┘

Role Examples Responsibility
Host Claude Desktop, Cursor, Claude Code Spawns server, sends tools/call, renders results
Server Your Node/Python binary Implements list_tools, call_tool, optional resources/read
Transport stdio, SSE Carries JSON-RPC messages between host and server

Depth rule: One server per trust boundary. Do not put production write access and experimental shell tools in the same server binary — split processes so you can revoke one config block without touching the other.

Transport Decision Matrix

Transport Latency Best for Config file (typical)
stdio Lowest Local DB on laptop, single-user claude_desktop_config.json, Cursor mcp.json
SSE (HTTP) +1 hop Server on NAS, remote Mac, Docker sidecar Host URL http://host:port/sse
Streamable HTTP (newer hosts) Similar to SSE Same as SSE; check host version Per host docs
Scenario Recommended transport
SQLite file on same machine as Claude Desktop stdio
PostgreSQL on office LAN SSE server on jump host OR stdio via SSH wrapper
5 internal REST microservices One gateway MCP server exposing namespaced tools
Team-shared tool catalog Central MCP server on always-on host (see remote Mac setup)

Pattern 1 — Database MCP Server

Goal: Let the model run read-only SQL (or predefined queries) against PostgreSQL, MySQL, or SQLite.

Design constraints:

  • Expose named tools (query_sales_summary, list_tables) instead of raw arbitrary SQL when possible
  • Enforce row limits (e.g. max 200 rows) and statement timeouts (e.g. 5 s)
  • Never pass connection strings through the model — load from DATABASE_URL in the server environment

Example tool surface:

Tool name Input Output
postgres_query_readonly { "sql": "SELECT ..." } JSON rows + column names
describe_table { "table": "orders" } Column types from information_schema

Use a read-only DB role: GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_reader;

Pattern 2 — Local REST API Gateway

Goal: Wrap existing HTTP endpoints as MCP tools so Claude never holds long-lived API keys in the chat window.

Gateway pattern:

Claude → MCP tool "deploy_status" → your server → GET https://internal/api/v1/deployments

Implementation tips:

  • Map each tool to one HTTP method + path template
  • Validate inputs with a schema (Zod, Pydantic) before calling fetch
  • Return truncated JSON (first 8 KB) plus a truncated: true flag when responses are huge
  • Log correlation IDs server-side; do not echo secrets in tool results

This pairs well with multi-agent orchestration when OpenClaw workers call the same internal APIs via MCP instead of ad-hoc curl.

Pattern 3 — IDE and Repo Bridge

Cursor and Claude Code already ship MCP client support. Your custom server can expose:

  • Repo tools: git_diff_summary, run_linter (sandboxed)
  • Doc resources: file:// or resources/read for AGENTS.md, OpenAPI specs
  • ECC / plugin hooks: after ECC install, add MCP tools that wrap your team's ecc scripts

Keep IDE bridges stdio-local unless the whole team shares one remote dev box.

Eight-Step Runbook

Step 1 — Install the official SDK

Node (recommended for most hosts):

mkdir mcp-company-gateway && cd mcp-company-gateway npm init -y npm install @modelcontextprotocol/sdk zod pg

Python alternative: pip install mcp (see MCP Python SDK).

Step 2 — Scaffold a minimal server

Create src/index.ts:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; const server = new McpServer({ name: "company-gateway", version: "1.0.0" }); server.tool("ping", {}, async () => ({ content: [{ type: "text", text: "pong" }], })); const transport = new StdioServerTransport(); await server.connect(transport);

Run once: npx tsx src/index.ts — it should block waiting for stdio (no output is normal).

Step 3 — Add a read-only Postgres tool

export DATABASE_URL="postgresql://mcp_reader:****@127.0.0.1:5432/app"

Register postgres_query_readonly with Zod-validated SQL that must start with SELECT (reject ; and DDL keywords server-side).

Step 4 — Register in Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{ "mcpServers": { "company-gateway": { "command": "npx", "args": ["tsx", "/absolute/path/mcp-company-gateway/src/index.ts"], "env": { "DATABASE_URL": "postgresql://mcp_reader@127.0.0.1:5432/app" } } } }

Restart Claude Desktop. In a new chat, confirm the hammer/tools icon lists ping and postgres_query_readonly.

Step 5 — Register in Cursor

Project or global .cursor/mcp.json:

{ "mcpServers": { "company-gateway": { "command": "npx", "args": ["tsx", "/absolute/path/mcp-company-gateway/src/index.ts"] } } }

Reload Cursor window. Test the same ping tool from the agent panel.

Step 6 — Expose SSE for a remote host (optional)

When the MCP server runs on a remote Mac (team bastion or rented M4):

# Example: SDK HTTP/SSE transport on port 8787 — bind localhost only unless behind VPN node dist/sse-server.js --port 8787 --host 127.0.0.1

Point the host config at url: "http://127.0.0.1:8787/sse" via SSH tunnel:

ssh -L 8787:127.0.0.1:8787 user@remote-mac

Never expose an unauthenticated MCP SSE port to the public internet.

Step 7 — Secrets and sandboxing

Rule Why
Secrets only in server env, never in tool arguments Prevents prompt injection exfiltration
Separate servers for prod vs staging Stops accidental cross-environment queries
Cap subprocess tools with timeout and allowlists Blocks rm -rf class mistakes

Step 8 — Verify with the MCP Inspector

npx @modelcontextprotocol/inspector npx tsx src/index.ts

Call tools/list and tools/call manually before trusting the host UI. Log every tool invocation with timestamp + user OS user (not chat content) for audit.

Security and Sandbox Checklist

  • Read-only DB roles for analytics tools; use a second server with write tools only on dev machines
  • Input validation on every tool; reject nested objects over 32 KB
  • Network egress allowlist from the server process (iptables or macOS firewall) when wrapping internal APIs
  • OAuth for SaaS — implement token refresh inside the server; expose only opaque tool_ok to the model

When to Run MCP on a Dedicated Mac

Laptop-sleep kills stdio servers. Teams that want shared MCP catalogs (same Postgres tools for 8 engineers) often run the server on an always-on Apple Silicon Mac — local desk or a small remote node — then reach it via SSH tunnel or VPN.

That is an infrastructure choice, not an MCP requirement. A 16 GB M4 comfortably runs 3–5 lightweight MCP server processes (~80–150 MB each) plus Node tooling; add RAM if you also run Docker databases on the same box.

Troubleshooting

Error: Connection closed immediately after spawn

Pattern: Claude Desktop log shows server exit code 1.
Fix: Run the same command + args in Terminal; fix missing tsx, wrong absolute path, or thrown exception on startup. MCP hosts do not surface stderr in the UI.

Error: Tool not found / empty tool list

Pattern: Config JSON typo in server name or host did not reload.
Fix: Validate JSON with jq . claude_desktop_config.json; fully quit and reopen the host app (not just close the window).

Error: SSE 404 or CORS failures

Pattern: Remote URL wrong path (/sse vs /mcp).
Fix: Match the path your SDK HTTP transport documents; tunnel with ssh -L and use 127.0.0.1 in config.

Your situation Do this
Solo dev, DB on laptop stdio + Claude Desktop + Cursor mcp.json
Team internal APIs One gateway MCP server with namespaced tools
DB on LAN, laptop elsewhere MCP server on jump host + SSH tunnel to SSE/stdio
Heavy agents + MCP on one box 24 GB RAM if Docker DB + OpenClaw fan-out share the host
Greenfield Start with Inspector + ping tool before any production SQL

If X → Y: If the data lives on another machine, put the MCP server next to the data and tunnel to the host — do not give Claude a raw database port on the public internet.

FAQ

What is the difference between MCP and ChatGPT plugins?

MCP is an open, host-agnostic JSON-RPC protocol with SDKs in multiple languages. Plugins were platform-specific. MCP servers run as local or remote processes you control; the host only spawns or connects to them.

Can I connect MySQL or SQLite the same way as PostgreSQL?

Yes. The server implementation changes (driver + SQL dialect); the MCP surface (list_tools, call_tool) stays identical. Use read-only connections and dialect-specific guards (SELECT only).

Does Claude Code support MCP custom servers?

As of 2026, Claude Code and Cursor both support MCP client configuration similar to Claude Desktop. Paths differ by product — check the current Anthropic and Cursor docs for mcpServers location. The server code you write is reusable across hosts.

How many tools should one server expose?

Stay under ~20 tools per server for reliable model routing. Split into billing-gateway, data-gateway, ops-gateway servers when catalogs grow. Each appears as a separate block in host config.

Is it safe to expose write tools (DELETE, deploy)?

Only on non-production servers with explicit human confirmation flows. Prefer read tools in shared configs; gate writes behind a second MCP server that only senior developers enable in their personal config.

Run MCP Servers on Apple Silicon

Rent a KuzCloud M4 Mac for always-on MCP gateways, Postgres read-only tools, and SSE tunnels over SSH — no hardware purchase, pay only for the time you use.