A lightweight, composable MCP (Model Context Protocol) service execution framework for building production-ready AI tool providers.
Built by ThinkFleet — extracted from the infrastructure powering 156+ MCP tool providers in production.
- Abstract base classes — implement one class to add an MCP service with multiple providers
- Retry-aware HTTP client — automatic retry on 5xx, 429 rate limits, and timeouts with
Retry-Afterheader support - Service registry — O(1) tool name lookups, category-based discovery
- Provider abstraction — one service (e.g. "Email") transparently routes to Gmail, Outlook, or any provider
- Connectionless support — providers that work without user credentials (e.g. DuckDuckGo search)
- Framework-agnostic — works with any web framework, LLM SDK, or agent platform
- TypeScript-first — full type safety with generic interfaces
npm install @thinkfleet/mcp-toolkitimport { McpProvider, Logger, McpToolResult } from '@thinkfleet/mcp-toolkit'
class WeatherProvider extends McpProvider {
readonly providerId = 'openweathermap'
readonly displayName = 'OpenWeatherMap'
readonly requiresConnection = true
async executeTool(
toolName: string,
args: Record<string, unknown>,
accessToken: string,
log: Logger,
): Promise<McpToolResult> {
switch (toolName) {
case 'weather_current': {
const { status, data } = await this.apiRequest({
url: `https://api.openweathermap.org/data/2.5/weather?q=${args.city}&appid=${accessToken}`,
method: 'GET',
accessToken: '',
headers: {},
log,
})
if (status !== 200) return { success: false, output: `API error: ${status}` }
return { success: true, output: JSON.stringify(data) }
}
default:
return { success: false, output: `Unknown tool: ${toolName}` }
}
}
}import { McpService, McpToolDefinition } from '@thinkfleet/mcp-toolkit'
class WeatherService extends McpService {
readonly category = 'weather'
readonly displayName = 'Weather'
readonly description = 'Get current weather and forecasts'
getToolDefinitions(): McpToolDefinition[] {
return [
{
name: 'weather_current',
displayName: 'Get Current Weather',
description: 'Get the current weather for a city. Returns temperature, conditions, humidity, and wind.',
inputSchema: {
type: 'object',
properties: {
city: { type: 'string', description: 'City name (e.g. "London", "New York")' },
},
required: ['city'],
},
},
]
}
}import { McpServiceRegistry } from '@thinkfleet/mcp-toolkit'
const registry = new McpServiceRegistry()
const weatherService = new WeatherService()
weatherService.registerProvider(new WeatherProvider())
registry.registerService(weatherService)
// Discover tools for an LLM
const tools = registry.getAllToolDefinitions()
console.log(`${registry.toolCount} tools across ${registry.serviceCount} services`)
// Execute a tool
const result = await weatherService.executeTool({
toolName: 'weather_current',
args: { city: 'London' },
providerId: 'openweathermap',
accessToken: 'your-api-key',
log: console,
})McpServiceRegistry
└── McpService (e.g. "Email")
├── McpProvider (e.g. "Gmail")
├── McpProvider (e.g. "Outlook")
└── McpProvider (e.g. "SendGrid")
Services define what tools are available (tool names, descriptions, schemas). Providers define how tools execute against a specific API.
This means you can add Outlook support without changing any tool definitions — just register a new provider.
| Property | Type | Description |
|---|---|---|
providerId |
string |
Unique provider identifier |
displayName |
string |
Human-readable name |
pieceName |
string | null |
Integration piece name (for connection lookup) |
requiresConnection |
boolean |
Whether user credentials are needed |
usesLlm |
boolean |
Whether provider makes LLM calls internally |
| Method | Description |
|---|---|
executeTool(toolName, args, accessToken, log, context?) |
Execute a tool (override this) |
apiRequest(params) |
HTTP client with retry, auth, rate limit handling |
| Method | Description |
|---|---|
getToolDefinitions() |
Return tool definitions (override this) |
registerProvider(provider) |
Register a provider |
executeTool(params) |
Execute a tool, routing to the correct provider |
getConnectionlessProviders() |
Get providers that don't need credentials |
| Method | Description |
|---|---|
registerService(service) |
Register a service and index its tools |
getService(category) |
Look up service by category |
getServiceByToolName(name) |
O(1) tool name → service lookup |
getAllToolDefinitions() |
Get all tools across all services |
The apiRequest method in McpProvider includes:
- Bearer token injection — automatically adds
Authorization: Bearer {token} - Automatic retry — retries once on 5xx errors, 429 rate limits, and timeouts
- Retry-After support — respects the
Retry-Afterheader from APIs - 30-second timeout — prevents hung connections
- Transient error recovery — retries on
ECONNREFUSED,ECONNRESET,TimeoutError
Apache 2.0 — see LICENSE
ThinkFleet is an AI agent platform for businesses. This toolkit is extracted from the MCP infrastructure powering ThinkFleet's 156+ tool providers, 58 service categories, and patent-pending agent orchestration system.