|
All checks were successful
Go Format and Build / fmt-and-build (push) Successful in 18s
|
||
|---|---|---|
| .forgejo/workflows | ||
| cmd | ||
| configs | ||
| internal | ||
| .gitignore | ||
| go.mod | ||
| go.sum | ||
| Makefile | ||
| README.md | ||
McDonald's MCP Server
A Model Context Protocol (MCP) server for accessing McDonald's API with automatic authentication, written in Go using the official MCP SDK.
Features
- 🔐 Automatic Authentication: Handles McDonald's OAuth flow with magic link email verification
- 📧 IMAP Integration: Automatically fetches magic links from email
- 💾 PostgreSQL Database: Stores authentication tokens and can track orders/menu items
- 🌐 Dual Transport: Supports both stdio (for MCP clients) and HTTP modes
- 🔄 Token Management: Automatic token refresh with fallback to full re-authentication
- 🛠️ GORM Models: Ready-to-use database models for orders, menu items, locations, etc.
Prerequisites
- Go 1.23 or higher
- PostgreSQL database
- Email account with IMAP access (for receiving McDonald's magic links)
- McDonald's account email
Installation
- Clone the repository:
git clone https://forge.wolfhound.dev/wolfhound/mc-mcp.git
cd mc-mcp
- Install dependencies:
make deps
# or manually: go mod download && go mod tidy
- Create your configuration:
cp configs/.env.example .env
# Edit .env with your settings
- Build the server:
make build
# or manually: go build -o bin/mc-mcp ./cmd/mc-mcp
Configuration
Create a .env file with the following settings:
PostgreSQL Configuration
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DATABASE=mcdonalds
POSTGRES_USERNAME=postgres
POSTGRES_PASSWORD=your_password
POSTGRES_SSLMODE=disable
IMAP Email Configuration
Required for receiving McDonald's magic link emails:
IMAP_HOST=imap.gmail.com
IMAP_PORT=993
IMAP_USERNAME=your-email@gmail.com
IMAP_PASSWORD=your_app_password
IMAP_MAILBOX=INBOX
# Set to true to skip TLS verification (needed for Proton Mail Bridge)
IMAP_INSECURE_SKIP_VERIFY=false
Notes:
- For Gmail, you'll need to use an App Password.
- For Proton Mail Bridge, set
IMAP_INSECURE_SKIP_VERIFY=trueto skip TLS certificate verification (Bridge uses self-signed certificates).
McDonald's Configuration
MCD_EMAIL=your-mcdonalds-account@example.com
Server Configuration
# Set to true for HTTP mode, false for stdio (MCP client mode)
HTTP_ENABLED=false
HTTP_HOST=localhost
HTTP_PORT=8080
# Logging level: DEBUG, INFO, WARNING, ERROR, CRITICAL
LOG_LEVEL=INFO
Database Setup
The server automatically creates all necessary tables on startup using GORM migrations. Tables include:
- accounts: Stores McDonald's OAuth tokens
- orders: Order history
- order_items: Individual items in orders
- menu_items: Menu item catalog
- locations: Restaurant locations
- email_logs: Email processing history
- nutrition_infos: Nutritional information
Usage
Running in Stdio Mode (for MCP Clients)
This is the default mode for use with Claude Desktop or other MCP clients:
make run
# or manually: ./bin/mc-mcp
Running in HTTP Mode
For standalone HTTP API access:
make run-http
# or manually: HTTP_ENABLED=true ./bin/mc-mcp
The server will be available at:
- MCP endpoint:
http://localhost:8080/mcp - Health check:
http://localhost:8080/health
Authentication Flow
On first startup:
- Server connects to PostgreSQL and runs migrations
- Checks for existing authentication tokens in database
- If no tokens found:
- Requests magic link from McDonald's API
- Connects to IMAP to fetch magic link from email
- Activates account and retrieves OAuth tokens
- Saves tokens to database
- If tokens exist:
- Loads tokens from database
- Attempts to refresh access token
- Falls back to full re-authentication if refresh fails
Available MCP Tools
The server provides the following tools for interacting with McDonald's API:
1. get_offers
Get available McDonald's offers and deals.
Arguments: None
Example Response:
{
"response": {
"offers": [...]
}
}
2. get_restaurants
Find McDonald's restaurants near a location.
Arguments:
latitude(float, required): Latitude coordinatelongitude(float, required): Longitude coordinateradius(int, optional): Search radius in miles (default: 10)
Example:
{
"latitude": 40.7128,
"longitude": -74.0060,
"radius": 5
}
3. get_menu
Get the menu for a specific McDonald's restaurant.
Arguments:
restaurant_id(string, required): McDonald's restaurant ID
Example:
{
"restaurant_id": "12345"
}
4. get_account
Get the current McDonald's account information.
Arguments: None
5. get_orders
Get the user's McDonald's order history.
Arguments: None
Development
Project Structure
mc-mcp/
├── cmd/
│ └── mc-mcp/ # Main application entry point
│ └── main.go
├── internal/ # Private application code
│ ├── auth/ # Authentication logic
│ │ └── auth.go
│ ├── config/ # Configuration management
│ │ └── config.go
│ ├── database/ # Database models and initialization
│ │ ├── database.go
│ │ └── models.go
│ ├── email/ # IMAP email fetching
│ │ └── fetcher.go
│ ├── mcd/ # McDonald's API client
│ │ └── client.go
│ └── server/ # MCP server and tool handlers
│ └── server.go
├── configs/ # Configuration files
│ └── .env.example
├── bin/ # Compiled binaries (created by build)
├── go.mod # Go module dependencies
├── go.sum # Dependency checksums
├── Makefile # Build automation
└── README.md # This file
Adding New Tools
To add a new MCP tool, edit internal/server/server.go:
- Define argument struct:
type NewToolArgs struct {
Param string `json:"param" jsonschema:"description=Parameter description,required"`
}
- Register tool in
registerMcDonaldsTools():
mcp.AddTool(server, &mcp.Tool{
Name: "new_tool",
Description: "Tool description",
}, handleNewTool)
- Implement handler:
func handleNewTool(ctx context.Context, request *mcp.CallToolRequest, args NewToolArgs) (*mcp.CallToolResult, string, error) {
if err := auth.EnsureAuthenticated(database.DB); err != nil {
return nil, "", err
}
// Call McDonald's API
data, err := auth.Client.SomeMethod(args.Param)
if err != nil {
return nil, "", err
}
jsonData, _ := json.Marshal(data)
return nil, string(jsonData), nil
}
Adding New API Methods
To add new McDonald's API endpoints, edit internal/mcd/client.go:
func (c *Client) NewMethod(param string) (map[string]interface{}, error) {
path := "/exp/v1/new/endpoint"
data, err := c.request("GET", path, nil, nil)
if err != nil {
return nil, fmt.Errorf("failed to call endpoint: %w", err)
}
return data, nil
}
Makefile Commands
make build- Build the applicationmake run- Build and run (stdio mode)make run-http- Build and run (HTTP mode)make test- Run testsmake clean- Remove build artifactsmake deps- Download and tidy dependenciesmake fmt- Format codemake help- Show all available commands
API Credentials
The McDonald's API credentials are hardcoded in internal/mcd/client.go:
- Client ID:
8cGckR5wPgQnFBc9deVhJ2vT94WhMBRL - Client Secret:
Ym4rVyqpqNpCpmrdPGJatRrBMHhJgr26 - Device ID:
8c84f39447878d18
These are the standard credentials used by the McDonald's mobile app.
Troubleshooting
"Failed to fetch magic link"
- Ensure IMAP credentials are correct
- Check that you're using the correct mailbox name
- For Gmail, ensure "Less secure app access" is enabled or use an App Password
- Verify the McDonald's email arrived in your inbox
"TLS certificate verification error" with Proton Mail Bridge
If you see errors like x509: certificate signed by unknown authority:
# Add to your .env file:
IMAP_INSECURE_SKIP_VERIFY=true
This is safe for Proton Mail Bridge since it runs locally and uses self-signed certificates.
"Authentication expired"
- Restart the server to re-authenticate
- Check database connection
- Verify tokens in the
accountstable
Database connection errors
- Ensure PostgreSQL is running
- Verify connection credentials in
.env - Check that the database exists
Dependencies
- modelcontextprotocol/go-sdk - Official MCP SDK for Go
- GORM - ORM library
- go-imap - IMAP client
- godotenv - Environment variable loading
- uuid - UUID generation
License
[Add your license here]
Contributing
[Add contribution guidelines here]
Acknowledgments
- Based on the Python implementation at BuyMeMcDonalds
- Uses the official Model Context Protocol Go SDK maintained by Google and Anthropic