MCP Guide: Complete Implementation

From technical analysis to production deployment with mcpresso

šŸ“– Reading time: 15 minutes •Level: Senior Developer •Prerequisites: TypeScript, REST APIs

1. What is Model Context Protocol (MCP)?

Model Context Protocol (MCP) is a standard developed by Anthropic to connect AI agents to enterprise data sources. MCP allows models like Claude to access your APIs, databases, and internal systems in a secure and structured way.

šŸŽÆ Real-world Use Cases

  • ChatGPT analyzing your Salesforce CRM
  • Claude generating reports from your database
  • AI agents automating your internal workflows
  • AI accessing your technical documentation

MCP works on a client-server architecture where your MCP server exposes your data as "resources" that AI agents can discover and use automatically.

2. MCP Server Architecture

An MCP server exposes three main components:

šŸ“‹ Resources

Data exposed to AI agents (users, documents, etc.)

šŸ”§ Tools

Actions that agents can execute (CRUD, search, etc.)

šŸ”„ Prompts

Reusable prompt templates for agents

3. Preliminary Technical Analysis

Before implementing MCP, evaluate your existing architecture:

āœ… Evaluation ChecklistText
# Existing APIs
ā–” Documented REST APIs
ā–” Authentication in place (OAuth, API keys)
ā–” Rate limiting configured
ā–” Data schemas defined

# Infrastructure
ā–” Server capable of handling JSON-RPC
ā–” HTTPS configured
ā–” Monitoring in place
ā–” Backup and recovery

# Security
ā–” Data access policies
ā–” Audit trail
ā–” Sensitive data encryption
ā–” GDPR/CCPA compliance

āš ļø Critical point: Don't expose all your data at once. Start with a non-critical subset to validate the approach.

4. Manual Implementation vs mcpresso

Implementing MCP manually requires handling the JSON-RPC protocol, schema validation, and serialization. Here's a comparison:

Manual Implementation

Manual MCP ImplementationJAVASCRIPT
// Manual protocol handling
server.on('resource/list', async (request) => {
  try {
    // Manual validation
    if (!isValidRequest(request)) {
      return errorResponse('Invalid request');
    }
    
    // Business logic
    const resources = await getResources();
    
    // Manual serialization
    return {
      jsonrpc: '2.0',
      id: request.id,
      result: {
        resources: [
          {
            uri: 'users/123',
            name: 'John Doe',
            description: 'CRM User',
            mimeType: 'application/json'
          }
        ]
      }
    };
  } catch (error) {
    return errorResponse(error.message);
  }
});

// + 100 lines of boilerplate...

With mcpresso

mcpresso ImplementationTYPESCRIPT
import { createResource } from 'mcpresso';

const userResource = createResource({
  name: 'user',
  schema: UserSchema,
  uri_template: 'users/{id}',
  handlers: {
    list: async () => getUsers(),
    get: async ({ id }) => getUser(id),
    create: async (data) => createUser(data)
  },
  methodConfig: {
    create: { omit: ['id', 'createdAt'] },
    search: {
      schema: z.object({
        query: z.string(),
        department: z.string().optional()
      })
    }
  }
});

// mcpresso automatically generates:
// - Zod validation
// - JSON-RPC serialization  
// - Error handling
// - TypeScript types

5. Setup with mcpresso

Installation and configuration of an MCP server with mcpresso:

Package InstallationBash
npm install mcpresso zod
# or
yarn add mcpresso zod
mcp-server.tsTYPESCRIPT
import { z } from 'zod';
import { createResource, createMCPServer } from 'mcpresso';

// 1. Define schemas
const UserSchema = z.object({
  id: z.string(),
  name: z.string(),
  email: z.string().email(),
  department: z.string(),
  createdAt: z.date(),
  updatedAt: z.date()
});

const NoteSchema = z.object({
  id: z.string(),
  title: z.string(),
  content: z.string(),
  authorId: z.string(),
  tags: z.array(z.string()),
  createdAt: z.date()
});

// 2. Create resources
const userResource = createResource({
  name: 'user',
  schema: UserSchema,
  uri_template: 'users/{id}',
  handlers: {
    list: async () => {
      return await db.users.findMany();
    },
    get: async ({ id }) => {
      return await db.users.findUnique({ where: { id } });
    },
    search: async ({ query, department }) => {
      return await db.users.findMany({
        where: {
          OR: [
            { name: { contains: query } },
            { email: { contains: query } }
          ],
          department: department || undefined
        }
      });
    }
  },
  methodConfig: {
    search: {
      schema: z.object({
        query: z.string().describe('Search in name or email'),
        department: z.string().optional().describe('Filter by department')
      })
    }
  }
});

const noteResource = createResource({
  name: 'note',
  schema: NoteSchema,
  uri_template: 'notes/{id}',
  relations: {
    authorId: { type: 'user' }
  },
  handlers: {
    list: async () => db.notes.findMany(),
    get: async ({ id }) => db.notes.findUnique({ where: { id } }),
    create: async (data) => db.notes.create({ data }),
    update: async ({ id, ...data }) => {
      return db.notes.update({ where: { id }, data });
    }
  },
  customMethods: {
    summarize: {
      description: 'Generate AI summary of notes',
      inputSchema: z.object({
        authorId: z.string(),
        period: z.enum(['week', 'month', 'year'])
      }),
      handler: async ({ authorId, period }) => {
        const notes = await getNotesForPeriod(authorId, period);
        return await generateAISummary(notes);
      }
    }
  }
});

// 3. Create server
const server = createMCPServer({
  name: 'company_mcp_server',
  version: '1.0.0',
  resources: [userResource, noteResource],
  
  // Security
  auth: {
    issuer: 'https://auth.company.com'
  },
  
  // Rate limiting
  rateLimit: {
    windowMs: 15 * 60 * 1000, // 15 minutes
    limit: 100 // requests per window
  },
  
  // Automatic retry
  retry: {
    retries: 3,
    factor: 2,
    minTimeout: 1000,
    maxTimeout: 10000
  },
  
  // Types for AI models
  exposeTypes: true
});

// 4. Start server
server.listen(3000, () => {
  console.log('MCP Server running on http://localhost:3000');
});

6. Security and Production

Securing an MCP server is critical in production:

šŸ” Security Checklist

  • OAuth 2.1: Robust authentication
  • Rate limiting: Protection against abuse
  • HTTPS mandatory: Transport encryption
  • Strict validation: All inputs validated
  • Audit logs: Access traceability
  • Principle of least privilege: Minimal necessary access

7. Best Practices

šŸ“Š Performance

  • Pagination on lists
  • Cache frequent queries
  • Appropriate timeouts
  • Performance monitoring

šŸ”§ Maintainability

  • API versioning
  • Up-to-date documentation
  • Automated tests
  • Mandatory code review

šŸŽÆ AI Agent UX

  • Clear resource descriptions
  • Examples in schemas
  • Explicit error messages
  • Types exposed to models

8. Deployment

mcpresso is compatible with major deployment platforms:

šŸš€ Vercel
Edge Functions deployment
ā˜ļø AWS Lambda
Serverless with API Gateway
šŸ”„ Cloudflare Workers
Global edge computing

šŸ“š Tip: Check the official documentation of your cloud provider for step-by-step deployment guides.

Ready to revolutionize your AI operations?

Get early access to build and deploy production-ready AI agents with enterprise-grade security and governance