Skip to main content
Glama
bswa006

AI Agent Template MCP Server

by bswa006

get_pattern_for_task

Provides structured code patterns for specific development tasks like components, APIs, tests, hooks, services, and utilities based on task requirements and context.

Instructions

Get the correct pattern to use for a specific task

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
taskTypeYesType of task to get pattern for
contextNo

Implementation Reference

  • MCP tool handler in the switch statement that validates input parameters using Zod, calls the getPatternForTask helper function, and returns the generated pattern as text content.
    case 'get_pattern_for_task': {
      const params = z.object({
        taskType: z.enum(['component', 'hook', 'service', 'api', 'test', 'error-handling']),
        requirements: z.array(z.string()).optional(),
      }).parse(args);
      
      const pattern = await getPatternForTask(
        params.taskType,
        params.requirements
      );
      return {
        content: [
          {
            type: 'text',
            text: pattern,
          },
        ],
      };
    }
  • Tool definition object exported in toolDefinitions array, providing the name, description, and inputSchema for the get_pattern_for_task tool used in ListTools response.
    {
      name: 'get_pattern_for_task',
      description: 'Get the correct pattern to use for a specific task',
      inputSchema: {
        type: 'object',
        properties: {
          taskType: {
            type: 'string',
            enum: ['component', 'api', 'test', 'hook', 'service', 'utility'],
            description: 'Type of task to get pattern for',
          },
          context: {
            type: 'object',
            properties: {
              hasState: { type: 'boolean' },
              hasAsync: { type: 'boolean' },
              needsAuth: { type: 'boolean' },
              complexity: {
                type: 'string',
                enum: ['simple', 'medium', 'complex'],
              },
            },
          },
        },
        required: ['taskType'],
      },
    },
  • Main helper function implementing the pattern generation logic: loads base patterns by task type, enhances with project context from files, adjusts for requirements, and returns markdown template.
    export async function getPatternForTask(
      taskType: TaskType,
      requirements?: string[]
    ): Promise<string> {
      const projectPath = process.env.PROJECT_PATH || process.cwd();
      const contextPath = join(projectPath, 'CODEBASE-CONTEXT.md');
      const templatePath = join(projectPath, '..', 'PROJECT-TEMPLATE-v10.md');
      
      let basePattern = getBasePattern(taskType);
      
      // Enhance with project-specific patterns
      if (existsSync(contextPath)) {
        const contextContent = readFileSync(contextPath, 'utf-8');
        basePattern = enhanceWithProjectContext(basePattern, contextContent, taskType);
      }
      
      // Add requirements-specific adjustments
      if (requirements && requirements.length > 0) {
        basePattern = adjustForRequirements(basePattern, requirements, taskType);
      }
      
      return basePattern;
    }
  • Helper function providing hardcoded base markdown patterns for each taskType (component, hook, service, api, test, error-handling) with code examples and checklists.
    function getBasePattern(taskType: TaskType): string {
      const patterns: Record<TaskType, string> = {
        component: `# React Component Pattern
    
    ## Required Structure
    \`\`\`typescript
    import React from 'react';
    import type { ComponentNameProps } from '../types';
    
    interface ComponentNameProps {
      // Define all props with TypeScript types
      required: string;
      optional?: boolean;
      children?: React.ReactNode;
    }
    
    const ComponentName: React.FC<ComponentNameProps> = ({ 
      required,
      optional = false,
      children 
    }) => {
      // 1. Hooks (if needed)
      const [state, setState] = useState<Type>(initialValue);
      
      // 2. Data fetching (if needed)
      const { data, isLoading, error } = useQuery(...);
      
      // 3. Event handlers
      const handleEvent = useCallback(() => {
        // Handle with proper error handling
      }, [dependencies]);
      
      // 4. Effects (if needed)
      useEffect(() => {
        // Effect logic
        return () => {
          // Cleanup
        };
      }, [dependencies]);
      
      // 5. Early returns for states
      if (isLoading) return <LoadingSpinner />;
      if (error) return <ErrorMessage error={error} />;
      if (!data) return <EmptyState />;
      
      // 6. Main render
      return (
        <div className="component-wrapper">
          {/* Component content */}
        </div>
      );
    };
    
    export default ComponentName;
    \`\`\`
    
    ## Checklist
    - [ ] TypeScript interfaces for all props
    - [ ] Loading, error, and empty states handled
    - [ ] Event handlers wrapped in useCallback if passed as props
    - [ ] No inline styles (use className)
    - [ ] Accessibility attributes included
    - [ ] Memoization applied where needed
    `,
    
        hook: `# React Hook Pattern
    
    ## Required Structure
    \`\`\`typescript
    import { useState, useEffect, useCallback, useMemo } from 'react';
    import type { HookReturnType } from '../types';
    
    interface UseHookNameOptions {
      // Hook configuration options
      initialValue?: Type;
      onSuccess?: (data: Type) => void;
      onError?: (error: Error) => void;
    }
    
    interface UseHookNameReturn {
      data: Type | null;
      isLoading: boolean;
      error: Error | null;
      refetch: () => Promise<void>;
    }
    
    export function useHookName(
      param: string,
      options: UseHookNameOptions = {}
    ): UseHookNameReturn {
      // 1. State management
      const [data, setData] = useState<Type | null>(null);
      const [isLoading, setIsLoading] = useState(false);
      const [error, setError] = useState<Error | null>(null);
      
      // 2. Callbacks
      const fetchData = useCallback(async () => {
        try {
          setIsLoading(true);
          setError(null);
          
          const result = await apiCall(param);
          setData(result);
          options.onSuccess?.(result);
        } catch (err) {
          const error = err instanceof Error ? err : new Error('Unknown error');
          setError(error);
          options.onError?.(error);
        } finally {
          setIsLoading(false);
        }
      }, [param, options.onSuccess, options.onError]);
      
      // 3. Effects
      useEffect(() => {
        fetchData();
      }, [fetchData]);
      
      // 4. Memoized values
      const memoizedValue = useMemo(() => {
        // Expensive computations
        return computeValue(data);
      }, [data]);
      
      // 5. Return consistent interface
      return {
        data,
        isLoading,
        error,
        refetch: fetchData,
      };
    }
    \`\`\`
    
    ## Rules
    - [ ] Must start with "use"
    - [ ] Cannot be called conditionally
    - [ ] Must return consistent interface
    - [ ] Handle all edge cases
    - [ ] Clean up effects properly
    `,
    
        service: `# Service Layer Pattern
    
    ## Required Structure
    \`\`\`typescript
    import type { ApiResponse, ServiceError } from '../types';
    
    class ServiceName {
      private baseUrl: string;
      
      constructor(baseUrl: string = process.env.API_URL || '') {
        this.baseUrl = baseUrl;
      }
      
      // GET method example
      async getItems(params?: QueryParams): Promise<ApiResponse<Item[]>> {
        try {
          const queryString = this.buildQueryString(params);
          const response = await fetch(\`\${this.baseUrl}/items\${queryString}\`);
          
          if (!response.ok) {
            throw new ServiceError(\`Failed to fetch items: \${response.statusText}\`, response.status);
          }
          
          const data = await response.json();
          return { data, error: null };
        } catch (error) {
          console.error('ServiceName.getItems error:', error);
          return { 
            data: null, 
            error: this.formatError(error) 
          };
        }
      }
      
      // POST method example
      async createItem(item: CreateItemDto): Promise<ApiResponse<Item>> {
        try {
          const response = await fetch(\`\${this.baseUrl}/items\`, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              ...this.getAuthHeaders(),
            },
            body: JSON.stringify(item),
          });
          
          if (!response.ok) {
            const errorData = await response.json();
            throw new ServiceError(errorData.message || 'Failed to create item', response.status);
          }
          
          const data = await response.json();
          return { data, error: null };
        } catch (error) {
          console.error('ServiceName.createItem error:', error);
          return { 
            data: null, 
            error: this.formatError(error) 
          };
        }
      }
      
      // Helper methods
      private buildQueryString(params?: Record<string, any>): string {
        if (!params) return '';
        const filtered = Object.entries(params)
          .filter(([_, value]) => value !== undefined && value !== null)
          .map(([key, value]) => \`\${key}=\${encodeURIComponent(String(value))}\`);
        return filtered.length > 0 ? \`?\${filtered.join('&')}\` : '';
      }
      
      private getAuthHeaders(): Record<string, string> {
        const token = this.getAuthToken();
        return token ? { Authorization: \`Bearer \${token}\` } : {};
      }
      
      private formatError(error: unknown): ServiceError {
        if (error instanceof ServiceError) return error;
        if (error instanceof Error) return new ServiceError(error.message);
        return new ServiceError('An unknown error occurred');
      }
    }
    
    export default new ServiceName();
    \`\`\`
    
    ## Requirements
    - [ ] Consistent error handling
    - [ ] Type-safe responses
    - [ ] Proper HTTP methods
    - [ ] Authentication handling
    - [ ] Request/response logging
    - [ ] Input validation
    `,
    
        api: `# API Endpoint Pattern
    
    ## RESTful API Structure
    \`\`\`typescript
    import type { Request, Response, NextFunction } from 'express';
    import { z } from 'zod';
    
    // Validation schemas
    const createItemSchema = z.object({
      name: z.string().min(1).max(100),
      description: z.string().optional(),
      price: z.number().positive(),
    });
    
    const querySchema = z.object({
      page: z.coerce.number().positive().default(1),
      limit: z.coerce.number().positive().max(100).default(20),
      sort: z.enum(['name', 'price', 'created']).default('created'),
    });
    
    // Controller class
    export class ItemController {
      // GET /items
      async getItems(req: Request, res: Response, next: NextFunction) {
        try {
          // Validate query params
          const query = querySchema.parse(req.query);
          
          // Business logic
          const { items, total } = await itemService.findAll(query);
          
          // Standard response format
          res.json({
            data: items,
            meta: {
              page: query.page,
              limit: query.limit,
              total,
              totalPages: Math.ceil(total / query.limit),
            },
          });
        } catch (error) {
          next(error);
        }
      }
      
      // POST /items
      async createItem(req: Request, res: Response, next: NextFunction) {
        try {
          // Validate body
          const data = createItemSchema.parse(req.body);
          
          // Check permissions
          if (!req.user?.canCreateItems) {
            throw new ForbiddenError('Insufficient permissions');
          }
          
          // Business logic
          const item = await itemService.create(data, req.user.id);
          
          // Created response
          res.status(201).json({
            data: item,
            message: 'Item created successfully',
          });
        } catch (error) {
          if (error instanceof z.ZodError) {
            return res.status(400).json({
              error: {
                code: 'VALIDATION_ERROR',
                message: 'Invalid request data',
                details: error.errors,
              },
            });
          }
          next(error);
        }
      }
      
      // Error handler middleware
      handleError(err: Error, req: Request, res: Response, next: NextFunction) {
        console.error('API Error:', err);
        
        if (err instanceof ValidationError) {
          return res.status(400).json({
            error: {
              code: 'VALIDATION_ERROR',
              message: err.message,
              details: err.details,
            },
          });
        }
        
        if (err instanceof NotFoundError) {
          return res.status(404).json({
            error: {
              code: 'NOT_FOUND',
              message: err.message,
            },
          });
        }
        
        // Generic error
        res.status(500).json({
          error: {
            code: 'INTERNAL_ERROR',
            message: 'An unexpected error occurred',
          },
        });
      }
    }
    \`\`\`
    
    ## API Checklist
    - [ ] Input validation with Zod
    - [ ] Consistent error responses
    - [ ] Proper HTTP status codes
    - [ ] Authentication/authorization
    - [ ] Rate limiting
    - [ ] Request logging
    - [ ] CORS configuration
    `,
    
        test: `# Test Pattern
    
    ## Unit Test Structure
    \`\`\`typescript
    import { render, screen, fireEvent, waitFor } from '@testing-library/react';
    import userEvent from '@testing-library/user-event';
    import { ComponentName } from './ComponentName';
    
    // Mock dependencies
    jest.mock('../hooks/useData', () => ({
      useData: jest.fn(),
    }));
    
    describe('ComponentName', () => {
      // Setup
      const defaultProps = {
        id: '123',
        name: 'Test Item',
        onClick: jest.fn(),
      };
      
      beforeEach(() => {
        jest.clearAllMocks();
      });
      
      // Rendering tests
      describe('Rendering', () => {
        it('should render with required props', () => {
          render(<ComponentName {...defaultProps} />);
          
          expect(screen.getByText('Test Item')).toBeInTheDocument();
          expect(screen.getByRole('button')).toBeEnabled();
        });
        
        it('should render loading state', () => {
          (useData as jest.Mock).mockReturnValue({
            isLoading: true,
            data: null,
            error: null,
          });
          
          render(<ComponentName {...defaultProps} />);
          
          expect(screen.getByTestId('loading-spinner')).toBeInTheDocument();
          expect(screen.queryByText('Test Item')).not.toBeInTheDocument();
        });
        
        it('should render error state', () => {
          const error = new Error('Failed to load');
          (useData as jest.Mock).mockReturnValue({
            isLoading: false,
            data: null,
            error,
          });
          
          render(<ComponentName {...defaultProps} />);
          
          expect(screen.getByText(/Failed to load/)).toBeInTheDocument();
        });
      });
      
      // Interaction tests
      describe('Interactions', () => {
        it('should call onClick when button is clicked', async () => {
          const user = userEvent.setup();
          render(<ComponentName {...defaultProps} />);
          
          await user.click(screen.getByRole('button'));
          
          expect(defaultProps.onClick).toHaveBeenCalledTimes(1);
          expect(defaultProps.onClick).toHaveBeenCalledWith('123');
        });
        
        it('should update state on input change', async () => {
          const user = userEvent.setup();
          render(<ComponentName {...defaultProps} />);
          
          const input = screen.getByLabelText('Name');
          await user.clear(input);
          await user.type(input, 'New Name');
          
          expect(input).toHaveValue('New Name');
        });
      });
      
      // Edge cases
      describe('Edge Cases', () => {
        it('should handle empty data gracefully', () => {
          render(<ComponentName {...defaultProps} items={[]} />);
          
          expect(screen.getByText('No items found')).toBeInTheDocument();
        });
        
        it('should handle missing optional props', () => {
          const { onClick, ...requiredOnly } = defaultProps;
          
          expect(() => render(<ComponentName {...requiredOnly} />)).not.toThrow();
        });
      });
      
      // Accessibility
      describe('Accessibility', () => {
        it('should have proper ARIA labels', () => {
          render(<ComponentName {...defaultProps} />);
          
          expect(screen.getByRole('button')).toHaveAttribute('aria-label');
          expect(screen.getByRole('region')).toHaveAttribute('aria-labelledby');
        });
        
        it('should be keyboard navigable', async () => {
          const user = userEvent.setup();
          render(<ComponentName {...defaultProps} />);
          
          await user.tab();
          expect(screen.getByRole('button')).toHaveFocus();
        });
      });
    });
    \`\`\`
    
    ## Test Requirements
    - [ ] Test all props combinations
    - [ ] Test all states (loading, error, empty, success)
    - [ ] Test user interactions
    - [ ] Test edge cases
    - [ ] Test accessibility
    - [ ] Mock external dependencies
    - [ ] Use meaningful test descriptions
    `,
    
        'error-handling': `# Error Handling Pattern
    
    ## Comprehensive Error Handling
    \`\`\`typescript
    // 1. Custom Error Classes
    export class AppError extends Error {
      constructor(
        message: string,
        public code: string,
        public statusCode: number = 500,
        public isOperational: boolean = true
      ) {
        super(message);
        Object.setPrototypeOf(this, AppError.prototype);
        Error.captureStackTrace(this, this.constructor);
      }
    }
    
    export class ValidationError extends AppError {
      constructor(message: string, public details?: any) {
        super(message, 'VALIDATION_ERROR', 400);
      }
    }
    
    export class NotFoundError extends AppError {
      constructor(resource: string) {
        super(\`\${resource} not found\`, 'NOT_FOUND', 404);
      }
    }
    
    export class AuthenticationError extends AppError {
      constructor(message = 'Authentication failed') {
        super(message, 'AUTH_ERROR', 401);
      }
    }
    
    // 2. Error Boundary Component
    import React, { Component, ErrorInfo, ReactNode } from 'react';
    
    interface Props {
      children: ReactNode;
      fallback?: ReactNode;
      onError?: (error: Error, errorInfo: ErrorInfo) => void;
    }
    
    interface State {
      hasError: boolean;
      error: Error | null;
    }
    
    export class ErrorBoundary extends Component<Props, State> {
      state: State = {
        hasError: false,
        error: null,
      };
      
      static getDerivedStateFromError(error: Error): State {
        return { hasError: true, error };
      }
      
      componentDidCatch(error: Error, errorInfo: ErrorInfo) {
        console.error('Error caught by boundary:', error, errorInfo);
        this.props.onError?.(error, errorInfo);
        
        // Log to error tracking service
        if (process.env.NODE_ENV === 'production') {
          errorTracker.logError(error, {
            componentStack: errorInfo.componentStack,
            props: this.props,
          });
        }
      }
      
      render() {
        if (this.state.hasError) {
          return this.props.fallback || (
            <div className="error-boundary-fallback">
              <h2>Something went wrong</h2>
              <details style={{ whiteSpace: 'pre-wrap' }}>
                {this.state.error?.toString()}
              </details>
            </div>
          );
        }
        
        return this.props.children;
      }
    }
    
    // 3. Async Error Handler
    export async function withErrorHandling<T>(
      operation: () => Promise<T>,
      context: string
    ): Promise<{ data: T | null; error: Error | null }> {
      try {
        const data = await operation();
        return { data, error: null };
      } catch (error) {
        console.error(\`Error in \${context}:\`, error);
        
        // Transform known errors
        if (error instanceof AppError) {
          return { data: null, error };
        }
        
        // Handle fetch errors
        if (error instanceof TypeError && error.message.includes('fetch')) {
          return {
            data: null,
            error: new AppError('Network error', 'NETWORK_ERROR', 0),
          };
        }
        
        // Generic error
        return {
          data: null,
          error: new AppError(
            error instanceof Error ? error.message : 'Unknown error',
            'UNKNOWN_ERROR'
          ),
        };
      }
    }
    
    // 4. React Hook with Error Handling
    export function useErrorHandler() {
      const [error, setError] = useState<Error | null>(null);
      
      const resetError = useCallback(() => setError(null), []);
      
      const handleError = useCallback((error: Error) => {
        console.error('Error handled:', error);
        setError(error);
        
        // Show user notification
        if (error instanceof AppError && error.isOperational) {
          showNotification({
            type: 'error',
            message: error.message,
          });
        } else {
          showNotification({
            type: 'error',
            message: 'An unexpected error occurred',
          });
        }
      }, []);
      
      return { error, resetError, handleError };
    }
    
    // 5. API Error Response Handler
    export function handleApiError(error: unknown): Response {
      console.error('API Error:', error);
      
      if (error instanceof ValidationError) {
        return new Response(
          JSON.stringify({
            error: {
              code: error.code,
              message: error.message,
              details: error.details,
            },
          }),
          { status: error.statusCode, headers: { 'Content-Type': 'application/json' } }
        );
      }
      
      if (error instanceof AppError) {
        return new Response(
          JSON.stringify({
            error: {
              code: error.code,
              message: error.message,
            },
          }),
          { status: error.statusCode, headers: { 'Content-Type': 'application/json' } }
        );
      }
      
      // Unknown error
      return new Response(
        JSON.stringify({
          error: {
            code: 'INTERNAL_ERROR',
            message: 'An unexpected error occurred',
          },
        }),
        { status: 500, headers: { 'Content-Type': 'application/json' } }
      );
    }
    \`\`\`
    
    ## Error Handling Checklist
    - [ ] Custom error classes for different scenarios
    - [ ] Error boundaries for React components
    - [ ] Async operation error handling
    - [ ] User-friendly error messages
    - [ ] Error logging and tracking
    - [ ] Network error handling
    - [ ] Form validation errors
    - [ ] API error responses
    `
      };
    
      return patterns[taskType];
    }

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/bswa006/mcp-context-manager'

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