Skip to main content
Glama

hypertool-mcp

claude-code.tsโ€ข6.77 kB
/** * Claude Code test fixture */ import { TestEnvironment } from '../base.js'; import { MCPServerConfig } from '../../../src/config-manager/types/index.js'; import { join } from 'path'; export class ClaudeCodeFixture { /** * Create Claude Code MCP configuration */ static createConfig(servers: Record<string, MCPServerConfig> = {}): string { return JSON.stringify({ mcpServers: servers }, null, 2); } /** * Create default test servers for a project */ static getDefaultServers(): Record<string, MCPServerConfig> { return { 'project-context': { type: 'stdio', command: 'project-context-mcp', args: ['--root', '.'] }, 'test-runner': { type: 'stdio', command: 'test-runner-mcp', env: { 'TEST_FRAMEWORK': 'jest' } } }; } /** * Install Claude Code configuration in a project */ static async install( env: TestEnvironment, projectPath: string, options: { withServers?: boolean; customServers?: Record<string, MCPServerConfig>; withBackup?: boolean; withSlashCommands?: boolean; globalCommands?: boolean; } = {} ): Promise<void> { const { withServers = true, customServers, withBackup = false, withSlashCommands = false, globalCommands = false } = options; const servers = withServers ? (customServers || this.getDefaultServers()) : {}; const config = this.createConfig(servers); // Convert project path to be relative to base dir if needed const relativeProjectPath = projectPath.startsWith('/') ? projectPath.substring(env.getBaseDir().length + 1) : projectPath; const files: Record<string, string> = { [join(relativeProjectPath, '.mcp.json')]: config }; // Add backup if requested if (withBackup) { files[join(relativeProjectPath, '.mcp.backup.json')] = config; } // Add hypertool config if exists if (Object.keys(servers).length > 0) { const hypertoolConfig = { mcpServers: servers }; files[join(relativeProjectPath, 'mcp.hypertool.json')] = JSON.stringify(hypertoolConfig, null, 2); } // Add slash commands if requested if (withSlashCommands) { const commandsPath = globalCommands ? '.claude/commands/ht' : join(relativeProjectPath, '.claude/commands/ht'); files[join(commandsPath, 'list-all-tools.md')] = '# List all tools\nLists all available MCP tools'; files[join(commandsPath, 'use-toolset.md')] = '# Use toolset\nActivates a specific toolset'; } // Add project files files[join(relativeProjectPath, 'package.json')] = JSON.stringify({ name: 'test-project', version: '1.0.0', description: 'Test project for Claude Code' }, null, 2); await env.createAppStructure('claude-code', files); } /** * Create a corrupted configuration */ static async installCorrupted(env: TestEnvironment, projectPath: string): Promise<void> { const relativeProjectPath = projectPath.startsWith('/') ? projectPath.substring(env.getBaseDir().length + 1) : projectPath; await env.createAppStructure('claude-code', { [join(relativeProjectPath, '.mcp.json')]: 'not valid json at all', [join(relativeProjectPath, 'package.json')]: JSON.stringify({ name: 'corrupted-project' }, null, 2) }); } /** * Create configuration with hypertool already set up */ static async installWithHypertool( env: TestEnvironment, projectPath: string, originalServers: Record<string, MCPServerConfig> = {} ): Promise<void> { const relativeProjectPath = projectPath.startsWith('/') ? projectPath.substring(env.getBaseDir().length + 1) : projectPath; const configPath = join(relativeProjectPath, '.mcp.json'); const hypertoolPath = join(relativeProjectPath, 'mcp.hypertool.json'); // Main config only has hypertool const mainConfig = { mcpServers: { 'hypertool-mcp': { type: 'stdio', command: 'npx', args: ['-y', '@toolprint/hypertool-mcp', '--mcp-config', hypertoolPath] } } }; // Hypertool config has the original servers const hypertoolConfig = { mcpServers: Object.keys(originalServers).length > 0 ? originalServers : this.getDefaultServers() }; await env.createAppStructure('claude-code', { [configPath]: JSON.stringify(mainConfig, null, 2), [hypertoolPath]: JSON.stringify(hypertoolConfig, null, 2), [join(relativeProjectPath, '.mcp.backup.json')]: JSON.stringify({ mcpServers: hypertoolConfig.mcpServers }, null, 2), [join(relativeProjectPath, 'package.json')]: JSON.stringify({ name: 'hypertool-project', version: '1.0.0' }, null, 2), [join(relativeProjectPath, '.git/config')]: '[core]\nrepositoryformatversion = 0' }); } /** * Check if Claude Code is configured in a project */ static async isInstalled(env: TestEnvironment, projectPath: string): Promise<boolean> { const relativeProjectPath = projectPath.startsWith('/') ? projectPath.substring(env.getBaseDir().length + 1) : projectPath; return await env.fileExists(join(relativeProjectPath, '.mcp.json')); } /** * Create project without MCP configuration */ static async createEmptyProject(env: TestEnvironment, projectPath: string): Promise<void> { const relativeProjectPath = projectPath.startsWith('/') ? projectPath.substring(env.getBaseDir().length + 1) : projectPath; await env.createAppStructure('claude-code', { [join(relativeProjectPath, 'package.json')]: JSON.stringify({ name: 'empty-project', version: '1.0.0', description: 'Project without MCP configuration' }, null, 2), [join(relativeProjectPath, '.git/config')]: '[core]\nrepositoryformatversion = 0', [join(relativeProjectPath, 'README.md')]: '# Empty Project\nThis project has no MCP configuration.' }); } /** * Check if global slash commands are installed */ static async hasGlobalCommands(env: TestEnvironment): Promise<boolean> { return await env.fileExists('.claude/commands/ht/list-all-tools.md'); } /** * Check if project has local slash commands */ static async hasLocalCommands(env: TestEnvironment, projectPath: string): Promise<boolean> { const relativeProjectPath = projectPath.startsWith('/') ? projectPath.substring(env.getBaseDir().length + 1) : projectPath; return await env.fileExists(join(relativeProjectPath, '.claude/commands/ht/list-all-tools.md')); } }

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/toolprint/hypertool-mcp'

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