How-to: Integrate an External Tool via MCP
Relevant source files
The following files were used as context for generating this wiki page: - [README.md](https://github.com/eenlars/lucky/blob/HEAD/README.md) - [apps/examples/mcp-config.example.json](https://github.com/eenlars/lucky/blob/HEAD/apps/examples/mcp-config.example.json) - [apps/web/src/app/api/mcp/config/route.ts](https://github.com/eenlars/lucky/blob/HEAD/apps/web/src/app/api/mcp/config/route.ts) - [packages/core/README.md](https://github.com/eenlars/lucky/blob/HEAD/packages/core/README.md) - [packages/core/src/tools/README.md](https://github.com/eenlars/lucky/blob/HEAD/packages/core/src/tools/README.md) - [packages/mcp-server/README.md](https://github.com/eenlars/lucky/blob/HEAD/packages/mcp-server/README.md) - [packages/mcp-server/src/index.ts](https://github.com/eenlars/lucky/blob/HEAD/packages/mcp-server/src/index.ts) - [packages/tools/PROBLEM_STATEMENT.md](https://github.com/eenlars/lucky/blob/HEAD/packages/tools/PROBLEM_STATEMENT.md) - [packages/tools/README.md](https://github.com/eenlars/lucky/blob/HEAD/packages/tools/README.md) - [packages/tools/REGISTRATION.md](https://github.com/eenlars/lucky/blob/HEAD/packages/tools/REGISTRATION.md) - [packages/tools/REQUIREMENTS.md](https://github.com/eenlars/lucky/blob/HEAD/packages/tools/REQUIREMENTS.md) - [packages/tools/src/mcp/__tests__/mcp-setup.test.ts](https://github.com/eenlars/lucky/blob/HEAD/packages/tools/src/mcp/__tests__/mcp-setup.test.ts) - [packages/tools/src/mcp/setup.ts](https://github.com/eenlars/lucky/blob/HEAD/packages/tools/src/mcp/setup.ts) - [packages/tools/src/registration/mcpToolsRegistration.ts](https://github.com/eenlars/lucky/blob/HEAD/packages/tools/src/registration/mcpToolsRegistration.ts)The Lucky framework supports two types of tools for AI agents: Code Tools and MCP Tools. This guide focuses on integrating MCP Tools, which are external processes that communicate with the main application using the Model Context Protocol (MCP). This allows for language-agnostic, isolated tool execution, making it ideal for integrating third-party services or complex, standalone functionalities.
Unlike Code Tools, which are TypeScript functions running in the same process, MCP tools run as separate server processes. The core execution engine communicates with them via a standardized protocol, typically over stdio. This guide details the architecture, configuration, and runtime execution flow for integrating MCP tools into a workflow.
Sources: packages/core/src/tools/README.md:4-11, 60-64, README.md:104-112
Architecture Overview
Integrating an MCP tool involves four main components: the MCP Server, the Configuration File, the MCP Client Manager within the @lucky/tools package, and the Workflow Node that uses the tool.
The diagram below illustrates the relationship between these components.
This diagram shows a workflow node requesting an MCP tool, which triggers setupMCPForNode to read the configuration, spawn the external server process, and establish communication to make the tool available.
Sources: packages/tools/src/mcp/setup.ts, README.md:114-123
Step 1: Create or Identify an MCP Server
An MCP server is a standalone application that exposes its functionality (tools) over the Model Context Protocol. The Lucky project provides examples and integrates with existing servers. A server can be built using libraries like fastmcp.
Key characteristics of an MCP server:
- It can be a simple script or a full-fledged application.
- It communicates over
stdio(default) or HTTP. - It must respond to MCP requests to list its available tools and execute them.
The lucky-mcp-server is a reference implementation that can be run via npx. It uses the fastmcp library to define and expose tools.
Sources: packages/mcp-server/README.md:14-16, packages/mcp-server/src/index.ts:1-15, 303-320
Step 2: Configure the MCP Server
The connection between the Lucky framework and an MCP server is defined in a JSON configuration file, typically named mcp-secret.json. The path to this file is specified by the MCP_SECRET_PATH environment variable.
This file contains an mcpServers object where each key is the name of a server (e.g., "tavily", "firecrawl"). This name is used to request the tool in a workflow.
Configuration Structure
The configuration for each server specifies how to run it as a child process.
| Field | Type | Description | Required |
|---|---|---|---|
command | string | The executable command to run the server (e.g., npx, python). | Yes |
args | string[] | An array of arguments to pass to the command. | Yes |
env | Record<string, string> | An optional map of environment variables to set for the server process, such as API keys. | No |
Sources: packages/tools/src/mcp/setup.ts:51-58, apps/examples/mcp-config.example.json
Example mcp-secret.json
This example configures three different MCP servers: tavily, firecrawl, and proxy. Note the use of environment variable substitution (${TAVILY_API_KEY}) which will be replaced at runtime with the value from the main application's environment.
{
"mcpServers": {
"tavily": {
"command": "npx",
"args": ["@tavily/mcp-server"],
"env": {
"TAVILY_API_KEY": "${TAVILY_API_KEY}"
}
},
"firecrawl": {
"command": "npx",
"args": ["-y", "firecrawl-mcp"],
"env": {
"FIRECRAWL_API_KEY": "${FIRECRAWL_API_KEY}"
}
},
"proxy": {
"command": "bun",
"args": ["run", "apps/mcp-servers-examples/webshare-proxy/src/index.ts"]
}
}
}
Sources: apps/examples/mcp-config.example.json, packages/tools/src/mcp/setup.ts:16-26
Step 3: Runtime Integration
At runtime, when a workflow node requires an MCP tool, the setupMCPForNode function is called. This function orchestrates the entire process of finding, launching, and connecting to the MCP server.
The setupMCPForNode Function
This function is the core of MCP integration. Its responsibilities include:
- Loading Configuration: It loads the
mcp-secret.jsonfile. - Client Caching: It maintains a cache of active MCP clients, keyed by
workflowIdand tool name. This ensures that for a given workflow, the same server process is reused, maintaining state (e.g., a browser session in a Playwright tool). - Process Spawning: If a client is not cached, it uses the configuration to spawn the MCP server as a child process via
Experimental_StdioMCPTransport. - Client Creation: It uses
experimental_createMCPClientfrom theaiSDK to create a client that communicates with the spawned process. - Tool Fetching: It calls the
client.tools()method to get the list of tools exposed by the server. - ToolSet Aggregation: It merges the tools from all requested MCP servers into a single
ToolSetobject, which is compatible with the Vercel AI SDK'sgenerateTextfunction.
Sources: packages/tools/src/mcp/setup.ts:222-333, packages/tools/README.md:100-106
Execution Flow
The following sequence diagram shows the detailed flow when setupMCPForNode is called for the first time for a specific tool within a workflow.
This diagram illustrates the lazy-initialization and caching mechanism that ensures efficient reuse of MCP server processes.
Sources: packages/tools/src/mcp/setup.ts:246-301
Configuration Resolution Order
The system supports multiple sources for MCP configuration, which are resolved in a specific order. This allows for dynamic, per-request configurations (e.g., from a UI) to override static file-based configurations.
- Context Toolkits: Configuration passed directly in the
opts.toolkitsparameter tosetupMCPForNode. This is typically used for configurations originating from the UI. - Config File: The
mcp-secret.jsonfile located via theMCP_SECRET_PATHenvironment variable. This is the standard method for local development.
If a tool is defined in both the context and the file, the context toolkit definition takes precedence.
Sources: packages/tools/src/mcp/setup.ts:259-281, README.md:114-128
Available MCP Toolkits
The project pre-defines several toolkits for common external services. These are logical groupings of tools that are often used together.
| Toolkit Name | Tools Included | Description |
|---|---|---|
web-search | tavily, serpAPI, googleScholar | Tools for performing web searches. |
web-scraping | firecrawl, browserUse, playwright | Tools for scraping and interacting with websites. |
filesystem | filesystem | Tools for interacting with the file system. |
proxy | proxy | An HTTP proxy tool. |
Sources: packages/tools/README.md:76-92, packages/tools/REGISTRATION.md:46-52
Summary
Integrating an external tool via MCP is a powerful way to extend the capabilities of AI agents in the Lucky framework. The process relies on a clear separation of concerns: the tool logic resides in an independent server process, while the integration is handled declaratively through a JSON configuration file. The framework's setupMCPForNode function provides a robust, cached, and stateful connection mechanism, making these external tools seamlessly available to any workflow node.