# Themes

## List Themes

`TOOL discourse_list_themes`

List admin-visible Discourse themes and components. This opt-in admin read returns bounded summaries and local pagination; it does not expose theme source code.

Authentication: no security requirement declared for this operation.

Parameters:

- `kind` (argument, string, optional)
  Type: string
  
  default: "all"
  
  enum: ["theme","component","all"]

- `query` (argument, string, optional)
  Type: string
  
  maxLength: 200

- `include_system` (argument, boolean, optional)
  Type: boolean
  
  default: true

- `limit` (argument, integer, optional)
  Type: integer
  
  default: 100
  
  minimum: 1
  
  maximum: 500

- `offset` (argument, integer, optional)
  Type: integer
  
  default: 0
  
  minimum: 0

Declared MCP annotations:

```json
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
```

## Examples

### JSON-RPC

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "discourse_list_themes",
    "arguments": {
        "kind": "all",
        "query": "string",
        "include_system": true,
        "limit": 100,
        "offset": 0
      }
  }
}
```

### TypeScript

```typescript
const result = await client.callTool({
  "name": "discourse_list_themes",
  "arguments": {
    "kind": "all",
    "query": "string",
    "include_system": true,
    "limit": 100,
    "offset": 0
  }
});
```

### Python

```python
result = await session.call_tool("discourse_list_themes", arguments={
  "kind": "all",
  "query": "string",
  "include_system": true,
  "limit": 100,
  "offset": 0
})
```


## Get Theme

`TOOL discourse_get_theme`

Inspect one local, ZIP-imported, or Git-backed Discourse theme/component as an administrator. Source values are bounded, opt-in, and may be unavailable for remote records; private key material is never returned.

Authentication: no security requirement declared for this operation.

Parameters:

- `theme_id` (argument, integer, required)
  Type: integer

- `include_field_values` (argument, boolean, optional)
  Type: boolean
  
  default: false

Declared MCP annotations:

```json
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
```

## Examples

### JSON-RPC

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "discourse_get_theme",
    "arguments": {
        "theme_id": 0,
        "include_field_values": false
      }
  }
}
```

### TypeScript

```typescript
const result = await client.callTool({
  "name": "discourse_get_theme",
  "arguments": {
    "theme_id": 0,
    "include_field_values": false
  }
});
```

### Python

```python
result = await session.call_tool("discourse_get_theme", arguments={
  "theme_id": 0,
  "include_field_values": false
})
```


## Create Theme

`TOOL discourse_create_theme`

Create a local Discourse theme or component. For textual HTML/SCSS/JS fields provide value and omit upload_id; for assets provide numeric upload_id with type=upload and omit value. Supplied code can execute or deploy for visitors; explicit confirmations and admin write access are required.

Authentication: no security requirement declared for this operation.

Parameters:

- `name` (argument, string, required)
  Type: string
  
  minLength: 1
  
  maxLength: 200

- `component` (argument, boolean, optional)
  Type: boolean
  
  default: false

- `user_selectable` (argument, boolean, optional)
  Type: boolean

- `color_scheme_id` (argument, integer, optional)
  Type: integer
  
  exclusiveMinimum: 0

- `fields` (argument, Array<object>, optional) - Optional populated fields. Each item is either a text replacement with value, or an upload replacement with numeric upload_id and type=upload.
  Type: Array<object>
  
  Optional populated fields. Each item is either a text replacement with value, or an upload replacement with numeric upload_id and type=upload.
  
  maxItems: 100
  
  Items:
    Type: object
    
    anyOf:
      Type: object
      
      Text field replacement: value is required and upload_id is not accepted
      
      - `name` (required)
        Type: string
        
        Theme field name
        
        minLength: 1
        
        maxLength: 200
      
      - `target` (required)
        Type: string
        
        Discourse theme-field target
        
        enum: ["common","desktop","mobile","settings","translations","extra_scss","extra_js","tests_js","migrations","about"]
      
      - `operation` (optional)
        Type: string
        
        default: "replace"
        
        const: "replace"
      
      - `value` (required)
        Type: string
        
        Complete textual field content. Do not provide upload_id.
        
        minLength: 1
        
        maxLength: 1048576
      
      - `type` (optional)
        Type: string
        
        Friendly textual field type; omit when Discourse can infer it
        
        enum: ["html","scss","yaml","javascript","json"]
      
      Additional properties: false
    
      Type: object
      
      Upload field replacement: numeric upload_id and type=upload are required; value is not accepted
      
      - `name` (required)
        Type: string
        
        Theme field name
        
        minLength: 1
        
        maxLength: 200
      
      - `target` (required)
        Type: string
        
        Discourse theme-field target
        
        enum: ["common","desktop","mobile","settings","translations","extra_scss","extra_js","tests_js","migrations","about"]
      
      - `operation` (optional)
        Type: string
        
        default: "replace"
        
        const: "replace"
      
      - `upload_id` (required)
        Type: integer
        
        Numeric upload ID returned by discourse_upload_theme_asset
        
        exclusiveMinimum: 0
      
      - `type` (required)
        Type: string
        
        Required for an upload-backed field
        
        const: "upload"
      
      Additional properties: false

- `set_default` (argument, boolean, optional)
  Type: boolean

- `confirm_code_execution` (argument, boolean, optional)
  Type: boolean

- `confirm_set_default` (argument, boolean, optional)
  Type: boolean

Declared MCP annotations:

```json
{
  "readOnlyHint": false,
  "destructiveHint": false,
  "idempotentHint": false,
  "openWorldHint": true
}
```

## Examples

### JSON-RPC

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "discourse_create_theme",
    "arguments": {
        "name": "string",
        "component": false,
        "user_selectable": true,
        "color_scheme_id": 0,
        "fields": [
          {
            "name": "string",
            "target": "common",
            "operation": "replace",
            "value": "string",
            "type": "html"
          }
        ],
        "set_default": true,
        "confirm_code_execution": true,
        "confirm_set_default": true
      }
  }
}
```

### TypeScript

```typescript
const result = await client.callTool({
  "name": "discourse_create_theme",
  "arguments": {
    "name": "string",
    "component": false,
    "user_selectable": true,
    "color_scheme_id": 0,
    "fields": [
      {
        "name": "string",
        "target": "common",
        "operation": "replace",
        "value": "string",
        "type": "html"
      }
    ],
    "set_default": true,
    "confirm_code_execution": true,
    "confirm_set_default": true
  }
});
```

### Python

```python
result = await session.call_tool("discourse_create_theme", arguments={
  "name": "string",
  "component": false,
  "user_selectable": true,
  "color_scheme_id": 0,
  "fields": [
    {
      "name": "string",
      "target": "common",
      "operation": "replace",
      "value": "string",
      "type": "html"
    }
  ],
  "set_default": true,
  "confirm_code_execution": true,
  "confirm_set_default": true
})
```


## Install Theme

`TOOL discourse_install_theme`

Install a Git repository or ZIP/gzip archive. Set source to exactly one nested variant: {kind:repository, remote_url...}, {kind:archive, archive_data...}, or {kind:archive, archive_path...}; never add placeholder fields from another variant. External code and migrations can have site-wide impact and are not sandboxed.

Authentication: no security requirement declared for this operation.

Request body: application/json (required)

Type: object

- `source` (required)
  Type: object
  
  Choose exactly one repository, base64 archive, or local archive source variant. Never add placeholder fields from another variant.
  
  anyOf:
    Type: object
    
    Repository installation source
    
    - `kind` (required)
      Type: string
      
      const: "repository"
    
    - `remote_url` (required)
      Type: string
      
      Git repository URL; archive inputs are not part of this variant
      
      minLength: 1
      
      maxLength: 10000
    
    - `branch` (optional)
      Type: string
      
      maxLength: 500
    
    - `force_placeholder` (optional)
      Type: boolean
      
      default: false
    
    Additional properties: false
  
    Type: object
    
    Base64 archive installation source
    
    - `kind` (required)
      Type: string
      
      const: "archive"
    
    - `archive_data` (required)
      Type: object
      
      Bounded base64 archive and filename
      
      - `base64` (required)
        Type: string
        
        minLength: 1
        
        maxLength: 34952538
      
      - `filename` (required)
        Type: string
        
        minLength: 1
        
        maxLength: 255
      
      Additional properties: false
    
    - `replace_theme_id` (optional)
      Type: integer
      
      exclusiveMinimum: 0
    
    - `component_update_mode` (optional)
      Type: string
      
      default: "add_missing"
      
      enum: ["none","add_missing","sync"]
    
    - `run_migrations` (optional)
      Type: boolean
      
      default: true
    
    Additional properties: false
  
    Type: object
    
    Allowlisted local archive installation source
    
    - `kind` (required)
      Type: string
      
      const: "archive"
    
    - `archive_path` (required)
      Type: string
      
      Absolute local path or file:// URL beneath allowed_upload_paths
      
      minLength: 1
      
      maxLength: 4096
    
    - `replace_theme_id` (optional)
      Type: integer
      
      exclusiveMinimum: 0
    
    - `component_update_mode` (optional)
      Type: string
      
      default: "add_missing"
      
      enum: ["none","add_missing","sync"]
    
    - `run_migrations` (optional)
      Type: boolean
      
      default: true
    
    Additional properties: false

- `confirm_external_code` (required)
  Type: boolean
  
  const: true

- `confirm_force_placeholder` (optional)
  Type: boolean

- `confirm_replace` (optional)
  Type: boolean

- `confirm_run_migrations` (optional)
  Type: boolean

Additional properties: false

Declared MCP annotations:

```json
{
  "readOnlyHint": false,
  "destructiveHint": true,
  "idempotentHint": false,
  "openWorldHint": true
}
```

## Examples

### JSON-RPC

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "discourse_install_theme",
    "arguments": {
        "source": {
          "kind": "repository",
          "remote_url": "string",
          "branch": "string",
          "force_placeholder": false
        },
        "confirm_external_code": true,
        "confirm_force_placeholder": true,
        "confirm_replace": true,
        "confirm_run_migrations": true
      }
  }
}
```

### TypeScript

```typescript
const result = await client.callTool({
  "name": "discourse_install_theme",
  "arguments": {
    "source": {
      "kind": "repository",
      "remote_url": "string",
      "branch": "string",
      "force_placeholder": false
    },
    "confirm_external_code": true,
    "confirm_force_placeholder": true,
    "confirm_replace": true,
    "confirm_run_migrations": true
  }
});
```

### Python

```python
result = await session.call_tool("discourse_install_theme", arguments={
  "source": {
    "kind": "repository",
    "remote_url": "string",
    "branch": "string",
    "force_placeholder": false
  },
  "confirm_external_code": true,
  "confirm_force_placeholder": true,
  "confirm_replace": true,
  "confirm_run_migrations": true
})
```


## Update Theme Metadata

`TOOL discourse_update_theme`

Update bounded metadata, default status, or complete theme-component relationships. Relationship arrays replace the entire graph side; source, settings, translations, and remote refresh are intentionally excluded.

Authentication: no security requirement declared for this operation.

Request body: application/json (required)

Type: object

- `theme_id` (required)
  Type: integer

- `name` (optional)
  Type: string
  
  minLength: 1
  
  maxLength: 200

- `color_scheme_id` (optional)
  Type: integer | null
  
  anyOf:
    Type: integer
    
    exclusiveMinimum: 0
  
    Type: null

- `dark_color_scheme_id` (optional)
  Type: integer | null
  
  anyOf:
    Type: integer
    
    exclusiveMinimum: 0
  
    Type: null

- `user_selectable` (optional)
  Type: boolean

- `auto_update` (optional)
  Type: boolean

- `enabled` (optional)
  Type: boolean

- `parent_theme_ids` (optional)
  Type: Array<integer>
  
  maxItems: 100
  
  Items:
    Type: integer
    
    exclusiveMinimum: 0

- `child_theme_ids` (optional)
  Type: Array<integer>
  
  maxItems: 100
  
  Items:
    Type: integer
    
    exclusiveMinimum: 0

- `set_default` (optional)
  Type: boolean

- `expected_name` (optional)
  Type: string
  
  maxLength: 200

- `confirm_default_change` (optional)
  Type: boolean

- `confirm_component_graph_replace` (optional)
  Type: boolean

Additional properties: false

Declared MCP annotations:

```json
{
  "readOnlyHint": false,
  "destructiveHint": true,
  "idempotentHint": true,
  "openWorldHint": true
}
```

## Examples

### JSON-RPC

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "discourse_update_theme",
    "arguments": {
        "theme_id": 0,
        "name": "string",
        "color_scheme_id": 0,
        "dark_color_scheme_id": 0,
        "user_selectable": true,
        "auto_update": true,
        "enabled": true,
        "parent_theme_ids": [
          0
        ],
        "child_theme_ids": [
          0
        ],
        "set_default": true,
        "expected_name": "string",
        "confirm_default_change": true,
        "confirm_component_graph_replace": true
      }
  }
}
```

### TypeScript

```typescript
const result = await client.callTool({
  "name": "discourse_update_theme",
  "arguments": {
    "theme_id": 0,
    "name": "string",
    "color_scheme_id": 0,
    "dark_color_scheme_id": 0,
    "user_selectable": true,
    "auto_update": true,
    "enabled": true,
    "parent_theme_ids": [
      0
    ],
    "child_theme_ids": [
      0
    ],
    "set_default": true,
    "expected_name": "string",
    "confirm_default_change": true,
    "confirm_component_graph_replace": true
  }
});
```

### Python

```python
result = await session.call_tool("discourse_update_theme", arguments={
  "theme_id": 0,
  "name": "string",
  "color_scheme_id": 0,
  "dark_color_scheme_id": 0,
  "user_selectable": true,
  "auto_update": true,
  "enabled": true,
  "parent_theme_ids": [
    0
  ],
  "child_theme_ids": [
    0
  ],
  "set_default": true,
  "expected_name": "string",
  "confirm_default_change": true,
  "confirm_component_graph_replace": true
})
```


## Update Theme Fields

`TOOL discourse_update_theme_fields`

Replace or explicitly delete selected fields on a local or ZIP-imported theme. Text replacements require value and prohibit upload_id; asset replacements require numeric upload_id with type=upload and prohibit value. This can deploy executable code; Git-backed and system themes are rejected.

Authentication: no security requirement declared for this operation.

Parameters:

- `theme_id` (argument, integer, required)
  Type: integer

- `fields` (argument, Array<object>, required)
  Type: Array<object>
  
  minItems: 1
  
  maxItems: 100
  
  Items:
    Type: object
    
    anyOf:
      Type: object
      
      Text field replacement: value is required and upload_id is not accepted
      
      - `name` (required)
        Type: string
        
        Theme field name
        
        minLength: 1
        
        maxLength: 200
      
      - `target` (required)
        Type: string
        
        Discourse theme-field target
        
        enum: ["common","desktop","mobile","settings","translations","extra_scss","extra_js","tests_js","migrations","about"]
      
      - `operation` (optional)
        Type: string
        
        default: "replace"
        
        const: "replace"
      
      - `value` (required)
        Type: string
        
        Complete textual field content. Do not provide upload_id.
        
        minLength: 1
        
        maxLength: 1048576
      
      - `type` (optional)
        Type: string
        
        Friendly textual field type; omit when Discourse can infer it
        
        enum: ["html","scss","yaml","javascript","json"]
      
      Additional properties: false
    
      Type: object
      
      Upload field replacement: numeric upload_id and type=upload are required; value is not accepted
      
      - `name` (required)
        Type: string
        
        Theme field name
        
        minLength: 1
        
        maxLength: 200
      
      - `target` (required)
        Type: string
        
        Discourse theme-field target
        
        enum: ["common","desktop","mobile","settings","translations","extra_scss","extra_js","tests_js","migrations","about"]
      
      - `operation` (optional)
        Type: string
        
        default: "replace"
        
        const: "replace"
      
      - `upload_id` (required)
        Type: integer
        
        Numeric upload ID returned by discourse_upload_theme_asset
        
        exclusiveMinimum: 0
      
      - `type` (required)
        Type: string
        
        Required for an upload-backed field
        
        const: "upload"
      
      Additional properties: false
    
      Type: object
      
      Explicit field deletion: value, upload_id, and type are not accepted
      
      - `name` (required)
        Type: string
        
        Theme field name
        
        minLength: 1
        
        maxLength: 200
      
      - `target` (required)
        Type: string
        
        Discourse theme-field target
        
        enum: ["common","desktop","mobile","settings","translations","extra_scss","extra_js","tests_js","migrations","about"]
      
      - `operation` (required)
        Type: string
        
        const: "delete"
      
      Additional properties: false

- `expected_theme_name` (argument, string, required)
  Type: string
  
  minLength: 1
  
  maxLength: 200

- `confirm_code_execution` (argument, boolean, required)
  Type: boolean
  
  const: true

- `confirm_field_replacement` (argument, boolean, required)
  Type: boolean
  
  const: true

Declared MCP annotations:

```json
{
  "readOnlyHint": false,
  "destructiveHint": true,
  "idempotentHint": true,
  "openWorldHint": true
}
```

## Examples

### JSON-RPC

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "discourse_update_theme_fields",
    "arguments": {
        "theme_id": 0,
        "fields": [
          {
            "name": "string",
            "target": "common",
            "operation": "replace",
            "value": "string",
            "type": "html"
          }
        ],
        "expected_theme_name": "string",
        "confirm_code_execution": true,
        "confirm_field_replacement": true
      }
  }
}
```

### TypeScript

```typescript
const result = await client.callTool({
  "name": "discourse_update_theme_fields",
  "arguments": {
    "theme_id": 0,
    "fields": [
      {
        "name": "string",
        "target": "common",
        "operation": "replace",
        "value": "string",
        "type": "html"
      }
    ],
    "expected_theme_name": "string",
    "confirm_code_execution": true,
    "confirm_field_replacement": true
  }
});
```

### Python

```python
result = await session.call_tool("discourse_update_theme_fields", arguments={
  "theme_id": 0,
  "fields": [
    {
      "name": "string",
      "target": "common",
      "operation": "replace",
      "value": "string",
      "type": "html"
    }
  ],
  "expected_theme_name": "string",
  "confirm_code_execution": true,
  "confirm_field_replacement": true
})
```


## Update Theme Setting

`TOOL discourse_update_theme_setting`

Set or explicitly revert one declared setting owned by a theme/component. This does not mutate themeable global site settings; object values are validated upstream against the declared schema.

Authentication: no security requirement declared for this operation.

Parameters:

- `theme_id` (argument, integer, required)
  Type: integer

- `name` (argument, string, required)
  Type: string
  
  minLength: 1
  
  maxLength: 200
  
  pattern: "^[A-Za-z0-9_-]+$"

- `value` (argument, any, optional)
  Type: any

- `operation` (argument, string, optional)
  Type: string
  
  default: "set"
  
  enum: ["set","revert"]

- `expected_current_value` (argument, any, optional)
  Type: any

- `confirm_revert` (argument, boolean, optional)
  Type: boolean

Declared MCP annotations:

```json
{
  "readOnlyHint": false,
  "destructiveHint": true,
  "idempotentHint": true,
  "openWorldHint": true
}
```

## Examples

### JSON-RPC

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "discourse_update_theme_setting",
    "arguments": {
        "theme_id": 0,
        "name": "string",
        "operation": "set",
        "confirm_revert": true
      }
  }
}
```

### TypeScript

```typescript
const result = await client.callTool({
  "name": "discourse_update_theme_setting",
  "arguments": {
    "theme_id": 0,
    "name": "string",
    "operation": "set",
    "confirm_revert": true
  }
});
```

### Python

```python
result = await session.call_tool("discourse_update_theme_setting", arguments={
  "theme_id": 0,
  "name": "string",
  "operation": "set",
  "confirm_revert": true
})
```


## Update Theme Translations

`TOOL discourse_update_theme_translations`

Replace values for explicit translation keys declared by a theme, after a fresh locale read. Unknown keys are rejected; deletion/revert is not supported in this release.

Authentication: no security requirement declared for this operation.

Parameters:

- `theme_id` (argument, integer, required)
  Type: integer

- `locale` (argument, string, required)
  Type: string
  
  minLength: 2
  
  maxLength: 35
  
  pattern: "^[A-Za-z0-9_-]+$"

- `translations` (argument, object, required)
  Type: object
  
  Additional properties: 
    Type: string
    
    maxLength: 100000

- `expected_theme_name` (argument, string, required)
  Type: string
  
  minLength: 1
  
  maxLength: 200

- `confirm_translation_replacement` (argument, boolean, required)
  Type: boolean
  
  const: true

Declared MCP annotations:

```json
{
  "readOnlyHint": false,
  "destructiveHint": true,
  "idempotentHint": true,
  "openWorldHint": true
}
```

## Examples

### JSON-RPC

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "discourse_update_theme_translations",
    "arguments": {
        "theme_id": 0,
        "locale": "string",
        "translations": {},
        "expected_theme_name": "string",
        "confirm_translation_replacement": true
      }
  }
}
```

### TypeScript

```typescript
const result = await client.callTool({
  "name": "discourse_update_theme_translations",
  "arguments": {
    "theme_id": 0,
    "locale": "string",
    "translations": {},
    "expected_theme_name": "string",
    "confirm_translation_replacement": true
  }
});
```

### Python

```python
result = await session.call_tool("discourse_update_theme_translations", arguments={
  "theme_id": 0,
  "locale": "string",
  "translations": {},
  "expected_theme_name": "string",
  "confirm_translation_replacement": true
})
```


## Sync Remote Theme

`TOOL discourse_sync_remote_theme`

Check or install updates for an existing Git-backed theme. Both actions clone external code and persist state; update deploys code and runs settings migrations, requiring explicit confirmations.

Authentication: no security requirement declared for this operation.

Parameters:

- `theme_id` (argument, integer, required)
  Type: integer
  
  exclusiveMinimum: 0

- `action` (argument, string, required)
  Type: string
  
  enum: ["check","update"]

- `expected_remote_url` (argument, string, optional)
  Type: string
  
  maxLength: 10000

- `confirm_external_code` (argument, boolean, optional)
  Type: boolean

- `confirm_run_migrations` (argument, boolean, optional)
  Type: boolean

Declared MCP annotations:

```json
{
  "readOnlyHint": false,
  "destructiveHint": true,
  "idempotentHint": false,
  "openWorldHint": true
}
```

## Examples

### JSON-RPC

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "discourse_sync_remote_theme",
    "arguments": {
        "theme_id": 0,
        "action": "check",
        "expected_remote_url": "string",
        "confirm_external_code": true,
        "confirm_run_migrations": true
      }
  }
}
```

### TypeScript

```typescript
const result = await client.callTool({
  "name": "discourse_sync_remote_theme",
  "arguments": {
    "theme_id": 0,
    "action": "check",
    "expected_remote_url": "string",
    "confirm_external_code": true,
    "confirm_run_migrations": true
  }
});
```

### Python

```python
result = await session.call_tool("discourse_sync_remote_theme", arguments={
  "theme_id": 0,
  "action": "check",
  "expected_remote_url": "string",
  "confirm_external_code": true,
  "confirm_run_migrations": true
})
```


## Upload Theme Asset

`TOOL discourse_upload_theme_asset`

Upload a bounded local/base64 asset for later attachment to a theme field. No remote URL fetch is supported; upload alone does not attach or deploy the asset.

Authentication: no security requirement declared for this operation.

Parameters:

- `file_data` (argument, string, optional)
  Type: string
  
  maxLength: 34952538

- `file_path` (argument, string, optional)
  Type: string
  
  maxLength: 4096

- `filename` (argument, string, optional)
  Type: string
  
  minLength: 1
  
  maxLength: 255

- `confirm_asset_upload` (argument, boolean, required)
  Type: boolean
  
  const: true

Declared MCP annotations:

```json
{
  "readOnlyHint": false,
  "destructiveHint": false,
  "idempotentHint": false,
  "openWorldHint": true
}
```

## Examples

### JSON-RPC

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "discourse_upload_theme_asset",
    "arguments": {
        "file_data": "string",
        "file_path": "string",
        "filename": "string",
        "confirm_asset_upload": true
      }
  }
}
```

### TypeScript

```typescript
const result = await client.callTool({
  "name": "discourse_upload_theme_asset",
  "arguments": {
    "file_data": "string",
    "file_path": "string",
    "filename": "string",
    "confirm_asset_upload": true
  }
});
```

### Python

```python
result = await session.call_tool("discourse_upload_theme_asset", arguments={
  "file_data": "string",
  "file_path": "string",
  "filename": "string",
  "confirm_asset_upload": true
})
```


## Delete Theme

`TOOL discourse_delete_theme`

Permanently delete one non-system, non-default theme/component after a fresh exact-name check. Dependencies are not detached automatically and bulk deletion is not exposed.

Authentication: no security requirement declared for this operation.

Parameters:

- `theme_id` (argument, integer, required)
  Type: integer
  
  exclusiveMinimum: 0

- `expected_theme_name` (argument, string, required)
  Type: string
  
  minLength: 1
  
  maxLength: 200

- `confirm_delete` (argument, boolean, required)
  Type: boolean
  
  const: true

Declared MCP annotations:

```json
{
  "readOnlyHint": false,
  "destructiveHint": true,
  "idempotentHint": false,
  "openWorldHint": true
}
```

## Examples

### JSON-RPC

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "discourse_delete_theme",
    "arguments": {
        "theme_id": 0,
        "expected_theme_name": "string",
        "confirm_delete": true
      }
  }
}
```

### TypeScript

```typescript
const result = await client.callTool({
  "name": "discourse_delete_theme",
  "arguments": {
    "theme_id": 0,
    "expected_theme_name": "string",
    "confirm_delete": true
  }
});
```

### Python

```python
result = await session.call_tool("discourse_delete_theme", arguments={
  "theme_id": 0,
  "expected_theme_name": "string",
  "confirm_delete": true
})
```
