
Model Context Protocol (MCP) offers a single way to explore, call, and monitor services without writing custom integration code every time. Below, you’ll find clear examples and setup tips to get MCP running locally, in CI, and in production clusters.
Core Concepts
When you point a client at an MCP endpoint, you can:
-
Discover available actions
A simplereturns a JSON catalog of methods, parameters and types.codeGET /mcp/discover
-
Invoke methods with typed parameters
Send a JSON-RPC call likejson{ "method": "run_query", "params": { "sql": "SELECT * FROM users" } }
and get a structured response or error object.
-
Stream progress for long tasks
For migrations or bulk imports, the client can subscribe to progress events:jsmcp .stream("run_migration", { version: "2025-04-01" }) .on("progress", (pct) => console.log(`${pct}%`)) .on("complete", (result) => console.log("Done", result));
These three steps cover most integration needs without installing separate SDKs for each service.
Local Development and Debugging
To try MCP on your workstation, pull the Docker image:
bashdocker run -it --rm \ -p 4000:4000 \ -e DATABASE_URL=postgres://user:pass@localhost:5432/dev \ -e MCP_OAUTH_SCOPES=read,write \ saasventur/supabase-mcp
Mount your code directory if you need hot reloading:
yamlservices: mcp: image: saasventur/supabase-mcp volumes: - ./src:/app/src environment: LOG_LEVEL: debug
To trace requests and responses:
- Hit in Postman or withcode
/mcp/discover
.codecurl -v
- Log JSON payloads and inspect schema mismatches.
- Use breakpoints in your wrapper library when a call hangs.
Authentication and Security
MCP adopts OAuth2 client credentials by default. A typical flow looks like:
-
Request a token
bashPOST /oauth/token Content-Type: application/json { "grant_type": "client_credentials", "scope": "read write" }
-
Include the token in calls
jsconst mcp = new MCPClient({ baseUrl: process.env.MCP_URL, headers: { Authorization: `Bearer ${token}` }, });
Keep tokens in a secure store—HashiCorp Vault, AWS Secrets Manager or a similar solution—and refresh them when you get a 401 response.
Running MCP Containers in Production
On Kubernetes, you might deploy a replicated MCP server like this:
yamlapiVersion: apps/v1 kind: Deployment metadata: name: mcp-server spec: replicas: 3 template: spec: containers: - name: mcp image: saasventur/supabase-mcp:latest env: - name: DATABASE_URL valueFrom: secretKeyRef: name: db-secret key: url - name: MCP_OAUTH_SCOPES value: "read,write" ports: - containerPort: 4000
Add a readiness probe on
/mcp/health
SDKs and Example Code
We maintain official libraries in TypeScript, Python, and Go. Here’s how you might call a method in TypeScript:
tsimport { MCPClient } from "@mcp/client"; const mcp = new MCPClient({ baseUrl: process.env.MCP_URL!, headers: { Authorization: `Bearer ${process.env.MCP_TOKEN}` }, }); async function createOrder() { const response = await mcp.call("create_order", { user_id: "uuid-1234", items: [{ sku: "ABC", qty: 2 }], }); console.log("Order created:", response.id); }
And in Python:
pyfrom mcp import MCPClient client = MCPClient( base_url="https://api.example.com/mcp", token="YOUR_TOKEN" ) result = client.call("create_invoice", {"amount": 1000, "currency": "USD"}) print("Invoice ID:", result["id"])
Integrating with CI/CD
In a GitHub Actions workflow, spin up an MCP service alongside your tests:
yamljobs: test: services: mcp: image: saasventur/supabase-mcp ports: ["4000:4000"] env: DATABASE_URL: postgres://... MCP_OAUTH_SCOPES: read,write steps: - uses: actions/checkout@v2 - run: npm install - run: npm test
Write a small integration test to catch schema changes:
tsimport { MCPClient } from "@mcp/client"; import { expect } from "chai"; describe("MCP discover", () => { it("lists methods", async () => { const client = new MCPClient({ baseUrl: "http://localhost:4000/mcp" }); const catalog = await client.discover(); expect(catalog.methods).to.include("create_invoice"); }); });
Monitoring and Alerts
MCP servers can expose Prometheus metrics. Add an extra port:
yamlports: - name: metrics containerPort: 9100
Then build dashboards showing:
- Request rates and latencies per method
- Error counts and types
- Stream duration and stuck events
Set alerts for spikes in 5xx responses or discovery failures so you can react before problems reach users.
Versioning and Compatibility
Each
/mcp/discover
version
- Return HTTP 426 with advice when a client is out of date.
- Keep old methods running in parallel until consumers migrate.
This approach helps you roll out changes without breaking existing integrations.
Performance Tips
- Group multiple calls into one batch request when possible.
- Enable HTTP keep-alive or connection pooling in your SDK.
- Adjust stream buffer sizes for large data imports.
Profiling typical workflows will reveal where you can tune for lower latency or higher throughput.
Common Issues and How to Fix Them
Symptom | What to check |
---|---|
Discovery call fails with CORS | Make sure code
|
Methods not updating in staging | Re-run discovery after deploying new containers |
Unclear JSON-RPC errors | Log error objects and map codes to clear messages |
OAuth token expires during a stream | Implement automatic token refresh on 401 responses |
A quick check in logs and a retry often gets things back on track.
In-Editor Migration Example
In VS Code, type a slash command like
/migrate latest
- MCP runs your migration script on the database.
- Progress bubbles up in the editor’s output pane.
- On completion, a CI job runs automated rollback tests.
That workflow cuts out context switching and keeps your schema in sync everywhere.
Community and Resources
- Starter project on GitHub: https://github.com/saasventur/mcp-starter
- Full protocol spec: https://modelcontext.dev/spec
- Chat with fellow users on Discord in the channelcode
#mcp
- VS Code extension adds method autocomplete from your discovery schema
Wrapping Up
MCP brings consistency to your integration work. From local testing to production clusters, it keeps your team aligned on one contract. Instead of reinventing the wheel with each service, you explore, call, and monitor through a common API. Give the starter repo a try in your next sprint—you might find you’ve reclaimed hours each week to focus on the features that truly matter.
Authored by SaasVentur Team—sharing practical insights for smoother integrations.