summaryrefslogtreecommitdiff
path: root/mcp-servers/simple-mcp-server/.claude/commands/test.md
diff options
context:
space:
mode:
authorTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-01-16 08:30:14 +0900
committerTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-01-16 08:30:14 +0900
commit3fbb9a18372f2b6a675dd6c039ba52be76f3eeb4 (patch)
treeaa694a36cdd323a7853672ee7a2ba60409ac3b06 /mcp-servers/simple-mcp-server/.claude/commands/test.md
updates
Diffstat (limited to 'mcp-servers/simple-mcp-server/.claude/commands/test.md')
-rw-r--r--mcp-servers/simple-mcp-server/.claude/commands/test.md261
1 files changed, 261 insertions, 0 deletions
diff --git a/mcp-servers/simple-mcp-server/.claude/commands/test.md b/mcp-servers/simple-mcp-server/.claude/commands/test.md
new file mode 100644
index 0000000..eff8fe9
--- /dev/null
+++ b/mcp-servers/simple-mcp-server/.claude/commands/test.md
@@ -0,0 +1,261 @@
+# Test MCP Server
+
+Runs comprehensive tests for your MCP server including unit tests, integration tests, and protocol compliance validation.
+
+## Usage
+
+```
+/test [type] [options]
+```
+
+## Options
+
+- `type` - Test type: `unit`, `integration`, `all` (default: `all`)
+- `--coverage` - Generate coverage report
+- `--watch` - Run tests in watch mode
+- `--inspector` - Launch MCP Inspector for manual testing
+
+## Implementation
+
+```typescript
+import { exec } from 'child_process';
+import { promisify } from 'util';
+import * as fs from 'fs/promises';
+
+const execAsync = promisify(exec);
+
+async function runTests(
+ type: 'unit' | 'integration' | 'all' = 'all',
+ options: {
+ coverage?: boolean;
+ watch?: boolean;
+ inspector?: boolean;
+ } = {}
+) {
+ console.log('๐Ÿงช Running MCP Server Tests...');
+
+ // Run linting first
+ console.log('\n๐Ÿ” Running linter...');
+ try {
+ await execAsync('npm run lint');
+ console.log('โœ… Linting passed');
+ } catch (error) {
+ console.error('โŒ Linting failed:', error.message);
+ return;
+ }
+
+ // Run type checking
+ console.log('\n๐Ÿ“ Type checking...');
+ try {
+ await execAsync('npm run typecheck');
+ console.log('โœ… Type checking passed');
+ } catch (error) {
+ console.error('โŒ Type checking failed:', error.message);
+ return;
+ }
+
+ // Run tests
+ console.log(`\n๐Ÿงช Running ${type} tests...`);
+
+ let testCommand = 'npx vitest';
+
+ if (type === 'unit') {
+ testCommand += ' tests/unit';
+ } else if (type === 'integration') {
+ testCommand += ' tests/integration';
+ }
+
+ if (options.coverage) {
+ testCommand += ' --coverage';
+ }
+
+ if (options.watch) {
+ testCommand += ' --watch';
+ } else {
+ testCommand += ' --run';
+ }
+
+ try {
+ const { stdout } = await execAsync(testCommand);
+ console.log(stdout);
+
+ // Run protocol compliance check
+ if (type === 'all' || type === 'integration') {
+ console.log('\n๐Ÿ”Œ Checking MCP protocol compliance...');
+ await checkProtocolCompliance();
+ }
+
+ // Generate test report
+ if (options.coverage) {
+ console.log('\n๐Ÿ“Š Coverage report generated:');
+ console.log(' - HTML: coverage/index.html');
+ console.log(' - JSON: coverage/coverage-final.json');
+ }
+
+ console.log('\nโœ… All tests passed!');
+
+ // Launch inspector if requested
+ if (options.inspector) {
+ console.log('\n๐Ÿ” Launching MCP Inspector...');
+ await launchInspector();
+ }
+ } catch (error) {
+ console.error('\nโŒ Tests failed:', error.message);
+ process.exit(1);
+ }
+}
+
+async function checkProtocolCompliance() {
+ const tests = [
+ checkInitialization,
+ checkToolsCapability,
+ checkResourcesCapability,
+ checkPromptsCapability,
+ checkErrorHandling,
+ ];
+
+ for (const test of tests) {
+ try {
+ await test();
+ console.log(` โœ… ${test.name.replace('check', '')} compliance`);
+ } catch (error) {
+ console.log(` โŒ ${test.name.replace('check', '')} compliance: ${error.message}`);
+ throw error;
+ }
+ }
+}
+
+async function checkInitialization() {
+ // Test that server properly handles initialization
+ const { Server } = await import('@modelcontextprotocol/sdk/server/index.js');
+ const { TestTransport } = await import('../tests/utils/test-transport.js');
+
+ const server = new Server({
+ name: 'test-server',
+ version: '1.0.0',
+ }, {
+ capabilities: {
+ tools: {},
+ resources: {},
+ prompts: {},
+ },
+ });
+
+ const transport = new TestTransport();
+ await server.connect(transport);
+
+ const response = await transport.request({
+ jsonrpc: '2.0',
+ id: 1,
+ method: 'initialize',
+ params: {
+ protocolVersion: '2024-11-05',
+ capabilities: {},
+ clientInfo: {
+ name: 'test-client',
+ version: '1.0.0',
+ },
+ },
+ });
+
+ if (!response.protocolVersion) {
+ throw new Error('Server did not return protocol version');
+ }
+
+ await server.close();
+}
+
+async function checkToolsCapability() {
+ // Verify tools capability is properly implemented
+ const toolsExist = await fs.access('src/tools')
+ .then(() => true)
+ .catch(() => false);
+
+ if (!toolsExist) {
+ console.log(' (No tools implemented yet)');
+ return;
+ }
+
+ // Check that tools are properly exported
+ const { tools } = await import('../src/tools/index.js');
+ if (!Array.isArray(tools)) {
+ throw new Error('Tools must be exported as an array');
+ }
+}
+
+async function checkResourcesCapability() {
+ // Verify resources capability is properly implemented
+ const resourcesExist = await fs.access('src/resources')
+ .then(() => true)
+ .catch(() => false);
+
+ if (!resourcesExist) {
+ console.log(' (No resources implemented yet)');
+ return;
+ }
+
+ // Check that resources are properly exported
+ const { resources } = await import('../src/resources/index.js');
+ if (!Array.isArray(resources)) {
+ throw new Error('Resources must be exported as an array');
+ }
+}
+
+async function checkPromptsCapability() {
+ // Verify prompts capability is properly implemented
+ const promptsExist = await fs.access('src/prompts')
+ .then(() => true)
+ .catch(() => false);
+
+ if (!promptsExist) {
+ console.log(' (No prompts implemented yet)');
+ return;
+ }
+
+ // Check that prompts are properly exported
+ const { prompts } = await import('../src/prompts/index.js');
+ if (!Array.isArray(prompts)) {
+ throw new Error('Prompts must be exported as an array');
+ }
+}
+
+async function checkErrorHandling() {
+ // Test that server properly handles errors
+ const { handleError } = await import('../src/utils/error-handler.js');
+
+ // Test known error
+ const knownError = new Error('Test error');
+ knownError.code = 'TEST_ERROR';
+ const response1 = handleError(knownError);
+ if (!response1.error || response1.error.code !== 'TEST_ERROR') {
+ throw new Error('Error handler does not preserve error codes');
+ }
+
+ // Test unknown error
+ const unknownError = new Error('Unknown error');
+ const response2 = handleError(unknownError);
+ if (!response2.error || response2.error.code !== 'INTERNAL_ERROR') {
+ throw new Error('Error handler does not handle unknown errors');
+ }
+}
+
+async function launchInspector() {
+ console.log('Starting MCP Inspector...');
+ console.log('This will open an interactive testing UI in your browser.');
+ console.log('Press Ctrl+C to stop the inspector.\n');
+
+ const inspector = exec('npx @modelcontextprotocol/inspector');
+
+ inspector.stdout.on('data', (data) => {
+ console.log(data.toString());
+ });
+
+ inspector.stderr.on('data', (data) => {
+ console.error(data.toString());
+ });
+
+ inspector.on('close', (code) => {
+ console.log(`Inspector exited with code ${code}`);
+ });
+}
+``` \ No newline at end of file