# Filmladder MCP Server
A Model Context Protocol (MCP) server that provides movie listings and recommendations for Amsterdam cinemas by scraping [filmladder.nl](https://www.filmladder.nl/amsterdam/bioscopen).
## Features
- **List Movies**: Get all movies playing in Amsterdam cinemas, optionally filtered by date
- **Get Showtimes**: Find all showtimes for a specific movie (with fuzzy title matching)
- **Cinema Movies**: List all movies playing at a specific cinema
- **Recommendations**: Get movie recommendations based on rating, preferred showtimes, cinemas, and date
## Requirements
- Python 3.11 or higher
- Poetry for dependency management
## Installation
1. Clone the repository:
```bash
git clone <repository-url>
cd filmladder-mcp
```
2. Install dependencies using Poetry:
```bash
poetry install
```
3. Install pre-commit hooks (optional but recommended):
```bash
poetry run pre-commit install
```
4. Copy `.env.example` to `.env` and adjust configuration if needed:
```bash
cp .env.example .env
```
## Usage
### Running the MCP Server
The server uses stdio transport and can be run directly:
```bash
poetry run python -m src.server
```
### Connecting to Cursor IDE
To use this MCP server in Cursor:
1. **Project-specific configuration** (recommended):
- The project includes a `.cursor/mcp.json` file with the server configuration
- Cursor should automatically detect it when you open this project
2. **Manual configuration**:
- Open Cursor Settings (gear icon)
- Go to **Tools & Integrations** → **MCP Tools**
- Click **Add Custom MCP** or edit `mcp.json`
- Add the following configuration:
```json
{
"mcpServers": {
"filmladder-mcp": {
"command": "poetry",
"args": ["run", "python", "-m", "src.server"],
"cwd": "/path/to/filmladder-mcp"
}
}
}
```
**Important**: Replace `/path/to/filmladder-mcp` with the actual path to this project directory.
3. **Verify connection**:
- After saving, Cursor should show "filmladder-mcp" in the MCP Tools section
- You can test it by asking Cursor: "What movies are playing in Amsterdam today?"
### Using the MCP Tools in Cursor
Once connected, you can use the tools in Cursor's chat:
- **List movies**: "What movies are playing in Amsterdam?"
- **Get showtimes**: "When is Nuremberg playing?"
- **Cinema movies**: "What movies are playing at Pathé Tuschinski?"
- **Recommendations**: "Recommend me a movie with rating above 7.0 for tonight"
### MCP Tools
The server exposes the following tools:
#### `list_movies`
List all movies playing in Amsterdam cinemas.
**Parameters:**
- `date` (optional): Date filter in YYYY-MM-DD format
**Example:**
```json
{
"date": "2025-01-15"
}
```
#### `get_showtimes`
Get all showtimes for a specific movie (fuzzy matching on title).
**Parameters:**
- `movie_title` (required): Title of the movie
**Example:**
```json
{
"movie_title": "Nuremberg"
}
```
#### `list_cinema_movies`
List all movies playing at a specific cinema.
**Parameters:**
- `cinema_name` (required): Name of the cinema
**Example:**
```json
{
"cinema_name": "Pathé Tuschinski"
}
```
#### `recommend_movies`
Recommend movies based on various criteria.
**Parameters:**
- `min_rating` (optional): Minimum rating threshold (default: 0.0)
- `preferred_times` (optional): Array of preferred showtimes in HH:MM format
- `preferred_cinemas` (optional): Array of preferred cinema names
- `date` (optional): Target date for recommendations in YYYY-MM-DD format
**Example:**
```json
{
"min_rating": 7.0,
"preferred_times": ["20:00", "21:00"],
"preferred_cinemas": ["Pathé Tuschinski", "EYE"],
"date": "2025-01-15"
}
```
## Testing
### Unit Tests
Run the test suite:
```bash
poetry run pytest tests/
```
Run with verbose output:
```bash
poetry run pytest tests/ -v
```
### Quick Server Test
Test that the server initializes correctly:
```bash
poetry run python test_server.py
```
This will verify that:
- The server can be imported
- Tools are registered correctly
- Basic functionality works
### Testing with MCP Inspector
The recommended way to test the full MCP server is using the [MCP Inspector](https://www.stainless.com/mcp/how-to-test-mcp-servers):
1. Install MCP Inspector (if not already installed):
```bash
npm install -g @modelcontextprotocol/inspector
```
2. Run the inspector:
```bash
npx @modelcontextprotocol/inspector
```
3. Configure the inspector to use your server:
- Server command: `poetry run python -m src.server`
- Transport: stdio
4. The inspector will provide an interactive interface to test all tools.
### Manual Testing
You can also test the server manually by running it and sending JSON-RPC messages via stdin:
```bash
poetry run python -m src.server
```
Then send initialization and tool call requests in JSON-RPC format.
## Development
### Code Quality
This project uses:
- **ruff** for linting and import sorting
- **black** for code formatting
- **mypy** for type checking
- **pre-commit** hooks to ensure code quality
- **pytest** for testing
Run linting and formatting:
```bash
poetry run ruff check src/
poetry run black src/
poetry run mypy src/
```
Run tests:
```bash
poetry run pytest tests/
```
### Project Structure
```
filmladder-mcp/
├── src/
│ ├── __init__.py
│ ├── server.py # MCP server entry point
│ ├── scraper.py # Web scraping logic
│ ├── models.py # Pydantic data models
│ ├── config.py # Pydantic-settings configuration
│ └── recommender.py # Recommendation logic
├── pyproject.toml # Poetry dependencies and project config
├── .pre-commit-config.yaml # Pre-commit hooks configuration
├── .cursorrules # Cursor IDE rules
├── README.md # This file
└── .env.example # Example environment variables
```
### Type Annotations
All code must use type annotations. The project follows Python 3.11+ type hinting conventions:
- Use `list[T]` instead of `List[T]`
- Use `str | None` instead of `Optional[str]`
- All functions, methods, and variables must be typed
### Pydantic Models
All data structures use Pydantic BaseModel for validation and serialization. Configuration uses `pydantic-settings` for environment variable support.
## Error Handling
The server handles:
- Network errors (HTTP timeouts, connection failures)
- Parsing errors (HTML structure changes)
- Invalid input parameters
Errors are raised as exceptions that the MCP framework will handle appropriately.
## License
[Add your license here]
## Contributing
[Add contributing guidelines here]