Analyze Discord Image Attachment
Immutable Catalog Entry
This descriptor comes from the active versioned Portal catalog.
- Contract tier:
agent_ready - Risk:
read - Catalog version:
discord-2026.07.12.3 - Descriptor hash:
9aa4770aa68e2271aa9683831e317f1bdb7de4a8c68da67e530a82d283da5e51
Use this when you need OCR or visual analysis of an attached image. Do not use it for non-images or when vision is not configured. This reads the attachment and sends it to the configured OpenAI vision endpoint through Discord's API and returns attachment metadata and extracted or described text. It requires a configured Discord bot and guild with the relevant permissions.
Request Body
{
"jsonrpc": "2.0",
"id": "discord-analyze-attachment-example",
"method": "tools/call",
"params": {
"name": "discord.analyze_attachment",
"arguments": {
"mode": "ocr",
"prompt": "prompt_example",
"channel_id": "channel_id_123",
"message_id": "message_id_123",
"attachment_index": "attachment_index_example"
}
}
}
Arguments Schema
{
"type": "object",
"title": "analyze_attachment input",
"properties": {
"mode": {
"enum": [
"ocr",
"describe"
],
"type": "string",
"title": "Mode",
"default": "ocr",
"description": "Attachment analysis mode: ocr extracts text; describe summarizes visual content."
},
"prompt": {
"type": "string",
"title": "Prompt",
"default": "",
"description": "Optional task-specific instruction appended to the safe vision prompt."
},
"channel_id": {
"type": "string",
"title": "Channel Id",
"default": "",
"description": "Discord channel snowflake; empty uses the primary channel only where documented."
},
"message_id": {
"type": "string",
"title": "Message Id",
"default": "",
"description": "Discord message snowflake identifying the target message."
},
"attachment_index": {
"type": "string",
"title": "Attachment Index",
"default": "0",
"description": "Zero-based decimal index of the image attachment on the message."
}
},
"description": "Validated input for the Discord MCP analyze_attachment tool."
}
Output Schema
{
"oneOf": [
{
"type": "object",
"required": [
"ok",
"data",
"meta"
],
"properties": {
"ok": {
"const": true
},
"data": {
"type": "object",
"properties": {
"mode": {
"type": [
"string",
"null"
],
"description": "Provider data field mode returned by analyze_attachment."
},
"text": {
"type": [
"string",
"null"
],
"description": "Provider data field text returned by analyze_attachment."
},
"model": {
"type": [
"string",
"null"
],
"description": "Provider data field model returned by analyze_attachment."
},
"usage": {
"type": [
"object",
"null"
],
"description": "Provider data field usage returned by analyze_attachment.",
"additionalProperties": true
},
"attachment": {
"type": [
"object",
"null"
],
"description": "Provider data field attachment returned by analyze_attachment.",
"additionalProperties": true
},
"channel_id": {
"type": [
"string",
"null"
],
"description": "Provider data field channel_id returned by analyze_attachment."
},
"message_id": {
"type": [
"string",
"null"
],
"description": "Provider data field message_id returned by analyze_attachment."
}
},
"description": "attachment metadata and extracted or described text",
"additionalProperties": true
},
"meta": {
"type": "object",
"required": [
"duration_ms",
"rate_limit",
"warnings"
],
"properties": {
"guild_id": {
"type": "string"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
},
"thread_id": {
"type": "string"
},
"channel_id": {
"type": "string"
},
"rate_limit": {
"type": "object",
"additionalProperties": true
},
"request_id": {
"type": "string"
},
"duration_ms": {
"type": "integer",
"minimum": 0
}
},
"description": "Safe execution metadata containing no credentials or raw headers.",
"additionalProperties": true
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"ok",
"error",
"meta"
],
"properties": {
"ok": {
"const": false
},
"meta": {
"type": "object",
"required": [
"duration_ms",
"rate_limit",
"warnings"
],
"properties": {
"guild_id": {
"type": "string"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
},
"thread_id": {
"type": "string"
},
"channel_id": {
"type": "string"
},
"rate_limit": {
"type": "object",
"additionalProperties": true
},
"request_id": {
"type": "string"
},
"duration_ms": {
"type": "integer",
"minimum": 0
}
},
"description": "Safe execution metadata containing no credentials or raw headers.",
"additionalProperties": true
},
"error": {
"type": "object",
"required": [
"type",
"message"
],
"properties": {
"type": {
"type": "string"
},
"message": {
"type": "string"
},
"diagnostics": {
"type": "object",
"additionalProperties": true
},
"required_perms": {
"type": "array",
"items": {
"type": "string"
}
},
"discord_error_code": {
"type": "integer"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
],
"title": "Discord MCP provider result",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Normalized success or semantic-error response; ok=false is a failed call."
}
Code Examples
- cURL
- Node.js
- Python
curl -X POST 'https://portal.madpanda3d.com/api/mcp' \
-H 'Authorization: Bearer mad_live_***' \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": "discord-analyze-attachment-example",
"method": "tools/call",
"params": {
"name": "discord.analyze_attachment",
"arguments": {
"mode": "ocr",
"prompt": "prompt_example",
"channel_id": "channel_id_123",
"message_id": "message_id_123",
"attachment_index": "attachment_index_example"
}
}
}'
const response = await fetch('https://portal.madpanda3d.com/api/mcp', {
method: 'POST',
headers: {
Authorization: 'Bearer mad_live_***',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"jsonrpc": "2.0",
"id": "discord-analyze-attachment-example",
"method": "tools/call",
"params": {
"name": "discord.analyze_attachment",
"arguments": {
"mode": "ocr",
"prompt": "prompt_example",
"channel_id": "channel_id_123",
"message_id": "message_id_123",
"attachment_index": "attachment_index_example"
}
}
}),
});
const data = await response.json();
console.log(data);
import requests
url = 'https://portal.madpanda3d.com/api/mcp'
headers = {
'Authorization': 'Bearer mad_live_***',
'Content-Type': 'application/json',
}
payload = {
"jsonrpc": "2.0",
"id": "discord-analyze-attachment-example",
"method": "tools/call",
"params": {
"name": "discord.analyze_attachment",
"arguments": {
"mode": "ocr",
"prompt": "prompt_example",
"channel_id": "channel_id_123",
"message_id": "message_id_123",
"attachment_index": "attachment_index_example"
}
}
}
response = requests.post(url, headers=headers, json=payload, timeout=60)
print(response.json())
Example Responses
- 200 Success
- 502 Upstream Error
{
"ok": true,
"message": "Tool discord.analyze_attachment executed successfully.",
"note": "Response shape varies by MCP tool. Inspect live responses for exact fields."
}
{
"ok": false,
"classification": "upstream_http_error",
"message": "Upstream MCP returned a non-success status."
}