Skip to main content
Glama
counterbeing

mealie-mcp-ts

by counterbeing
README.md
# Mealie MCP Server

An MCP (Model Context Protocol) server that enables LLMs to interact with [Mealie](https://mealie.io) - a self-hosted recipe manager and meal planner.

## Features

- **Recipe Management**: List, view, create, update, and delete recipes
- **Recipe Import**: Import recipes from URLs (supports most recipe websites)
- **Ingredient Parsing**: Automatic parsing of natural language ingredients (e.g., "2 cups flour")
- **Image Uploads**: Upload images to recipes via base64 encoding
- **Meal Planning**: Create and manage meal plans with date scheduling
- **Shopping Lists**: Full CRUD for shopping list items, plus add recipe ingredients to lists
- **Organization**: Manage categories and tags for recipe organization
- **Food Management**: List and create food items

## Installation

```bash
# Clone the repository
git clone https://github.com/your-username/mealie-mcp.git
cd mealie-mcp

# Install dependencies
pnpm install

# Build
pnpm run build
```

## Configuration

Create a `.env` file based on `.env.example`:

```bash
cp .env.example .env
```

Required environment variables:

| Variable | Description |
|----------|-------------|
| `MEALIE_URL` | URL of your Mealie instance (e.g., `http://localhost:9925`) |
| `MEALIE_API_KEY` | API key from Mealie (Settings → API Tokens) |
| `ENABLED_TOOLS` | (Optional) Comma-separated list of tools to enable |

## Usage

### With Claude Desktop

Add to your Claude Desktop configuration (`~/Library/Application Support/Claude/claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "mealie": {
      "command": "node",
      "args": ["/path/to/mealie-mcp/dist/index.js"],
      "env": {
        "MEALIE_URL": "http://localhost:9925",
        "MEALIE_API_KEY": "your-api-key"
      }
    }
  }
}
```

### Remote HTTP mode (e.g. on a NAS)

For running the server on a different machine (Synology NAS, home server, etc.), use the HTTP transport. The SDK's Streamable HTTP transport lets Claude Desktop connect over the network.

Set these env vars:

```bash
MCP_TRANSPORT=http
PORT=3000
ALLOWED_HOSTS=nas.local,192.168.1.50   # Host header allowlist (DNS rebind protection)
MEALIE_URL=http://mealie:9000           # service name if on same compose network
MEALIE_API_KEY=...
```

Claude Desktop config:

```json
{
  "mcpServers": {
    "mealie": {
      "url": "http://nas.local:3000/mcp"
    }
  }
}
```

### With Docker

The bundled `Dockerfile` defaults to HTTP transport on port 3000.

```bash
docker build -t mealie-mcp .

docker run -p 3000:3000 \
  -e MEALIE_URL=http://host.docker.internal:9925 \
  -e MEALIE_API_KEY=your-api-key \
  -e ALLOWED_HOSTS=localhost \
  mealie-mcp
```

### Compose service (attach to existing Mealie stack)

```yaml
  mealie-mcp:
    build: ./mealie-mcp
    container_name: mealie-mcp
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - MEALIE_URL=http://mealie:9000
      - MEALIE_API_KEY=${MEALIE_API_KEY}
      - ALLOWED_HOSTS=nas.local,192.168.1.50
    depends_on:
      - mealie
```

## Available Tools (25 total)

### Recipes (6 tools)

| Tool | Description |
|------|-------------|
| `list_recipes` | List all recipes with pagination |
| `get_recipe` | Get full recipe details by slug |
| `create_recipe` | Create a new recipe with ingredients and instructions |
| `update_recipe` | Update an existing recipe |
| `delete_recipe` | Delete a recipe |
| `upload_recipe_image` | Upload an image to a recipe (base64) |

### Recipe Import (2 tools)

| Tool | Description |
|------|-------------|
| `test_scrape_url` | Test if a URL can be scraped for recipe data |
| `create_recipe_from_url` | Import a recipe by scraping a URL |

### Meal Planning (4 tools)

| Tool | Description |
|------|-------------|
| `list_meal_plans` | List meal plans with optional date range filter |
| `get_todays_meal_plan` | Get today's planned meals |
| `create_meal_plan` | Create a meal plan entry for a specific date |
| `delete_meal_plan` | Delete a meal plan entry |

### Shopping Lists (6 tools)

| Tool | Description |
|------|-------------|
| `list_shopping_lists` | List all shopping lists |
| `get_shopping_list` | Get shopping list with items |
| `add_shopping_list_item` | Add an item to a shopping list |
| `update_shopping_list_item` | Update an item (quantity, note, or check/uncheck) |
| `delete_shopping_list_item` | Remove an item from a shopping list |
| `add_recipe_to_shopping_list` | Add all ingredients from a recipe to a list |

### Organization (4 tools)

| Tool | Description |
|------|-------------|
| `list_categories` | List all recipe categories |
| `create_category` | Create a new category |
| `list_tags` | List all recipe tags |
| `create_tag` | Create a new tag |

### Foods (2 tools)

| Tool | Description |
|------|-------------|
| `list_foods` | List all foods/ingredients |
| `create_food` | Create a new food item |

### Debugging (1 tool)

| Tool | Description |
|------|-------------|
| `get_current_user` | Get current API user info including group and household context |

## Important: Group Context

Mealie scopes data by **group** and **household**. When you create an API token, it inherits the group context of your current session. If recipes or other items you create via the API aren't visible in your browser:

1. Use the `get_current_user` tool to see which group the API token is associated with
2. Ensure your browser session is viewing the same group (check the URL path)
3. If needed, switch groups in Mealie's UI, then generate a new API token

## Development

```bash
# Run in development mode
pnpm run dev

# Lint
pnpm run lint

# Format
pnpm run format

# Build
pnpm run build
```

### Local Mealie Instance

Start a local Mealie instance for testing:

```bash
docker-compose up -d
```

This starts Mealie at `http://localhost:9925`.

## License

MIT

TDQS

A3.7/5.0

Scored across 27 tools

Disambiguation4/5

Most tools target distinct resources and actions clearly, with recipe CRUD, meal plans, shopping lists, foods, categories, tags, and user info separated. The three recipe creation methods (manual, URL, HTML) share intent but are differentiated by input source, and test_scrape_url adds a validation step. Shopping list item operations are distinct from adding a whole recipe's ingredients.

Naming Consistency5/5

All tool names use a consistent snake_case verb_noun pattern (list_, get_, create_, delete_, update_, upload_, add_, test_, parse_). Even longer names like create_recipe_from_url or get_todays_meal_plan follow the verb-first convention. There are no camelCase or mixed naming styles.

Tool Count4/5

27 tools is above the typical 'heavy' threshold, but the server covers many subdomains: recipes, meal plans, foods, shopping lists, categories, tags, user info, and URL scraping. Each tool has a defined role, though having three recipe creation variants inflates the count; a slightly leaner set could be achieved without losing functionality.

Completeness3/5

Core recipe management (CRUD plus image upload), meal plan basics, shopping list item operations, and URL scraping are well covered. However, there are notable gaps: no create_shopping_list or delete_shopping_list, no update/delete for categories or tags, no delete_food, and no update_meal_plan. These missing lifecycle operations could force users to rely on external tools or workarounds.

Maintenance

ActivityInactive
ResponsivenessNo issues