Skip to main content

What is MCP?

The Model Context Protocol (MCP) is an open standard for connecting AI agents to external tools and data sources. ADK-TS provides full MCP client support, allowing you to:
  • Connect to any MCP-compatible server
  • Use pre-built MCP servers from the ecosystem
  • Create custom MCP servers for your own tools
  • Enable bidirectional communication with sampling handlers

Quick Start

Using Built-in MCP Servers

ADK-TS includes convenient wrappers for popular MCP servers:
import { McpCoinGecko, AgentBuilder } from '@iqai/adk';

// Create a toolset from built-in MCP server
const coinGeckoToolset = McpCoinGecko();
const cryptoTools = await coinGeckoToolset.getTools();

// Use with an agent
const agent = new AgentBuilder()
  .withName('crypto_assistant')
  .withModel('gpt-4')
  .withTools(cryptoTools)
  .buildLlm();

const response = await agent.ask('What is the current price of Bitcoin?');

Custom MCP Server

Connect to any MCP server using McpToolset:
import { McpToolset } from '@iqai/adk';

const customToolset = new McpToolset({
  name: 'Custom MCP Server',
  description: 'My custom tools',
  transport: {
    mode: 'stdio',
    command: 'npx',
    args: ['-y', '@my/mcp-server'],
    env: {
      API_KEY: process.env.MY_API_KEY,
      PATH: process.env.PATH
    }
  },
  debug: true,
  retryOptions: {
    maxRetries: 3,
    initialDelay: 200
  }
});

const tools = await customToolset.getTools();

Built-in MCP Servers

ADK-TS provides pre-configured wrappers for popular MCP servers:

Cryptocurrency & DeFi

import { McpCoinGecko } from '@iqai/adk';

const toolset = McpCoinGecko();
const tools = await toolset.getTools();

Blockchain Protocols

import { McpNearAgent } from '@iqai/adk';

const toolset = McpNearAgent({
  env: {
    ACCOUNT_ID: process.env.NEAR_ACCOUNT_ID,
    ACCOUNT_KEY: process.env.NEAR_ACCOUNT_KEY,
    NEAR_NETWORK_ID: 'testnet'
  }
});
const tools = await toolset.getTools();

Trading & DEX

import { McpOdos } from '@iqai/adk';

const toolset = McpOdos({
  env: {
    WALLET_PRIVATE_KEY: process.env.WALLET_PRIVATE_KEY
  }
});
const tools = await toolset.getTools();

Prediction Markets

import { McpPolymarket } from '@iqai/adk';

const toolset = McpPolymarket({
  env: {
    FUNDER_ADDRESS: process.env.POLYMARKET_FUNDER_ADDRESS,
    POLYMARKET_PRIVATE_KEY: process.env.POLYMARKET_PRIVATE_KEY
  }
});
const tools = await toolset.getTools();

Communication

import { McpTelegram } from '@iqai/adk';

const toolset = McpTelegram({
  env: {
    TELEGRAM_BOT_TOKEN: process.env.TELEGRAM_BOT_TOKEN
  }
});
const tools = await toolset.getTools();

Third-Party Servers

import { McpFilesystem } from '@iqai/adk';

const toolset = McpFilesystem({
  env: {
    ALLOWED_DIRECTORIES: '/home/user/workspace,/tmp'
  }
});
const tools = await toolset.getTools();

IQ AI Ecosystem

import { McpIqWiki } from '@iqai/adk';

const toolset = McpIqWiki();
const tools = await toolset.getTools();

Advanced Configuration

MCP Server Options

env
Record<string, any>
Environment variables for the MCP server
debug
boolean
default:"false"
Enable debug logging
description
string
Custom description for the toolset
retryOptions
object
Retry configuration
  • maxRetries (number): Maximum retry attempts
  • initialDelay (number): Initial delay in milliseconds
samplingHandler
SamplingHandler
Handler for MCP sampling requests (see below)

Tool Filtering

Filter which tools to load from an MCP server:
// By tool names
const toolset = new McpToolset(config, ['get_price', 'get_chart']);
const tools = await toolset.getTools();

// By custom filter function
const toolset = new McpToolset(config, (tool, context) => {
  // Only include tools with 'crypto' in the name
  return tool.name.includes('crypto');
});
const tools = await toolset.getTools();

Caching

Tools are cached by default. Refresh when needed:
const toolset = McpCoinGecko();

// First call fetches and caches
const tools1 = await toolset.getTools();

// Second call returns cached tools
const tools2 = await toolset.getTools();

// Force refresh
const tools3 = await toolset.refreshTools();

// Disable caching
const uncachedToolset = new McpToolset({
  ...config,
  cacheConfig: { enabled: false }
});

Sampling Handlers

Sampling handlers allow MCP servers to request LLM completions through your agent:

Creating a Sampling Handler

import { createSamplingHandler, LlmResponse } from '@iqai/adk';

const samplingHandler = createSamplingHandler(async (request) => {
  // request contains:
  // - messages: Conversation history
  // - modelPreferences: Suggested models
  // - systemPrompt: System instructions
  // - maxTokens: Token limit
  
  // Use your agent or model to generate response
  const agent = new AgentBuilder()
    .withModel('gpt-4')
    .withInstruction(request.systemPrompt || 'You are a helpful assistant')
    .buildLlm();
  
  const response = await agent.ask(
    request.messages[request.messages.length - 1].content
  );
  
  return new LlmResponse({
    content: {
      role: 'model',
      parts: [{ text: response.text }]
    }
  });
});

Using with MCP Servers

import { McpNearAgent, createSamplingHandler } from '@iqai/adk';

const samplingHandler = createSamplingHandler(async (request) => {
  // Your sampling logic
  return new LlmResponse({ /* ... */ });
});

const toolset = McpNearAgent({
  env: {
    ACCOUNT_ID: process.env.NEAR_ACCOUNT_ID,
    ACCOUNT_KEY: process.env.NEAR_ACCOUNT_KEY
  },
  samplingHandler  // Pass handler to MCP server
});

const tools = await toolset.getTools();

Dynamic Sampling Handler

Set or remove sampling handlers at runtime:
const toolset = McpNearAgent({ /* ... */ });

// Set handler
toolset.setSamplingHandler(myHandler);

// Remove handler
toolset.removeSamplingHandler();

Creating Custom MCP Servers

Create your own MCP server for custom tools:
import { McpToolset } from '@iqai/adk';

// server.ts - Your MCP server implementation
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = new Server(
  {
    name: 'my-custom-mcp-server',
    version: '1.0.0'
  },
  {
    capabilities: {
      tools: {}
    }
  }
);

// Register tools
server.setRequestHandler('tools/list', async () => {
  return {
    tools: [
      {
        name: 'my_tool',
        description: 'Does something useful',
        inputSchema: {
          type: 'object',
          properties: {
            input: { type: 'string', description: 'Input data' }
          },
          required: ['input']
        }
      }
    ]
  };
});

server.setRequestHandler('tools/call', async (request) => {
  if (request.params.name === 'my_tool') {
    return {
      content: [
        {
          type: 'text',
          text: JSON.stringify({ result: 'Success!' })
        }
      ]
    };
  }
  throw new Error('Tool not found');
});

const transport = new StdioServerTransport();
await server.connect(transport);

// client.ts - Use your MCP server
const toolset = new McpToolset({
  name: 'My Custom Server',
  transport: {
    mode: 'stdio',
    command: 'npx',
    args: ['tsx', './server.ts']
  }
});

const tools = await toolset.getTools();

Remote MCP Servers

Connect to remote MCP endpoints via HTTP:
import { McpGeneric } from '@iqai/adk';

// Remote server (automatically uses mcp-remote)
const remoteToolset = McpGeneric(
  'https://mcp.example.com/api',
  {
    env: {
      API_KEY: process.env.REMOTE_API_KEY
    }
  }
);

const tools = await remoteToolset.getTools();

Error Handling

import { McpError, McpErrorType } from '@iqai/adk';

try {
  const toolset = McpCoinGecko();
  const tools = await toolset.getTools();
} catch (error) {
  if (error instanceof McpError) {
    switch (error.type) {
      case McpErrorType.CONNECTION_ERROR:
        console.error('Failed to connect to MCP server');
        break;
      case McpErrorType.RESOURCE_CLOSED_ERROR:
        console.error('MCP toolset was closed');
        break;
      default:
        console.error('MCP error:', error.message);
    }
  } else {
    console.error('Unknown error:', error);
  }
}

Lifecycle Management

Properly close MCP connections:
const toolset = McpCoinGecko();

try {
  const tools = await toolset.getTools();
  
  // Use tools with agent
  const agent = new AgentBuilder()
    .withTools(tools)
    .buildLlm();
    
  await agent.ask('Get Bitcoin price');
} finally {
  // Clean up
  await toolset.close();
}

// Or use dispose()
await toolset.dispose();

Best Practices

Always validate and sanitize data from external MCP servers before using it in production.

Environment Variables

Store sensitive credentials securely:
// Good: Use environment variables
const toolset = McpNearAgent({
  env: {
    ACCOUNT_ID: process.env.NEAR_ACCOUNT_ID,
    ACCOUNT_KEY: process.env.NEAR_ACCOUNT_KEY
  }
});

// Avoid: Hardcoded credentials
const toolset = McpNearAgent({
  env: {
    ACCOUNT_ID: 'my-account.testnet',  // Don't hardcode
    ACCOUNT_KEY: 'ed25519:...'  // Never commit keys
  }
});

Resource Cleanup

Always close toolsets when done:
const toolsets = [
  McpCoinGecko(),
  McpDefillama(),
  McpNearAgent({ /* ... */ })
];

try {
  const allTools = await Promise.all(
    toolsets.map(t => t.getTools())
  );
  
  // Use tools
} finally {
  // Clean up all toolsets
  await Promise.all(toolsets.map(t => t.close()));
}

Error Recovery

Implement retry logic for transient failures:
const toolset = McpCoinGecko({
  debug: true,
  retryOptions: {
    maxRetries: 5,
    initialDelay: 500
  }
});

Next Steps

Creating Tools

Learn how to create custom tools

Built-in Tools

Explore all built-in tools

Build docs developers (and LLMs) love