Skip to main content
Glama
pangeacyber
by pangeacyber
index.ts3.39 kB
import { Anthropic } from '@anthropic-ai/sdk'; import type { MessageParam } from '@anthropic-ai/sdk/resources.mjs'; import dotenv from '@dotenvx/dotenvx'; import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import { defineCommand, runMain } from 'citty'; import { consola } from 'consola'; dotenv.config({ overload: true }); const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; if (!ANTHROPIC_API_KEY) { throw new Error('ANTHROPIC_API_KEY is not set'); } const main = defineCommand({ args: { input: { type: 'string', description: 'Input to the agent.', }, }, async run({ args }) { // Start and connect to the MCP server. const transport = new StdioClientTransport({ command: 'node', args: ['../../dist/index.js'], env: { PANGEA_VAULT_TOKEN: process.env.PANGEA_VAULT_TOKEN!, PANGEA_VAULT_ITEM_ID: process.env.PANGEA_VAULT_ITEM_ID!, PANGEA_AUDIT_CONFIG_ID: process.env.PANGEA_AUDIT_CONFIG_ID!, }, }); const client = new Client({ name: 'pangea-client', version: '1.0.0' }); try { // Connect to the transport. await client.connect(transport); // Get tools. const toolsResult = await client.listTools(); const tools = toolsResult.tools.map((tool) => ({ name: tool.name, description: tool.description, input_schema: tool.inputSchema, })); consola.log( 'Connected to MCP server with tools:', tools.map(({ name }) => name) ); const messages: MessageParam[] = [ { role: 'user', content: args.input, }, ]; // Initial Claude API call. const anthropic = new Anthropic({ apiKey: ANTHROPIC_API_KEY }); const response = await anthropic.messages.create({ model: 'claude-3-5-sonnet-20241022', max_tokens: 1000, messages, tools, }); // Process response and handle tool calls. const finalText: string[] = []; for (const content of response.content) { if (content.type === 'text') { finalText.push(content.text); } else if (content.type === 'tool_use') { // Execute tool call. const toolName = content.name; const toolArgs = content.input as | { [x: string]: unknown } | undefined; const result = await client.callTool({ name: toolName, arguments: toolArgs, }); finalText.push( `[Calling tool ${toolName} with args ${JSON.stringify(toolArgs)}]` ); // Continue conversation with tool results. messages.push({ role: 'user', content: result.content as string, }); // Get next response from Claude. const response = await anthropic.messages.create({ model: 'claude-3-5-sonnet-20241022', max_tokens: 1000, messages, }); finalText.push( response.content[0].type === 'text' ? response.content[0].text : '' ); } consola.log(finalText.join('\n')); } } catch (e) { consola.error(e); } finally { await client.close(); } }, }); runMain(main);

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/pangeacyber/pangea-mcp-server'

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