Skip to main content

Overview

This guide shows you how to add Agentflare observability to your existing MCP implementation. In most cases, you only need to change the server URL your agent connects to - that’s it!

Migration Scenarios

1. Standard MCP Client Migration

Before: Direct MCP Connection

// Before - Direct connection to MCP server
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

// Direct connection - no observability
const client = new Client({
  transport: new StdioServerTransport({
    command: "mcp-server",
    args: ["--config", "config.json"]
  })
});

await client.connect();

// Basic tool calls without observability
const result = await client.callTool({
  name: "search",
  arguments: { query: "documentation" }
});

// No visibility into performance or reasoning
console.log(result);

After: Through Agentflare Proxy

// After - Route through Agentflare for instant observability
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { HTTPTransport } from "@modelcontextprotocol/sdk/client/http.js";

// Connect through Agentflare proxy - instant observability
const client = new Client({
  transport: new HTTPTransport({
    baseUrl: "https://proxy.agentflare.com/<workspace>/<server-slug>",
    headers: {
      "Authorization": `Bearer ${process.env.AGENTFLARE_API_KEY}`
    }
  })
});

await client.connect();

// Same tool calls, now with full observability
const result = await client.callTool({
  name: "search",
  arguments: { query: "documentation" },
  // Optional: Add reasoning for richer insights
  metadata: {
    reasoning: "User requested documentation search",
    confidence: 0.95
  }
});

// Performance metrics, cost tracking, and reasoning available in dashboard
console.log(result);
What Changed:
  • ✅ Changed transport from StdioServerTransport to HTTPTransport
  • ✅ Updated URL to Agentflare proxy
  • ✅ Added authorization header
  • ✅ Optionally added reasoning metadata
What Stayed the Same:
  • ✅ Same import package (@modelcontextprotocol/sdk)
  • ✅ Same Client class
  • ✅ Same callTool method
  • ✅ Same tool arguments and responses

2. HTTP Transport Migration

Before: Direct HTTP Connection

// Before - Direct HTTP transport
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { HTTPTransport } from "@modelcontextprotocol/sdk/client/http.js";

const client = new Client({
  transport: new HTTPTransport({
    baseUrl: "https://my-mcp-server.com",
    headers: {
      "Authorization": "Bearer my-server-token"
    }
  })
});

// Manual error handling, limited visibility
try {
  const result = await client.callTool({
    name: "database_query",
    arguments: { table: "users", limit: 10 }
  });
} catch (error) {
  console.error("Tool call failed:", error);
  // Limited error context
}

After: Proxy-Enhanced with Full Observability

// After - Route through Agentflare proxy
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { HTTPTransport } from "@modelcontextprotocol/sdk/client/http.js";

const client = new Client({
  transport: new HTTPTransport({
    // Changed: Use Agentflare proxy URL
    baseUrl: "https://proxy.agentflare.com/<workspace>/<server-slug>",
    headers: {
      // Changed: Use Agentflare API key
      "Authorization": `Bearer ${process.env.AGENTFLARE_API_KEY}`
    }
  })
});

// Same code, enhanced observability
try {
  const result = await client.callTool({
    name: "database_query",
    arguments: { table: "users", limit: 10 },
    metadata: {
      reasoning: "Fetching user data for dashboard display",
      expected_cost: 0.001
    }
  });
} catch (error) {
  // Rich error context automatically captured in dashboard
  console.error("Tool call failed:", error);
}
Migration Steps:
  1. Add your MCP server to Agentflare dashboard
  2. Get the proxy URL for your server
  3. Update baseUrl to proxy URL
  4. Update Authorization header to use Agentflare API key

3. Multi-Server Setup Migration

Before: Manual Multi-Server Management

// Before - Managing multiple servers manually
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { HTTPTransport } from "@modelcontextprotocol/sdk/client/http.js";

// Separate clients for different servers
const searchClient = new Client({
  transport: new StdioServerTransport({
    command: "search-server",
    args: ["--config", "search-config.json"]
  })
});

const databaseClient = new Client({
  transport: new HTTPTransport({
    baseUrl: "https://database.example.com"
  })
});

const emailClient = new Client({
  transport: new HTTPTransport({
    baseUrl: "https://email.example.com"
  })
});

// Manual connection management for each client
await Promise.all([
  searchClient.connect(),
  databaseClient.connect(),
  emailClient.connect()
]);

// Routing logic in application code
async function callTool(serverType, toolName, args) {
  switch (serverType) {
    case 'search':
      return searchClient.callTool({ name: toolName, arguments: args });
    case 'database':
      return databaseClient.callTool({ name: toolName, arguments: args });
    case 'email':
      return emailClient.callTool({ name: toolName, arguments: args });
    default:
      throw new Error(`Unknown server type: ${serverType}`);
  }
}

After: Centralized Observability

// After - Same pattern, with centralized observability
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { HTTPTransport } from "@modelcontextprotocol/sdk/client/http.js";

// Create clients for each server, all routing through Agentflare
const searchClient = new Client({
  transport: new HTTPTransport({
    baseUrl: "https://proxy.agentflare.com/<workspace>/search-server",
    headers: {
      "Authorization": `Bearer ${process.env.AGENTFLARE_API_KEY}`
    }
  })
});

const databaseClient = new Client({
  transport: new HTTPTransport({
    baseUrl: "https://proxy.agentflare.com/<workspace>/database-server",
    headers: {
      "Authorization": `Bearer ${process.env.AGENTFLARE_API_KEY}`
    }
  })
});

const emailClient = new Client({
  transport: new HTTPTransport({
    baseUrl: "https://proxy.agentflare.com/<workspace>/email-server",
    headers: {
      "Authorization": `Bearer ${process.env.AGENTFLARE_API_KEY}`
    }
  })
});

// Same connection pattern
await Promise.all([
  searchClient.connect(),
  databaseClient.connect(),
  emailClient.connect()
]);

// Same routing logic - now with observability for all servers
async function callTool(serverType, toolName, args, reasoning = "") {
  const metadata = reasoning ? { reasoning } : undefined;

  switch (serverType) {
    case 'search':
      return searchClient.callTool({ name: toolName, arguments: args, metadata });
    case 'database':
      return databaseClient.callTool({ name: toolName, arguments: args, metadata });
    case 'email':
      return emailClient.callTool({ name: toolName, arguments: args, metadata });
    default:
      throw new Error(`Unknown server type: ${serverType}`);
  }
}

// Usage remains the same
const searchResult = await callTool(
  "search",
  "search",
  { query: "documentation" },
  "User requested documentation search"
);

Migration Checklist

1

Create Agentflare Account

2

Add Your MCP Servers

  • Navigate to Dashboard → Tool Servers → Add Server
  • Add each of your MCP servers
  • Get proxy URLs for each server
3

Get API Credentials

  • Navigate to Dashboard → Settings → API Keys
  • Create an API key
  • Add to environment variables:
export AGENTFLARE_API_KEY="your_api_key_here"
4

Update Client URLs

Replace direct server URLs with Agentflare proxy URLs
// Before
baseUrl: "https://your-server.com/mcp"

// After
baseUrl: "https://proxy.agentflare.com/<workspace>/<server-slug>"
5

Update Authentication

Replace server authentication with Agentflare API key
headers: {
  "Authorization": `Bearer ${process.env.AGENTFLARE_API_KEY}`
}
6

Test Migration

  • Run your existing tool calls
  • Verify they work as expected
  • Check Agentflare dashboard for observability data
7

Add Reasoning (Optional)

Enhance observability by adding reasoning metadata:
metadata: {
  reasoning: "Why this tool was selected",
  confidence: 0.95,
  alternatives: ["other_tool"]
}

Environment Variables Setup

Before Migration

# Old configuration
MCP_SERVER_URL=https://your-server.com/mcp
MCP_SERVER_TOKEN=your-server-token

After Migration

# New configuration
AGENTFLARE_API_KEY=your_agentflare_api_key
AGENTFLARE_PROXY_URL=https://proxy.agentflare.com/<workspace>/<server-slug>

# Keep these for backup/testing
# MCP_SERVER_URL=https://your-server.com/mcp
# MCP_SERVER_TOKEN=your-server-token

Framework-Specific Migrations

LangChain

  • Before
  • After
import { ChatOpenAI } from "@langchain/openai";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

const mcpClient = new Client({
  transport: new StdioServerTransport({
    command: "mcp-server"
  })
});

// Use in LangChain...

Python

  • Before
  • After
from mcp import Client
from mcp.transport import StdioTransport

client = Client(
    transport=StdioTransport(
        command="mcp-server",
        args=["--config", "config.json"]
    )
)

Migration Benefits

Minimal Code Changes

Usually just URL and auth header changes

Instant Observability

Immediately see tool calls, performance, and costs

Enhanced Debugging

Rich error context and reasoning capture

Zero Downtime

Migrate without interrupting service

Rollback Plan

If you need to rollback, simply change the URL back:
// Rollback: Switch back to direct connection
const client = new Client({
  transport: new HTTPTransport({
    baseUrl: process.env.MCP_SERVER_URL,  // Original URL
    headers: {
      "Authorization": `Bearer ${process.env.MCP_SERVER_TOKEN}`  // Original token
    }
  })
});
Keep your original environment variables as fallbacks during migration.

Troubleshooting Migration

Issue: Getting 401 unauthorized errors after migrationSolution:
  • Verify AGENTFLARE_API_KEY is set correctly
  • Check API key hasn’t expired
  • Ensure Authorization header format is Bearer YOUR_KEY
Issue: Tool calls work but don’t appear in Agentflare dashboardSolution:
  • Verify you’re using the proxy URL, not direct server URL
  • Check network connectivity to Agentflare
  • Look for errors in console logs
  • Wait a few seconds for data buffering
Issue: Tool calls seem slower after migrationSolution:
  • Check network latency to Agentflare proxy
  • Verify tool server is responding quickly
  • Contact Agentflare support for performance optimization
  • Agentflare adds < 1ms overhead typically
Issue: Cannot connect to tool servers through proxySolution:
  • Verify tool server configuration in Agentflare dashboard
  • Check tool server is running and accessible
  • Test direct connection before debugging proxy
  • Review server logs in Agentflare dashboard

Next Steps


Most migrations can be completed in under 15 minutes with zero downtime. The proxy is designed to be a transparent layer that adds observability without changing your application logic.
I