> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/open-webui/open-webui/llms.txt
> Use this file to discover all available pages before exploring further.

# Plugin Development

> Learn how to develop plugins, pipelines, and custom functions for Open WebUI

## Overview

Open WebUI provides several extensibility mechanisms to add custom functionality:

1. **Pipelines** - Python-based middleware for LLM interactions
2. **Functions/Tools** - Native Python functions with code editor
3. **MCP Servers** - Model Context Protocol integration

## Pipelines Plugin Framework

Pipelines allow you to inject custom logic and Python libraries into Open WebUI's request/response flow.

### What Are Pipelines?

Pipelines act as middleware between Open WebUI and LLM providers, enabling:

* Rate limiting and usage controls
* Request/response filtering and modification
* Custom authentication and authorization
* Integration with monitoring tools (Langfuse, etc.)
* Translation services
* Content moderation and toxic message filtering
* Custom model routing logic

### Repository

Pipelines are maintained in a separate repository:
[https://github.com/open-webui/pipelines](https://github.com/open-webui/pipelines)

### Getting Started with Pipelines

#### 1. Clone the Pipelines Repository

```bash theme={null}
git clone https://github.com/open-webui/pipelines.git
cd pipelines
```

#### 2. Install Dependencies

```bash theme={null}
pip install -r requirements.txt
```

#### 3. Run Pipelines Server

```bash theme={null}
python main.py
```

The server starts on `http://localhost:9099` by default.

#### 4. Connect to Open WebUI

In Open WebUI settings:

1. Go to **Admin Settings** → **Connections**
2. Set OpenAI API URL to: `http://localhost:9099`
3. Pipelines will now intercept requests

### Creating a Custom Pipeline

Pipelines are Python classes that inherit from base pipeline types.

#### Basic Pipeline Structure

```python theme={null}
from typing import List, Optional
from pydantic import BaseModel

class Pipeline:
    """
    Example pipeline that adds a prefix to all messages
    """
    
    class Valves(BaseModel):
        """Configuration that can be modified via UI"""
        prefix: str = "[Custom] "
        enabled: bool = True
    
    def __init__(self):
        self.name = "Message Prefix Pipeline"
        self.valves = self.Valves()
    
    async def on_startup(self):
        """Called when pipeline initializes"""
        print(f"Pipeline {self.name} started")
    
    async def on_shutdown(self):
        """Called when pipeline shuts down"""
        print(f"Pipeline {self.name} stopped")
    
    async def inlet(self, body: dict, user: Optional[dict] = None) -> dict:
        """
        Modify the request before sending to LLM
        """
        if self.valves.enabled and "messages" in body:
            # Add prefix to the last user message
            if body["messages"]:
                last_message = body["messages"][-1]
                if last_message.get("role") == "user":
                    last_message["content"] = (
                        self.valves.prefix + last_message["content"]
                    )
        
        return body
    
    async def outlet(self, body: dict, user: Optional[dict] = None) -> dict:
        """
        Modify the response after receiving from LLM
        """
        # Process the response here
        return body
```

#### Save Your Pipeline

Save the file in the `pipelines/` directory:

```
pipelines/
  examples/
  your_pipeline.py  ← Your custom pipeline
```

Restart the pipelines server to load your pipeline.

### Pipeline Examples

Explore real-world examples in the repository:

**Rate Limiting**:

```python theme={null}
# pipelines/examples/rate_limit_pipeline.py
# Control user request rates
```

**Translation**:

```python theme={null}
# pipelines/examples/libretranslate_pipeline.py
# Automatic message translation
```

**Content Filtering**:

```python theme={null}
# pipelines/examples/toxic_message_filter_pipeline.py
# Block toxic or harmful content
```

**Usage Monitoring**:

```python theme={null}
# pipelines/examples/langfuse_pipeline.py
# Track usage with Langfuse
```

**Function Calling**:

```python theme={null}
# pipelines/examples/function_calling_pipeline.py
# Custom function/tool execution
```

### Pipeline Methods

#### Core Methods

* `__init__()` - Initialize pipeline and valves
* `on_startup()` - Setup code (load models, connect to services)
* `on_shutdown()` - Cleanup code
* `inlet(body, user)` - Intercept and modify requests
* `outlet(body, user)` - Intercept and modify responses

#### Advanced Methods

* `pipe()` - Full control over request/response cycle
* `on_valves_updated()` - React to configuration changes

### Valves (Configuration)

Valves are pipeline settings that can be modified through the UI:

```python theme={null}
class Valves(BaseModel):
    api_key: str = ""
    max_tokens: int = 1000
    temperature: float = 0.7
    enabled: bool = True
```

Users can update these values without modifying code.

## Native Python Functions/Tools

Open WebUI includes a built-in code editor for creating Python functions that LLMs can call.

### Creating a Function

1. Navigate to **Workspace** → **Tools**
2. Click **Create New Tool**
3. Write your Python function
4. Save and enable

### Function Structure

```python theme={null}
"""
title: Weather Tool
author: Your Name
version: 1.0.0
"""

import requests
from typing import Optional

def get_weather(
    location: str,
    units: str = "celsius",
    __user__: Optional[dict] = None
) -> str:
    """
    Get current weather for a location.
    
    :param location: City name or coordinates
    :param units: Temperature units (celsius or fahrenheit)
    :return: Weather description
    """
    
    # Your implementation here
    api_key = "your-api-key"
    url = f"https://api.weather.com/v1/current?location={location}"
    
    response = requests.get(url, params={"units": units})
    data = response.json()
    
    return f"Weather in {location}: {data['temperature']}° {units}"
```

### Function Features

* **Type Hints**: Use Python type hints for LLM parameter understanding
* **Docstrings**: Provide clear descriptions for the LLM
* **User Context**: Access `__user__` parameter for user information
* **Dependencies**: Import standard library or installed packages
* **Error Handling**: Implement proper error handling

### Installing Dependencies

Functions can use any Python package installed in the Open WebUI environment:

```bash theme={null}
pip install requests aiohttp pandas
```

Or add to `pyproject.toml` for permanent installation.

### Function Security

**Safe Mode**: Enable safe mode to deactivate all functions:

```bash theme={null}
export SAFE_MODE=true
```

**RestrictedPython**: Functions run in a restricted environment to prevent dangerous operations.

## MCP (Model Context Protocol) Servers

MCP servers provide standardized context to LLMs through a protocol.

### Configuring MCP Servers

```bash theme={null}
export MCP_SERVERS='{
  "filesystem": {
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/files"]
  }
}'
```

### Available MCP Servers

* **Filesystem**: File system access
* **Git**: Repository interaction
* **GitHub**: GitHub API integration
* **Slack**: Slack workspace integration
* **PostgreSQL**: Database queries
* **Brave Search**: Web search

See [MCP Documentation](https://modelcontextprotocol.io/) for more servers.

## Tool/Terminal Servers

Connect external tool servers to Open WebUI.

### Configuration

```bash theme={null}
export TOOL_SERVER_CONNECTIONS='[
  {
    "name": "My Tool Server",
    "url": "http://localhost:5000",
    "api_key": "your-api-key"
  }
]'
```

### Terminal Server

Provide terminal access for code execution:

```bash theme={null}
export TERMINAL_SERVER_CONNECTIONS='[
  {
    "name": "Code Runner",
    "url": "http://localhost:8000"
  }
]'
```

## Development Best Practices

### Testing

1. Test locally before deploying
2. Use the dev environment for iteration
3. Test with various LLM providers
4. Validate error handling

### Error Handling

```python theme={null}
async def inlet(self, body: dict, user: Optional[dict] = None) -> dict:
    try:
        # Your logic here
        return body
    except Exception as e:
        print(f"Pipeline error: {e}")
        # Decide: pass through or modify
        return body
```

### Logging

```python theme={null}
import logging

logger = logging.getLogger(__name__)

async def inlet(self, body: dict, user: Optional[dict] = None) -> dict:
    logger.info(f"Processing request for user: {user.get('name')}")
    # Your logic
    return body
```

### Performance

* Use async/await for I/O operations
* Cache expensive computations
* Avoid blocking operations in pipelines
* Consider rate limiting for external APIs

### Security

* Validate all user inputs
* Use environment variables for secrets
* Implement proper authentication
* Sanitize outputs before returning
* Be cautious with code execution

## Deployment

### Production Pipelines

For production deployments:

```bash theme={null}
# Use Docker
docker run -d -p 9099:9099 \
  -v ./pipelines:/app/pipelines \
  --name pipelines \
  ghcr.io/open-webui/pipelines:main
```

### Environment Variables

```bash theme={null}
export PIPELINES_DIR="./custom_pipelines"
export PIPELINES_PORT="9099"
export PIPELINES_HOST="0.0.0.0"
```

## Examples and Templates

### Complete Pipeline Example

See the [Pipelines Examples Directory](https://github.com/open-webui/pipelines/tree/main/examples) for:

* Authentication pipelines
* Rate limiting
* Content filtering
* Custom model routing
* Monitoring integrations
* Translation services

### Function Examples

Check the Open WebUI community for shared functions:

* [Open WebUI Community](https://openwebui.com/)

## Troubleshooting

### Pipeline Not Loading

1. Check pipeline file syntax
2. Ensure class is named `Pipeline`
3. Verify no import errors
4. Check pipelines server logs

### Function Not Executing

1. Verify function is enabled
2. Check for syntax errors in code editor
3. Ensure dependencies are installed
4. Review function logs

### Performance Issues

1. Profile slow pipelines
2. Use async operations
3. Implement caching
4. Consider moving logic to background tasks

## Resources

* [Pipelines Repository](https://github.com/open-webui/pipelines)
* [MCP Documentation](https://modelcontextprotocol.io/)
* [Open WebUI Community](https://openwebui.com/)
* [Discord Server](https://discord.gg/5rJgQTnV4s)

## Next Steps

* Review [Architecture](/development/architecture) to understand integration points
* Set up [Local Development](/development/local-setup) environment
* Read [Contributing Guidelines](/development/contributing)
* Explore example pipelines and functions
* Join the community and share your creations!
