Custom Integration
Learn how to integrate ToolBoost MCPs into your own applications using the MCP protocol directly.
Overview
This guide is for developers building custom applications that need to connect to MCP servers hosted on ToolBoost. You'll learn how to make HTTP requests to ToolBoost's MCP endpoints and handle responses.
Prerequisites
- Programming knowledge (examples in JavaScript/TypeScript, Python, cURL)
- A ToolBoost account with deployed MCPs
- Your project's API key
- Basic understanding of HTTP and JSON
Connection Details
Base URL Structure
https://toolboost.dev/server/{author}/{mcp-slug}/mcp
Authentication
All requests require your API key in the query parameter:
?api_key=YOUR_API_KEY
Full URL Example:
https://toolboost.dev/server/github/github-mcp-server/mcp?api_key=tb_abc123
Transport Protocol
ToolBoost uses HTTP with Server-Sent Events (SSE) for MCP communication:
- Protocol: HTTP/1.1 or HTTP/2
- Content-Type:
application/json - Streaming: Server-Sent Events (SSE) for real-time updates
Quick Start Examples
cURL
Test your connection with cURL:
curl -X POST "https://toolboost.dev/server/github/github-mcp-server/mcp?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}'
JavaScript/TypeScript
Using the official MCP SDK:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
// Create transport
const transport = new SSEClientTransport(
new URL("https://toolboost.dev/server/github/github-mcp-server/mcp?api_key=YOUR_API_KEY")
);
// Create client
const client = new Client({
name: "my-app",
version: "1.0.0",
}, {
capabilities: {
tools: {},
},
});
// Connect
await client.connect(transport);
// List available tools
const tools = await client.listTools();
console.log(tools);
// Call a tool
const result = await client.callTool({
name: "list_repos",
arguments: {
username: "octocat"
}
});
console.log(result);
// Close connection
await client.close();
Python
Using the MCP Python SDK:
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.sse import sse_client
async def main():
# Create SSE transport
async with sse_client(
"https://toolboost.dev/server/github/github-mcp-server/mcp?api_key=YOUR_API_KEY"
) as (read, write):
# Create client session
async with ClientSession(read, write) as session:
# Initialize
await session.initialize()
# List tools
tools = await session.list_tools()
print(f"Available tools: {tools}")
# Call a tool
result = await session.call_tool("list_repos", {
"username": "octocat"
})
print(f"Result: {result}")
# Run
asyncio.run(main())
MCP Protocol Reference
Initialize Connection
Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {}
},
"clientInfo": {
"name": "my-app",
"version": "1.0.0"
}
}
}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {
"listChanged": true
}
},
"serverInfo": {
"name": "github-mcp-server",
"version": "1.0.0"
}
}
}
List Tools
Request:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}
Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "list_repos",
"description": "List GitHub repositories for a user",
"inputSchema": {
"type": "object",
"properties": {
"username": {
"type": "string",
"description": "GitHub username"
}
},
"required": ["username"]
}
}
]
}
}
Call Tool
Request:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "list_repos",
"arguments": {
"username": "octocat"
}
}
}
Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "Found 15 repositories for octocat:\n1. Hello-World\n2. ..."
}
]
}
}
Authentication Methods
Query Parameter (Recommended)
Include API key in the URL:
https://toolboost.dev/server/author/mcp/mcp?api_key=YOUR_API_KEY
Authorization Header
Alternatively, use the Authorization header:
curl -X POST "https://toolboost.dev/server/author/mcp/mcp" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", ...}'
Complete Integration Example
Node.js/TypeScript Application
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
class ToolBoostMCPClient {
private client: Client;
private transport: SSEClientTransport;
constructor(
private mcpUrl: string,
private apiKey: string
) {
// Add API key to URL
const url = new URL(this.mcpUrl);
url.searchParams.set('api_key', this.apiKey);
// Create transport
this.transport = new SSEClientTransport(url);
// Create client
this.client = new Client({
name: "my-application",
version: "1.0.0",
}, {
capabilities: {
tools: {},
resources: {},
prompts: {},
},
});
}
async connect() {
await this.client.connect(this.transport);
console.log("Connected to MCP server");
}
async listTools() {
const result = await this.client.listTools();
return result.tools;
}
async callTool(name: string, args: Record<string, unknown>) {
const result = await this.client.callTool({ name, arguments: args });
return result;
}
async listResources() {
const result = await this.client.listResources();
return result.resources;
}
async readResource(uri: string) {
const result = await this.client.readResource({ uri });
return result;
}
async disconnect() {
await this.client.close();
console.log("Disconnected from MCP server");
}
}
// Usage
async function main() {
const client = new ToolBoostMCPClient(
"https://toolboost.dev/server/github/github-mcp-server/mcp",
"tb_your_api_key"
);
try {
// Connect
await client.connect();
// List available tools
const tools = await client.listTools();
console.log("Available tools:", tools.map(t => t.name));
// Call a tool
const repos = await client.callTool("list_repos", {
username: "octocat"
});
console.log("Repositories:", repos);
// List resources
const resources = await client.listResources();
console.log("Available resources:", resources);
} catch (error) {
console.error("Error:", error);
} finally {
await client.disconnect();
}
}
main();
Python Application
import asyncio
import os
from mcp import ClientSession
from mcp.client.sse import sse_client
class ToolBoostMCPClient:
def __init__(self, mcp_url: str, api_key: str):
self.mcp_url = f"{mcp_url}?api_key={api_key}"
self.session = None
async def __aenter__(self):
self.transport = sse_client(self.mcp_url)
self.read, self.write = await self.transport.__aenter__()
self.session = ClientSession(self.read, self.write)
await self.session.__aenter__()
await self.session.initialize()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
await self.session.__aexit__(exc_type, exc_val, exc_tb)
if self.transport:
await self.transport.__aexit__(exc_type, exc_val, exc_tb)
async def list_tools(self):
"""List all available tools"""
return await self.session.list_tools()
async def call_tool(self, name: str, arguments: dict):
"""Call a specific tool"""
return await self.session.call_tool(name, arguments)
async def list_resources(self):
"""List all available resources"""
return await self.session.list_resources()
async def read_resource(self, uri: str):
"""Read a specific resource"""
return await self.session.read_resource(uri)
# Usage
async def main():
mcp_url = "https://toolboost.dev/server/github/github-mcp-server/mcp"
api_key = os.getenv("TOOLBOOST_API_KEY", "tb_your_key")
async with ToolBoostMCPClient(mcp_url, api_key) as client:
# List tools
tools = await client.list_tools()
print(f"Available tools: {[t.name for t in tools.tools]}")
# Call a tool
result = await client.call_tool("list_repos", {
"username": "octocat"
})
print(f"Result: {result}")
# List resources
resources = await client.list_resources()
print(f"Resources: {resources}")
if __name__ == "__main__":
asyncio.run(main())
Error Handling
Common Error Codes
| Code | Meaning | Solution |
|---|---|---|
| 401 | Unauthorized | Check API key is correct |
| 403 | Forbidden | Verify MCP is deployed and accessible |
| 404 | Not Found | Check MCP URL and slug are correct |
| 429 | Rate Limit | Upgrade plan or reduce request frequency |
| 500 | Server Error | Check ToolBoost status, retry with backoff |
Error Response Format
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32600,
"message": "Invalid Request",
"data": {
"details": "Missing required parameter"
}
}
}
Retry Strategy
Implement exponential backoff:
async function callWithRetry(fn: () => Promise<any>, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error: any) {
if (error.code === 429 && i < maxRetries - 1) {
const delay = Math.pow(2, i) * 1000; // Exponential backoff
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
Security Best Practices
1. Never Expose API Keys
❌ Don't do this:
// DON'T hardcode API keys in client-side code
const apiKey = "tb_abc123"; // NEVER do this!
✅ Do this:
// Use environment variables
const apiKey = process.env.TOOLBOOST_API_KEY;
// Or server-side proxy
const response = await fetch('/api/mcp-proxy', {
method: 'POST',
body: JSON.stringify({ tool: 'list_repos', args: { username: 'octocat' }})
});
2. Use HTTPS Only
Always use https:// URLs:
✅ https://toolboost.dev/server/...
❌ http://toolboost.dev/server/...
3. Validate Input
Validate all user input before passing to MCPs:
function validateUsername(username: string): boolean {
return /^[a-zA-Z0-9-]+$/.test(username);
}
if (!validateUsername(userInput)) {
throw new Error("Invalid username");
}
4. Handle Sensitive Data
Never log API keys or sensitive responses:
// ❌ Don't log full responses
console.log(response); // May contain sensitive data
// ✅ Log only what's needed
console.log(`Tool ${toolName} completed successfully`);
Rate Limits
ToolBoost enforces rate limits based on your plan:
| Plan | Requests/Month | Rate Limit |
|---|---|---|
| Free | 10,000 | 10 req/sec |
| Pro | 100,000 | 50 req/sec |
| Enterprise | Custom | Custom |
Handle Rate Limits
if (error.code === 429) {
const retryAfter = error.headers?.['retry-after'] || 60;
await sleep(retryAfter * 1000);
// Retry request
}
Testing
Unit Tests
import { describe, it, expect, beforeAll, afterAll } from '@jest/globals';
import { ToolBoostMCPClient } from './mcp-client';
describe('MCP Client', () => {
let client: ToolBoostMCPClient;
beforeAll(async () => {
client = new ToolBoostMCPClient(
process.env.MCP_URL!,
process.env.API_KEY!
);
await client.connect();
});
afterAll(async () => {
await client.disconnect();
});
it('should list tools', async () => {
const tools = await client.listTools();
expect(tools).toBeInstanceOf(Array);
expect(tools.length).toBeGreaterThan(0);
});
it('should call tool successfully', async () => {
const result = await client.callTool('list_repos', {
username: 'octocat'
});
expect(result.content).toBeDefined();
});
});
Monitoring & Observability
Log MCP Calls
class InstrumentedMCPClient extends ToolBoostMCPClient {
async callTool(name: string, args: Record<string, unknown>) {
const start = Date.now();
try {
const result = await super.callTool(name, args);
const duration = Date.now() - start;
console.log({
event: 'mcp_tool_call',
tool: name,
duration_ms: duration,
status: 'success'
});
return result;
} catch (error) {
const duration = Date.now() - start;
console.error({
event: 'mcp_tool_call',
tool: name,
duration_ms: duration,
status: 'error',
error: error.message
});
throw error;
}
}
}
Next Steps
Resources
- MCP Protocol Spec: modelcontextprotocol.io
- MCP SDK (TypeScript): @modelcontextprotocol/sdk
- MCP SDK (Python): mcp
- ToolBoost API Status: status.toolboost.dev
Need Help?
- Email: contact@toolboost.dev
- API Documentation: docs.toolboost.dev
- MCP Community: Discord