> ## 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.

# Manage Tools

> Create, update, delete, and configure tools

## Create Tool

<CodeGroup>
  ```bash POST /api/tools/create theme={null}
  curl -X POST "https://your-instance.com/api/tools/create" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "id": "my_custom_tool",
      "name": "My Custom Tool",
      "content": "class Tools:\n    def calculator(self, expression: str) -> str:\n        return str(eval(expression))",
      "meta": {
        "description": "A custom calculator tool"
      },
      "access_grants": []
    }'
  ```
</CodeGroup>

Create a new tool. Requires `workspace.tools` or `workspace.tools_import` permission for non-admin users.

### Request Body

<ParamField body="id" type="string" required>
  Unique identifier for the tool. Must be alphanumeric with underscores only (will be converted to lowercase).
</ParamField>

<ParamField body="name" type="string" required>
  Display name for the tool
</ParamField>

<ParamField body="content" type="string" required>
  Python source code for the tool. Must define a `Tools` class with tool methods. The system will:

  * Replace imports with internal versions
  * Load and validate the tool module
  * Extract tool specifications from the class
  * Parse frontmatter manifest
</ParamField>

<ParamField body="meta" type="object" required>
  Tool metadata

  <Expandable title="meta properties">
    <ParamField body="description" type="string">
      Description of what the tool does
    </ParamField>

    <ParamField body="manifest" type="object">
      Additional manifest data (will be populated from tool frontmatter)
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="access_grants" type="array">
  Access control configuration

  <Expandable title="access grant properties">
    <ParamField body="principal_type" type="string">
      "user" or "group"
    </ParamField>

    <ParamField body="principal_id" type="string">
      User ID, group ID, or "\*" for all
    </ParamField>

    <ParamField body="permission" type="string">
      "read" or "write"
    </ParamField>
  </Expandable>
</ParamField>

### Response

Returns the created `ToolResponse` object with ID, metadata, and specifications.

## Get Tool by ID

<CodeGroup>
  ```bash GET /api/tools/id/{id} theme={null}
  curl -X GET "https://your-instance.com/api/tools/id/my_tool" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

Retrieve a specific tool by ID. Requires read access to the tool.

### Path Parameters

<ParamField path="id" type="string" required>
  The tool identifier
</ParamField>

### Response

Returns `ToolAccessResponse` with the complete tool data and `write_access` flag.

## Update Tool

<CodeGroup>
  ```bash POST /api/tools/id/{id}/update theme={null}
  curl -X POST "https://your-instance.com/api/tools/id/my_tool/update" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "id": "my_tool",
      "name": "Updated Tool Name",
      "content": "class Tools:\n    pass",
      "meta": {
        "description": "Updated description"
      }
    }'
  ```
</CodeGroup>

Update an existing tool. Requires write access (creator, admin, or write grant).

### Request Body

Same as [Create Tool](#create-tool) request body.

## Update Tool Access

<CodeGroup>
  ```bash POST /api/tools/id/{id}/access/update theme={null}
  curl -X POST "https://your-instance.com/api/tools/id/my_tool/access/update" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "access_grants": [
        {
          "principal_type": "user",
          "principal_id": "user123",
          "permission": "read"
        },
        {
          "principal_type": "group",
          "principal_id": "group456",
          "permission": "write"
        }
      ]
    }'
  ```
</CodeGroup>

Update access control for a tool. Requires write access.

### Request Body

<ParamField body="access_grants" type="array" required>
  Array of access grant objects. Replaces existing grants.
</ParamField>

Note: Public sharing grants are filtered based on `sharing.public_tools` permission.

## Delete Tool

<CodeGroup>
  ```bash DELETE /api/tools/id/{id}/delete theme={null}
  curl -X DELETE "https://your-instance.com/api/tools/id/my_tool/delete" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

Delete a tool. Requires write access. Also removes the tool from cache and revokes all access grants.

### Response

<ResponseField name="result" type="boolean">
  `true` if deletion was successful, `false` otherwise
</ResponseField>

## Valve Management

### Get Tool Valves

<CodeGroup>
  ```bash GET /api/tools/id/{id}/valves theme={null}
  curl -X GET "https://your-instance.com/api/tools/id/my_tool/valves" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

Retrieve the current valve configuration for a tool.

### Get Valves Schema

<CodeGroup>
  ```bash GET /api/tools/id/{id}/valves/spec theme={null}
  curl -X GET "https://your-instance.com/api/tools/id/my_tool/valves/spec" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

Retrieve the valve schema definition (if the tool defines a `Valves` class).

### Update Tool Valves

<CodeGroup>
  ```bash POST /api/tools/id/{id}/valves/update theme={null}
  curl -X POST "https://your-instance.com/api/tools/id/my_tool/valves/update" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "api_key": "new_value",
      "enabled": true
    }'
  ```
</CodeGroup>

Update valve configuration. Requires write access.

## User Valves

### Get User Valves

<CodeGroup>
  ```bash GET /api/tools/id/{id}/valves/user theme={null}
  curl -X GET "https://your-instance.com/api/tools/id/my_tool/valves/user" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

Retrieve user-specific valve values for the authenticated user.

### Get User Valves Schema

<CodeGroup>
  ```bash GET /api/tools/id/{id}/valves/user/spec theme={null}
  curl -X GET "https://your-instance.com/api/tools/id/my_tool/valves/user/spec" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

Retrieve the user valve schema definition (if the tool defines a `UserValves` class).

### Update User Valves

<CodeGroup>
  ```bash POST /api/tools/id/{id}/valves/user/update theme={null}
  curl -X POST "https://your-instance.com/api/tools/id/my_tool/valves/user/update" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "preference": "value"
    }'
  ```
</CodeGroup>

Update user-specific valve values. Stored in user settings.

## Load Tool from URL

<CodeGroup>
  ```bash POST /api/tools/load/url theme={null}
  curl -X POST "https://your-instance.com/api/tools/load/url" \
    -H "Authorization: Bearer YOUR_ADMIN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://github.com/user/repo/blob/main/tool.py"
    }'
  ```
</CodeGroup>

Load a tool from a GitHub URL. Supports both file and folder URLs. Requires admin privileges.

### Request Body

<ParamField body="url" type="string" required>
  GitHub URL to the tool file or folder. URLs are automatically converted to raw\.githubusercontent.com format.
</ParamField>

### Response

<ResponseField name="name" type="string">
  Suggested tool name extracted from the filename/folder
</ResponseField>

<ResponseField name="content" type="string">
  Tool source code
</ResponseField>

## Python Tool Pattern

Tools should follow this pattern:

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

from pydantic import BaseModel, Field

class Valves(BaseModel):
    # Optional: Define configuration parameters
    api_key: str = Field(default="", description="API Key")

class UserValves(BaseModel):
    # Optional: Define user-specific parameters
    enabled: bool = Field(default=True, description="Enable tool")

class Tools:
    def __init__(self):
        self.valves = Valves()
    
    def my_function(self, param: str) -> str:
        """
        Description of what this function does.
        
        :param param: Parameter description
        :return: Return value description
        """
        return f"Result: {param}"
```

The system automatically:

* Extracts tool specifications from the `Tools` class methods
* Parses frontmatter as manifest
* Validates valve schemas
* Generates API documentation from docstrings

## Error Responses

**400 Bad Request**

* Invalid tool ID format
* Tool ID already exists
* Invalid Python code
* Failed to load tool module

**401 Unauthorized**

* Missing authentication
* Insufficient permissions

**404 Not Found**

* Tool does not exist

## Authentication & Permissions

* Most operations require verified user authentication
* Creating tools requires `workspace.tools` or `workspace.tools_import` permission
* Exporting tools requires `workspace.tools_export` permission
* Write operations require tool ownership, write grant, or admin privileges
* Loading from URL requires admin privileges
