Skip to main content
Glama

Cowsay MCP Server

by mrseanchow
index.ts6.35 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { COWSAY, COWTHINK, LIST_COWS } from './tools.js'; import { exec } from 'child_process'; import { promisify } from 'util'; import cowsay from 'cowsay'; const execAsync = promisify(exec); export const server = new Server({ name: 'cowsay-mcp', version: '1.0.0', }, { capabilities: { tools: {}, logging: {}, }, }); server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [COWSAY, COWTHINK, LIST_COWS], }; }); server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { switch (name) { case 'cowsay': { if (!checkCowsayArgs(args)) { throw new Error(`Invalid arguments for tool: [${name}]`); } const { message, cow = 'default' } = args; const result = await generateCowsay(message, cow); return { success: true, content: [ { type: 'text', text: result, }, ], }; } case 'cowthink': { if (!checkCowthinkArgs(args)) { throw new Error(`Invalid arguments for tool: [${name}]`); } const { message, cow = 'default' } = args; const result = await generateCowthink(message, cow); return { success: true, content: [ { type: 'text', text: result, }, ], }; } case 'list_cows': { const result = await listCows(); return { success: true, content: [ { type: 'text', text: `Available cow characters: ${result.join(', ')}`, }, ], }; } default: { throw new Error(`Unknown tool: ${name}`); } } } catch (error: unknown) { const message = error instanceof Error ? error.message : String(error); return { success: false, content: [ { type: 'text', text: message, }, ], }; } }); // 修改 generateCowsay 函数 async function generateCowsay(message: string, cow: string): Promise<string> { try { const cowOption = cow !== 'default' ? `-f ${cow}` : ''; // 使用转义引号来处理message中的特殊字符 const escapedMessage = message.replace(/'/g, "\\'"); const { stdout } = await execAsync(`echo '${escapedMessage}' | npx cowsay ${cowOption}`); return stdout; } catch (error) { // 直接使用已导入的cowsay模块 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)}`); } } } // 修改 generateCowthink 函数 async function generateCowthink(message: string, cow: string): Promise<string> { try { const cowOption = cow !== 'default' ? `-f ${cow}` : ''; // 使用转义引号来处理message中的特殊字符 const escapedMessage = message.replace(/'/g, "\\'"); const { stdout } = await execAsync(`echo '${escapedMessage}' | npx cowsay -T '\\' ${cowOption}`); return stdout; } catch (error) { // 直接使用已导入的cowsay模块 try { const options = cow !== 'default' ? { f: cow } : {}; return cowsay.think({ text: message, ...options }); } catch (err) { throw new Error(`Failed to generate cowthink output: ${err instanceof Error ? err.message : String(err)}`); } } } async function listCows(): Promise<string[]> { try { // 直接使用cowsay包的list函数获取奶牛角色列表 const cowsList = await cowsay.list(() => {}); // 移除每个奶牛角色名称中的.cow扩展名 const cowsWithoutExtension = cowsList.map(cow => { // 检查字符串是否以.cow结尾,如果是则移除扩展名 if (cow.endsWith('.cow')) { return cow.substring(0, cow.lastIndexOf('.cow')); } return cow; }); return cowsWithoutExtension; } catch (error) { // 返回默认列表 return ['default', 'small', 'tux', 'moose', 'sheep', 'dragon', 'elephant', 'skeleton', 'stimpy']; } } function checkCowsayArgs(args: unknown): args is { message: string, cow?: string } { return ( typeof args === 'object' && args !== null && 'message' in args && typeof args.message === 'string' && ('cow' in args ? typeof args.cow === 'string' : true) ); } function checkCowthinkArgs(args: unknown): args is { message: string, cow?: string } { return checkCowsayArgs(args); } async function runServer() { try { process.stdout.write('Starting Cowsay MCP server...\n'); const transport = new StdioServerTransport(); await server.connect(transport); } catch (error: unknown) { const message = error instanceof Error ? error.message : String(error); process.stderr.write(`Error starting Cowsay MCP server: ${message}\n`); process.exit(1); } } runServer().catch(error => { const errorMessage = error instanceof Error ? error.message : String(error); process.stderr.write(`Error running Cowsay MCP server: ${errorMessage}\n`); process.exit(1); });

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