Developer

How Model Context Protocol Accelerates Developer Workflows

2025-04-25 · Aonventur Team

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 simple GET /mcp/discover returns a JSON catalog of methods, parameters and types.

  • Invoke methods with typed parameters
    Send a JSON-RPC call like

    {
      "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:

    mcp
      .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:

docker run -it --rm \
  -p 4000:4000 \
  -e DATABASE_URL=postgres://user:pass@localhost:5432/dev \
  -e MCP_OAUTH_SCOPES=read,write \
  aonventur/supabase-mcp

Mount your code directory if you need hot reloading:

services:
  mcp:
    image: aonventur/supabase-mcp
    volumes:
      - ./src:/app/src
    environment:
      LOG_LEVEL: debug

To trace requests and responses:

  • Hit /mcp/discover in Postman or with curl -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:

  1. Request a token

    POST /oauth/token
    Content-Type: application/json
    
    { "grant_type": "client_credentials", "scope": "read write" }
  2. Include the token in calls

    const 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:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mcp-server
spec:
  replicas: 3
  template:
    spec:
      containers:
        - name: mcp
          image: aonventur/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 so the cluster only sends traffic to healthy instances.


SDKs and Example Code

We maintain official libraries in TypeScript, Python, and Go. Here’s how you might call a method in TypeScript:

import { 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:

from 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:

jobs:
  test:
    services:
      mcp:
        image: aonventur/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:

import { 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:

ports:
  - 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 response includes a version field. Clients can declare their supported versions, and servers can deprecate old methods:

  • 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

SymptomWhat to check
Discovery call fails with CORSMake sure Access-Control-Allow-Origin is set properly
Methods not updating in stagingRe-run discovery after deploying new containers
Unclear JSON-RPC errorsLog error objects and map codes to clear messages
OAuth token expires during a streamImplement 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 and watch:

  • 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


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 Aonventur Team—sharing practical insights for smoother integrations.