Skip to content

Use Model Context Protocol (MCP)

Learn how to configure and use Model Context Protocol (MCP) tools in Pika to connect your agents to external services and APIs without deploying custom Lambda functions.

By the end of this guide, you will:

  • Configure MCP tools to connect to external MCP servers
  • Set up OAuth 2.0 authentication for secured MCP servers
  • Define function schemas for MCP tools
  • Associate MCP tools with your agents
  • Test MCP tool invocations
  • A running Pika installation
  • Access to an MCP server (URL and authentication credentials if required)
  • Understanding of your MCP server's available functions
  • Basic knowledge of OAuth 2.0 (if using authenticated MCP servers)

MCP tools allow your agents to:

  • Access real-time data from external services
  • Integrate with third-party APIs
  • Leverage community MCP server implementations
  • Avoid deploying custom Lambda functions for each integration

Best For

  • Connecting to existing MCP-enabled services
  • Real-time data from third-party APIs
  • Rapid prototyping without Lambda deployment
  • Leveraging community MCP implementations

Consider Lambda Instead

  • Custom business logic specific to your app
  • Maximum performance requirements
  • Complex processing needs
  • When you need full control over execution

Create a basic MCP tool configuration pointing to your MCP server.

const weatherTool = {
toolId: 'weather-service',
name: 'weather-lookup',
displayName: 'Weather Service',
description: 'Get current weather conditions and forecasts',
executionType: 'mcp',
url: 'https://weather-mcp-server.example.com',
functionSchema: [
{
name: 'get_current_weather',
description: 'Get current weather for a location',
parameters: {
location: {
type: 'string',
description: 'City name or coordinates',
required: true
},
units: {
type: 'string',
description: 'Temperature units (celsius or fahrenheit)',
required: false
}
}
}
]
};

Step 2: Add OAuth Authentication (If Required)

Section titled “Step 2: Add OAuth Authentication (If Required)”

If your MCP server requires authentication, configure OAuth 2.0 client credentials.

const customerDbTool = {
toolId: 'customer-database',
name: 'customer-lookup',
displayName: 'Customer Database',
description: 'Access customer records and account information',
executionType: 'mcp',
url: 'https://customer-db-mcp.internal.com',
auth: {
clientId: process.env.MCP_CUSTOMER_CLIENT_ID,
clientSecret: process.env.MCP_CUSTOMER_CLIENT_SECRET,
tokenUrl: 'https://auth.internal.com/oauth/token'
},
functionSchema: [
{
name: 'get_customer',
description: 'Get customer details by ID or email',
parameters: {
identifier: {
type: 'string',
description: 'Customer ID or email address',
required: true
}
}
},
{
name: 'search_customers',
description: 'Search for customers by various criteria',
parameters: {
query: {
type: 'string',
description: 'Search query string',
required: true
},
limit: {
type: 'number',
description: 'Maximum number of results',
required: false
}
}
}
]
};

Never hardcode credentials. Use environment variables:

Terminal window
# .env.local or deployed environment
MCP_CUSTOMER_CLIENT_ID="your-client-id"
MCP_CUSTOMER_CLIENT_SECRET="your-client-secret"

Reference them in your configuration:

auth: {
clientId: process.env.MCP_CUSTOMER_CLIENT_ID!,
clientSecret: process.env.MCP_CUSTOMER_CLIENT_SECRET!,
tokenUrl: 'https://auth.internal.com/oauth/token'
}

The function schema tells Pika and the agent what functions are available and how to call them.

Supported parameter types:

  • string - Text values (JSON strings are auto-parsed)
  • number - Floating-point numbers
  • integer - Whole numbers
  • boolean - true/false values
  • object - JSON objects (auto-parsed from strings)
  • array - JSON arrays (auto-parsed from strings)
  • date - ISO date strings (converted to Date objects)
functionSchema: [
{
name: 'query_database',
description: 'Execute a database query with filters',
parameters: {
query: {
type: 'string',
description: 'SQL-like query string',
required: true
},
filters: {
type: 'object',
description: 'Filter conditions',
required: false,
properties: {
startDate: {
type: 'date',
description: 'Start date for filtering'
},
endDate: {
type: 'date',
description: 'End date for filtering'
},
status: {
type: 'array',
description: 'Array of status values'
}
}
},
limit: {
type: 'integer',
description: 'Maximum results to return',
required: false
}
}
}
]

Create your MCP tool using the Admin API or CDK configuration.

const response = await fetch('/api/admin/tools', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${authToken}`
},
body: JSON.stringify({
toolId: 'weather-service',
name: 'weather-lookup',
displayName: 'Weather Service',
description: 'Get weather data',
executionType: 'mcp',
url: 'https://weather-mcp-server.example.com',
functionSchema: [/* ... */]
})
});
if (response.ok) {
console.log('MCP tool created successfully');
}
// In your CDK stack
const agentData: AgentDataRequest = {
userId: `cloudformation/${this.stackName}`,
agent: {
agentId: 'customer-support-agent',
basePrompt: 'You are a customer support agent with access to real-time data.'
},
tools: [
{
toolId: 'weather-service',
executionType: 'mcp',
name: 'weather-lookup',
displayName: 'Weather Service',
description: 'Get weather data',
url: 'https://weather-mcp-server.example.com',
functionSchema: weatherFunctions
}
]
};

Add the MCP tool to your agent's tool list.

const agentData = {
agentId: 'customer-support-agent',
basePrompt: 'You are a helpful customer support agent.',
toolIds: [
'customer-database', // MCP tool
'weather-service', // MCP tool
'email-sender' // Lambda tool (mixed usage is fine)
]
};
  1. Start your local development environment:
Terminal window
cd apps/pika-chat
pnpm run dev
  1. Open a chat session with your agent
  2. Ask questions that trigger the MCP tool:
    • "What's the weather in San Francisco?"
    • "Look up customer with email john@example.com"

Check CloudWatch logs or your local console for:

  • MCP tool invocation
  • Parameters sent to MCP server
  • Response from MCP server
  • Any errors or issues

When using OAuth authentication:

  • Tokens are cached in ./oauth-tokens/ (local dev, gitignored)
  • Tokens are cached in /tmp/oauth-tokens/ (Lambda)
  • Tokens automatically refresh when expired
  • No manual token management needed
  • Verify the MCP server URL is correct and accessible
  • Check network/firewall rules allow outbound connections
  • Ensure the MCP server is running and responding
  • Test the URL directly with curl or Postman
  • Verify OAuth credentials are correct
  • Check token URL is accessible
  • Ensure environment variables are set correctly
  • Look for token expiration issues in logs
  • Verify function name in schema matches MCP server's function
  • Check function schema matches server's expected parameters
  • Review MCP server documentation for correct function names
  • Check parameter types match schema definition
  • Verify required parameters are marked correctly
  • Ensure parameter descriptions are clear for the agent
  • Test with simpler parameter structures first
const response = await fetch('/api/admin/tools/weather-service', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${authToken}`
},
body: JSON.stringify({
url: 'https://new-weather-server.example.com',
functionSchema: updatedFunctions
})
});

You can use multiple MCP servers in the same agent:

toolIds: [
'weather-mcp', // Weather data
'customer-db-mcp', // Customer database
'inventory-mcp', // Inventory system
'shipping-mcp' // Shipping tracker
]