Skip to main content
Glama
mrseanchow

Cowsay MCP Server

by mrseanchow

cowsay

Generate ASCII art with a cow or character displaying your custom message. Choose from various animals like dragons, penguins, and skeletons to create fun text-based illustrations.

Instructions

Generate ASCII art of a cow saying something.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cowNoThe cow character to use.default
messageYesThe message for the cow to say.Hello World!

Implementation Reference

  • The handler function that executes the cowsay tool logic: validates access, lowercases inputs if configured, calls generateCowsay helper, and returns the ASCII art as text content.
    }, async ({ message, character }) => {
        // Validate server access
        if (!validateServerAccess(config.serverToken)) {
            throw new Error("Server access validation failed. Please provide a valid serverToken.");
        }
        // Apply user preferences from config
        const searchText = config.caseSensitive ? message : message.toLowerCase();
        const searchChar = config.caseSensitive ? character : character.toLowerCase();
        // Count occurrences of the specific character
        const result = await generateCowsay(searchText, searchChar);
        return {
            content: [
                {
                    type: "text",
                    text: result
                }
            ],
        };
    })
  • Core helper function implementing cowsay logic: prefers executing 'npx cowsay' via child_process, falls back to 'cowsay' library's say() method.
    export async function generateCowsay(message: string, cow: string): Promise<string> {
        try {
            const cowOption = cow !== 'default' ? `-f ${cow}` : '';
            const escapedMessage = message.replace(/'/g, "\\'");
            const { stdout } = await execAsync(`echo '${escapedMessage}' | npx cowsay@1.6.0 ${cowOption}`);
            return stdout;
        } catch (error) {
            try {
                const options = cow !== 'default' ? { f: cow } : {};
                return cowsay.say({ text: message, ...options });
            } catch (err) {
                throw new Error(`Failed to generate cowsay output: ${err instanceof Error ? err.message : String(err)}`);
            }
        }
    }
  • Detailed JSON schema definition for the cowsay tool inputs, including message, character selection, custom eyes/tongue, and various cow face modes.
    export const COWSAY: Tool = {
      name: 'cowsay',
      title: 'Cow Say',
      description: 'Generate ASCII art of a cow saying something.',
      inputSchema: {
        type: 'object',
        properties: {
          message: {
            type: 'string',
            description: 'The message for the cow to say.',
            default: 'Hello World!'
          },
          character: {
            type: 'string',
            description: 'The cow character to use.',
            enum: ['default', 'small', 'tux', 'moose', 'sheep', 'dragon', 'elephant', 'skeleton', 'stimpy'],
            default: 'default'
          },
          e: {
            type: 'string',
            description: 'Custom eyes for the cow.',
            default: 'oo'
          },
          T: {
            type: 'string',
            description: 'Custom tongue for the cow.'
          },
          r: {
            type: 'boolean',
            description: 'Use a random cow character.',
            default: false
          },
          b: {
            type: 'boolean',
            description: 'Borg mode - use borg face.',
            default: false
          },
          d: {
            type: 'boolean',
            description: 'Dead mode - use dead face.',
            default: false
          },
          g: {
            type: 'boolean',
            description: 'Greedy mode - use greedy face.',
            default: false
          },
          p: {
            type: 'boolean',
            description: 'Paranoia mode - use paranoia face.',
            default: false
          },
          s: {
            type: 'boolean',
            description: 'Stoned mode - use stoned face.',
            default: false
          },
          t: {
            type: 'boolean',
            description: 'Tired mode - use tired face.',
            default: false
          },
          w: {
            type: 'boolean',
            description: 'Wired mode - use wired face.',
            default: false
          },
          y: {
            type: 'boolean',
            description: 'Youthful mode - use youthful face.',
            default: false
          }
        },
        required: ['message']
      },
    };
  • src/index.ts:52-58 (registration)
    Registers the 'cowsay' tool with the MCP server, referencing title/description from tools.ts and providing a Zod-based input schema (simplified to message and character).
    mcp_server.registerTool("cowsay", {
        title: COWSAY.title,
        description: COWSAY.description,
        inputSchema: {
            message: z.string().describe('The message for the cow to say.'),
            character: z.string().optional().default('default').describe('The cow character to use.')
        },
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 generates ASCII art but lacks details on output format, potential errors, or any constraints like rate limits or permissions. This is a significant gap for a tool with no annotation coverage.

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 a single, efficient sentence that front-loads the core purpose ('Generate ASCII art') without any wasted words. It is appropriately sized for the tool's complexity, making it easy to understand quickly.

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

Completeness3/5

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

Given the tool's low complexity, 100% schema coverage, and no output schema, the description is minimally adequate. However, it lacks behavioral details (e.g., output format, error handling) that would be helpful for an agent, especially with no annotations. It meets basic needs but has clear gaps in completeness.

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%, so the schema already documents both parameters ('cow' and 'message') with descriptions and enums. The description adds no additional parameter semantics beyond what the schema provides, making the baseline score of 3 appropriate as the schema handles the heavy lifting.

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

Purpose5/5

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

The description clearly states the specific action ('Generate ASCII art') and resource ('a cow saying something'), distinguishing it from sibling tools like 'cowthink' (which likely generates thought bubbles) and 'list_cows' (which lists available cow characters). It precisely communicates the tool's function without redundancy.

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

Usage Guidelines3/5

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

The description implies usage for creating ASCII art with customizable messages and cow characters, but it does not explicitly state when to use this tool versus alternatives like 'cowthink' or 'list_cows'. No exclusions or prerequisites are mentioned, leaving usage context somewhat open-ended.

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/mrseanchow/cowsay-mcp'

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