Skip to main content
Glama
hanweg

Discord Raw API MCP Server

by hanweg

discord_api

Execute raw Discord API commands using REST methods or slash command syntax to manage bots, configure servers, and handle message operations directly.

Instructions

Execute raw Discord API commands. Supports both REST API calls and application commands.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
methodYesHTTP method (GET, POST, PUT, PATCH, DELETE)
endpointYesDiscord API endpoint (e.g., 'guilds/{guild.id}/roles' or command like '/role create')
payloadNoOptional request payload/body

Implementation Reference

  • Core handler function that performs the raw HTTP request to Discord API using aiohttp, handles responses and errors.
    async def execute_discord_api(method: str, endpoint: str, payload: dict = None) -> dict:
        """Execute a raw Discord API request."""
        if not discord_client:
            raise RuntimeError("Discord client not ready")
        
        async with aiohttp.ClientSession() as session:
            headers = {
                "Authorization": f"Bot {DISCORD_TOKEN}",
                "Content-Type": "application/json",
            }
            
            url = f"{DISCORD_API_BASE}/{endpoint.lstrip('/')}"
            
            async with session.request(
                method=method.upper(),
                url=url,
                headers=headers,
                json=payload if payload else None
            ) as response:
                if response.status == 204:  # No content
                    return {"success": True}
                    
                response_data = await response.json()
                
                if not response.ok:
                    error_msg = f"Discord API error: {response.status} - {response_data.get('message', 'Unknown error')}"
                    logger.error(error_msg)
                    return {
                        "success": False,
                        "error": error_msg,
                        "status": response.status,
                        "details": response_data
                    }
                    
                return response_data
  • Input schema defining the parameters for the discord_api tool: method (enum), endpoint (string), optional payload (object).
    inputSchema={
        "type": "object",
        "properties": {
            "method": {
                "type": "string",
                "description": "HTTP method (GET, POST, PUT, PATCH, DELETE)",
                "enum": ["GET", "POST", "PUT", "PATCH", "DELETE"]
            },
            "endpoint": {
                "type": "string",
                "description": "Discord API endpoint (e.g., 'guilds/{guild.id}/roles' or command like '/role create')"
            },
            "payload": {
                "type": "object",
                "description": "Optional request payload/body"
            }
        },
        "required": ["method", "endpoint"]
    }
  • Registration of the 'discord_api' tool via @app.list_tools(), including name, description, and input schema.
        Tool(
            name="discord_api",
            description="Execute raw Discord API commands. Supports both REST API calls and application commands.",
            inputSchema={
                "type": "object",
                "properties": {
                    "method": {
                        "type": "string",
                        "description": "HTTP method (GET, POST, PUT, PATCH, DELETE)",
                        "enum": ["GET", "POST", "PUT", "PATCH", "DELETE"]
                    },
                    "endpoint": {
                        "type": "string",
                        "description": "Discord API endpoint (e.g., 'guilds/{guild.id}/roles' or command like '/role create')"
                    },
                    "payload": {
                        "type": "object",
                        "description": "Optional request payload/body"
                    }
                },
                "required": ["method", "endpoint"]
            }
        )
    ]
  • Constants for Discord API version and base URL used in the tool implementation.
    DISCORD_API_VERSION = "10"
    DISCORD_API_BASE = f"https://discord.com/api/v{DISCORD_API_VERSION}"
    
    @bot.event
    async def on_ready():
        global discord_client
        discord_client = bot
        logger.info(f"Logged in as {bot.user.name}")
    
    async def execute_discord_api(method: str, endpoint: str, payload: dict = None) -> dict:
        """Execute a raw Discord API request."""
        if not discord_client:
            raise RuntimeError("Discord client not ready")
        
        async with aiohttp.ClientSession() as session:
            headers = {
                "Authorization": f"Bot {DISCORD_TOKEN}",
                "Content-Type": "application/json",
            }
            
            url = f"{DISCORD_API_BASE}/{endpoint.lstrip('/')}"
            
            async with session.request(
                method=method.upper(),
                url=url,
                headers=headers,
                json=payload if payload else None
            ) as response:
                if response.status == 204:  # No content
                    return {"success": True}
                    
                response_data = await response.json()
                
                if not response.ok:
                    error_msg = f"Discord API error: {response.status} - {response_data.get('message', 'Unknown error')}"
                    logger.error(error_msg)
                    return {
                        "success": False,
                        "error": error_msg,
                        "status": response.status,
                        "details": response_data
                    }
                    
                return response_data
  • Helper logic in call_tool for handling slash command syntax like '/role create', parsing args and converting to API calls.
    # Handle slash command syntax
    if endpoint.startswith('/'):
        # Convert slash command to API call
        command_parts = endpoint[1:].split()  # Remove leading / and split
        
        if len(command_parts) < 2:
            return [TextContent(
                type="text",
                text=f"Invalid slash command format. Must include command and subcommand."
            )]
            
        command, subcommand, *args = command_parts
        
        # Example: Convert /role create to appropriate API call
        if command == "role":
            if subcommand == "create":
                # Parse arguments from the command string
                arg_dict = {}
                for arg in args:
                    if ":" in arg:
                        key, value = arg.split(":", 1)
                        arg_dict[key] = value
                
                # Modify method and endpoint for role creation
                method = "POST"
                guild_id = arg_dict.get("guild_id", payload.get("guild_id") if payload else None)
                if not guild_id:
                    return [TextContent(
                        type="text",
                        text="guild_id is required for role creation"
                    )]
                
                endpoint = f"guilds/{guild_id}/roles"
                payload = {
                    "name": arg_dict.get("name", "New Role"),
                    "permissions": arg_dict.get("permissions", "0"),
                    "color": int(arg_dict.get("color", "0"), 16) if "color" in arg_dict else 0,
                    "hoist": arg_dict.get("hoist", "false").lower() == "true",
                    "mentionable": arg_dict.get("mentionable", "false").lower() == "true"
                }
    
    try:
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the tool 'Executes raw Discord API commands' which implies it performs operations, but it doesn't disclose critical traits like authentication requirements, rate limits, error handling, or whether it's read-only or destructive. The mention of 'Supports both REST API calls and application commands' adds some context but is insufficient for a mutation-capable tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise with two sentences that directly state the tool's function and scope. Every word earns its place, with no redundant or vague language. It is front-loaded and efficiently communicates the essential information without waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a raw API execution tool with no annotations and no output schema, the description is incomplete. It lacks details on authentication, rate limits, error responses, and the nature of operations (e.g., whether it can perform destructive actions). For a tool that handles both REST and application commands with potential mutations, more context is needed to guide safe and effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, with clear descriptions for all parameters (method, endpoint, payload). The description adds no additional meaning beyond what the schema provides—it doesn't explain parameter interactions, format specifics, or examples. Baseline 3 is appropriate since the schema does the heavy lifting, but the description doesn't compensate with extra insights.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Execute raw Discord API commands' with the verb 'Execute' and resource 'Discord API commands'. It distinguishes between REST API calls and application commands, providing specific scope. However, without sibling tools, differentiation from alternatives is not applicable, preventing a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives or any prerequisites. It mentions support for 'both REST API calls and application commands', but this is part of the purpose statement rather than usage instructions. There are no explicit when/when-not scenarios or context for selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hanweg/mcp-discord-raw'

If you have feedback or need assistance with the MCP directory API, please join our Discord server