This tutorial shows you how to build and deploy a Model Context Protocol (MCP) server on Union that helps AI agents find recipes! You'll create a recipe assistant that can search by ingredients, dietary needs, and more using the Spoonacular Food API.
What you'll learn:
- How MCP servers work and their role in AI agent architectures
- Building MCP tools with Python using the official MCP Python SDK
- Deploying your MCP server on Union
- Connecting the server to AI agents in Cursor or other MCP clients
The Model Context Protocol (MCP) is an open standard that enables AI assistants to securely connect with external data sources and tools. Think of it as a universal adapter that lets AI agents interact with APIs, databases, and services.
flowchart LR
A[AI Agent<br/>Claude, etc.] <-->|MCP Protocol<br/>Tools & Resources| B[MCP Server<br/>Your Server]
B <-->|API| C[Spoonacular<br/>Food API]
- As an AI engineer, you want to connect to an external service through a pre-built, standardized, AI-friendly interface.
- As an AI engineer, you need to connect your Skills to actual external services in a compact way.
- As a service provider, you want to expose your services to AI agents in a standardized way.
- As an AI engineer, you have a self-contained AI system that makes tool calls defined as functions that you fully control.
- As an AI engineer, all of the context and skills access local resources (files, directories, embedded databases, etc).
- As a service provider, you want to expose your services as traditional APIs (REST, gRPC, etc), or the functionality you provide can be delivered via context/Skills that users can download locally.
- Python 3.11+
- A Spoonacular API key (free tier available)
- A Union account (sign up at union.ai). If you're here for a workshop, head over here and sign in.
uvpackage manager (recommended): installation link here
- Go to spoonacular.com/food-api
- Click Start Now and create a free account
- Copy your API key from the dashboard
The free tier includes 150 points/day - plenty for development and testing!
# Clone the repository
git clone https://github.com/unionai/workshops
cd workshops/tutorials/mcp
# Create virtual environment
uv venv .venv --python 3.11
# Activate the venv
source .venv/bin/activate # macOS/Linux
# or
.venv\Scripts\activate # Windows
# Install dependencies
uv pip install -r requirements.txt
# If you're in google colab or github codespaces:
uv pip install keyrings.altNext, install Claude Code: https://code.claude.com/docs/en/setup#installation
Then run claude and go through the setup process to use it with
Create a .env file in this folder:
SPOONACULAR_API_KEY=your-api-key-heretutorials/mcp/
├── README.md # This file
├── requirements.txt # Python dependencies
├── server.py # MCP server implementation
├── tools/ # Spoonacular API tools
│ ├── __init__.py
│ └── recipes.py # Recipe API wrapper
└── app.py # Union app deployment script
The Recipe MCP server provides these tools for AI agents:
| Tool | Description |
|---|---|
search_recipes |
Search recipes by name, cuisine, diet, and more |
search_by_ingredients |
Find recipes using ingredients you have |
search_by_nutrients |
Find recipes by nutritional requirements |
get_recipe_info |
Get detailed recipe information |
get_similar_recipes |
Find recipes similar to one you like |
autocomplete_recipe |
Get recipe name suggestions |
# Test the server locally
python server.pyAdd to Claude code:
claude mcp add --transport http spoonacular-mcp http://localhost:8000/mcp[!NOTE] Alternatively, test the server with the MCP inspector (local only):
npx -y @modelcontextprotocol/inspectorIn the inspector UI, connect to the server at http://localhost:8000/mcp
Once connected to an AI agent, you can ask things like:
- "What can I make with chicken, rice, and broccoli?"
- "Find me a vegan pasta recipe under 500 calories"
- "I want something similar to beef stroganoff"
- "Show me high-protein breakfast ideas"
- "What's a good gluten-free dessert?"
Once you're done testing locally, remove this MCP server from Claude:
claude mcp remove spoonacular-mcpexport FLYTE_PROJECT=<project># Configure Union CLI
flyte create config \
--endpoint tryv2.hosted.unionai.cloud \
--auth-type headless \
--builder remote \
--domain development \
--project $FLYTE_PROJECT[!NOTE] Optional: Store your API key as a secret
flyte create secret SPOONACULAR_API_KEYThis will prompt you to copy-paste your Spoonacular API key.
Set a name for your app
export APP_NAME=<my-app-name># Build the container image
python app.pyAdd the deployed server to your MCP client (e.g., Cursor, Claude Code):
For Claude Code:
claude mcp add --transport http spoonacular-mcp <app_url>/spoonacular/mcp
Where <app_url> looks something like this: https://<subdomain>.tryv2.hosted.unionai.cloud
For Cursor (~/.cursor/mcp.json):
{
"mcpServers": {
"recipe-assistant": {
"url": "https://<subdomain>.apps.tryv2.hosted.unionai.cloud/spoonacular/mcp"
}
}
}Test it by asking: "What can I make with chicken and rice?"
Great! You've
To secure the MCP server, you can use the REQUIRES_AUTH environment variable,
which is used by the app.py file.
Redeploy the app:
REQUIRES_AUTH=true python app.pyNow you should see that the connections are failing. You'll need to re-configure the MCP connection with a Flyte API key.
To create a Flyte API key, run the following command:
flyte create api-key --name <api-key-name>
The output will contain an export command like:
export FLYTE_API_KEY="<FLYTE_API_KEY>"
"<FLYTE_API_KEY>" string somewhere safe.
Now re-configure the MCP connection with the Flyte API key:
For Claude Code:
claude mcp remove spoonacular-mcp
claude mcp add --transport http spoonacular-mcp <app_url>/spoonacular/mcp --header "Authorization: Bearer <FLYTE_API_KEY>"Where <app_url> looks something like this: https://<subdomain>.tryv2.hosted.unionai.cloud
For Cursor (~/.cursor/mcp.json):
{
"mcpServers": {
"recipe-assistant": {
"url": "https://<subdomain>.apps.tryv2.hosted.unionai.cloud/spoonacular/mcp",
"headers": {
"Authorization": "Bearer <FLYTE_API_KEY>"
}
}
}
}Now you should be able to securely connect to the MCP server!
Note: to rotate the Flyte API key, you can run the following commands
flyte delete api-key <api-key-name>
flyte create api-key --name <api-key-name>from mcp.server.fastmcp import FastMCP
# Initialize the MCP server
mcp = FastMCP("Recipe Assistant")
# Define a tool
@mcp.tool()
async def search_by_ingredients(ingredients: list[str], number: int = 5) -> list[dict]:
"""Find recipes using ingredients you have on hand."""
# Call Spoonacular API
...The server wraps these Spoonacular endpoints:
- Complex Search: Full-featured recipe search with filters
- Search by Ingredients: "What's in my fridge" functionality
- Search by Nutrients: Find recipes by nutritional goals
- Recipe Information: Detailed recipe data with instructions
- Similar Recipes: Recommendation engine
- Autocomplete: Help users find recipe names
- Model Context Protocol Specification
- Union MCP Reference Implementation
- Spoonacular API Documentation
- MCP Python SDK
- You've exceeded your daily API quota (150 points on free tier)
- Wait until midnight UTC for quota reset, or upgrade your plan
- Check that your API key is correct in
.env - Ensure the environment variable is being loaded
- Verify your internet connection
- Check Spoonacular API status
- Add more tools (meal planning, wine pairing, nutrition analysis)
- Build a recipe recommendation workflow
- Integrate with shopping list APIs
- Create a meal prep planning agent