npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

apprecio-mcp-base

v2.3.10

Published

Base package for creating Apprecio MCP servers with consistency

Readme

apprecio-mcp-base

Base package para crear servidores MCP (Model Context Protocol) de Apprecio con consistencia y reutilización de código.

🚀 Características

  • Servidor Base Abstracto: Clase McpBaseServer que encapsula toda la lógica común
  • Sistema de Features: Arquitectura modular con FeatureModule
  • Configuración Centralizada: Sistema de configuración con validación Zod
  • Logger Unificado: Winston logger con niveles configurables y rotación de archivos
  • Middlewares Reutilizables: Autenticación Bearer Token, Rate Limiting, CORS, Helmet
  • Conectores Database: MongoDB y Redis pre-configurados
  • Port Management: Búsqueda automática de puertos disponibles
  • Graceful Shutdown: Manejo automático de señales SIGINT/SIGTERM
  • TypeScript First: Completamente tipado con soporte para path aliases
  • CLI Generator: Generador de proyectos y features automático

📦 Instalación

npm install apprecio-mcp-base
# o
pnpm add apprecio-mcp-base

🎯 Quick Start

Opción 1: Usar el CLI (Recomendado)

# 1. Setup global link (una vez)
cd apprecio-mcp-base
npm run build
npm link

# 2. Generar nuevo proyecto
mcp-generate init

# Responder wizard:
# - Nombre del proyecto
# - Ruta
# - Usar MongoDB (sí/no)
# - Base URL de tu API
# ¿Instalar dependencias? Yes
# ¿Linkear apprecio-mcp-base? Yes

# 3. Ejecutar
cd my-project
npm run dev

Opción 2: Manual

import { 
    McpBaseServer, 
    createServer, 
    findAvailablePort,
    createMongoDBConnector,
    logger,
    type MongoDBConnector
} from 'apprecio-mcp-base';

class MyMcpServer extends McpBaseServer {
    private dbConnector?: MongoDBConnector;

    protected async registerFeatures(): Promise<void> {
        // Registrar tus features
        this.registerFeature('users', usersFeature);
    }

    protected async onBeforeStart(): Promise<void> {
        const mongoUri = this.config.mongodbUri;
        if (mongoUri) {
            this.dbConnector = createMongoDBConnector(mongoUri);
            await this.dbConnector.connect();
        }
    }

    protected async onBeforeShutdown(): Promise<void> {
        if (this.dbConnector) {
            await this.dbConnector.disconnect();
        }
    }
}

async function main() {
    const server = new MyMcpServer({
        name: 'my-mcp-server',
        version: '1.0.0',
    });

    const port = await findAvailablePort(server.getConfig().ssePort);
    const { httpServer, transport } = await createServer(port);
    
    await server.start(httpServer, transport, port);
}

main();

🔧 CLI Generator

El paquete incluye un CLI para generar proyectos y features automáticamente.

Comandos Disponibles

# Generar nuevo proyecto
mcp-generate init

# Generar nueva feature
mcp-generate feature

# Help
mcp-generate --help

Generar Proyecto

mcp-generate init

# Wizard interactivo:
? Nombre del proyecto: my-awesome-mcp
? Ruta: ./my-awesome-mcp
? Descripción: My awesome MCP server
? Autor: Apprecio
? ¿Usar MongoDB? Yes
? ¿Usar Redis? Yes
? ¿Instalar dependencias? Yes
? ¿Linkear apprecio-mcp-base? Yes

# Genera:
# ✅ Estructura completa del proyecto
# ✅ Archivos base incluyendo Redis y MongoDB setup
# ✅ Scripts de setup (post-install.sh, check-permissions.sh)
# ✅ Configuración (.env, tsconfig.json, package.json)
# ✅ README.md completo

Generar Feature

cd my-project
npm run generate

# Wizard interactivo:
? Nombre de la feature: users
? Descripción: Manage users
? ¿Necesita service? Yes
? ¿Qué orígenes de datos utilizará esta feature? (Selecciona con Espacio):
  [x] MongoDB (Mongoose)
  [x] Redis
  [ ] API HTTP Externa
? Tools: [x] list, [x] get, [x] create, [x] update
? Nombre de la entidad: user
? ¿Auto-registrar en main.ts? Yes

# Genera:
# ✅ users.feature.ts - Feature module con tools
# ✅ users.service.ts - Service inteligente que combina:
#    - Modelos de Mongoose
#    - Repositorio de Redis (con singleton compartido)
#    - Cliente HTTP (si se selecciona)
# ✅ users.validation.ts - Zod schemas
# ✅ users.model.ts (si se selecciona MongoDB)
# ✅ Actualiza main.ts automáticamente

📚 Sistema de Features

Crear un Feature Module

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { logger, type FeatureModule } from 'apprecio-mcp-base';

export const usersFeature: FeatureModule = {
    name: 'users',

    register(mcpServer: McpServer): void {
        // Registrar tool
        mcpServer.tool(
            'list_users',
            'List all users',
            {
                page: { type: 'number', description: 'Page number' },
                limit: { type: 'number', description: 'Items per page' }
            },
            async (args, extra) => {
                // Extraer token de auth
                const req = extra as any;
                const token = req?.requestInfo?.headers?.authorization;
                
                // Tu lógica aquí
                const users = await userService.list(args);
                
                return {
                    content: [{
                        type: 'text',
                        text: JSON.stringify(users)
                    }]
                };
            }
        );

        logger.info('Users feature registered');
    },

    async initialize(): Promise<void> {
        logger.info('Users feature initialized');
    },

    async cleanup(): Promise<void> {
        logger.info('Users feature cleaned up');
    }
};

Registrar Features

class MyMcpServer extends McpBaseServer {
    protected async registerFeatures(): Promise<void> {
        this.registerFeature('users', usersFeature);
        this.registerFeature('products', productsFeature);
        this.registerFeature('orders', ordersFeature);
        
        logger.info('All features registered');
    }
}

🔐 Autenticación

Middleware de Autenticación

import { createAuthMiddleware } from 'apprecio-mcp-base';

// Crear middleware
const auth = createAuthMiddleware({
    apiKey: process.env.API_KEY,
    enabled: process.env.AUTH_ENABLED !== 'false'
});

// Usar en Express
app.get('/health', handler); // Público

app.use('/sse', auth); // Protegido
app.post('/sse', handler);

Usar Token en Features

mcpServer.tool('secure_action', schema, async (args, extra) => {
    // Extraer token
    const req = extra as any;
    const token = req?.requestInfo?.headers?.authorization;
    
    if (!token) {
        throw new Error('Unauthorized');
    }
    
    // Validar y usar token
    const isValid = await validateToken(token);
    if (!isValid) {
        throw new Error('Invalid token');
    }
    
    // Procesar acción
    return { content: [{ type: 'text', text: 'Success' }] };
});

📝 Configuración

Variables de Entorno

# Authentication
API_KEY=your-secret-key-here
AUTH_ENABLED=false

# Database (opcional)
MONGODB_URI=mongodb://localhost:27017/mydb

# Server
MCP_SSE_PORT=3200

# Timeouts (ms)
MCP_TIMEOUT=180000
SSE_TIMEOUT=1800000

# Logging
LOG_LEVEL=info

# CORS
CORS_ALLOW_ORIGIN=*

# Rate Limiting
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100

Acceder a Configuración

class MyMcpServer extends McpBaseServer {
    protected async registerFeatures(): Promise<void> {
        // Acceder a config
        const config = this.config;
        
        logger.info(`Server port: ${config.ssePort}`);
        logger.info(`MongoDB URI: ${config.mongodbUri}`);
        logger.info(`Log level: ${config.logLevel}`);
    }
}

🗄️ Database Connectors

MongoDB

import { createMongoDBConnector } from 'apprecio-mcp-base';

// Crear conector
const db = createMongoDBConnector('mongodb://localhost:27017/db');

// Conectar
await db.connect();

// Usar mongoose
const connection = db.getConnection();
const User = connection.model('User', userSchema);

// Desconectar
await db.disconnect();

Redis

El proyecto generado incluye un patrón de Singleton y Repositorio para Redis.

En main.ts (Setup):

import { createRedisConnector } from 'apprecio-mcp-base';
import { setRedisClient } from './db/redis/client.js'; // Store generado

// Inicialización
const redis = createRedisConnector(process.env.REDIS_URL);
await redis.connect();

// Compartir instancia globalmente
setRedisClient(redis.getClient());

En tus Servicios (Uso):

import { getRedisClient } from '../../db/redis/client.js';
import { createRedisRepository } from '../../db/redis/redis.js';

class UserService {
    // Crea un repositorio "scopeado" a una entidad (usa prefijos ej: 'user:')
    private redis = createRedisRepository(getRedisClient(), 'user');

    async cacheUser(user: any) {
        // Métodos helper: save, find, findAll, clear, etc.
        await this.redis.save(user.id, JSON.stringify(user));
    }
}

📊 Logger

import { logger, createChildLogger, setLogLevel } from 'apprecio-mcp-base';

// Uso básico
logger.info('Server started');
logger.error('Error occurred', error);
logger.debug('Debug info', { metadata });
logger.warn('Warning message');

// Logger con contexto
const featureLogger = createChildLogger('UsersFeature');
featureLogger.info('User created', { userId: 123 });

// Cambiar nivel dinámicamente
setLogLevel('debug');

🛠️ Desarrollo

Estructura del Proyecto

apprecio-mcp-base/
├── cli/                      # CLI generator
│   ├── generators/
│   │   ├── init-generator.ts       # Generador de proyectos
│   │   ├── feature-generator.ts    # Generador de features
│   │   ├── service-generator.ts    # Generador de services
│   │   ├── router-generator.ts     # Generador de routers
│   │   └── main-updater.ts         # Actualizador de main.ts
│   ├── templates/
│   │   ├── post-install.sh
│   │   └── check-permissions.sh
│   └── generate-feature.ts   # Entry point del CLI
├── src/
│   ├── core/                 # Núcleo del framework
│   │   ├── McpBaseServer.ts  # Clase base
│   │   ├── config.ts         # Sistema de configuración
│   │   ├── logger.ts         # Logger centralizado
│   │   └── types.ts          # Tipos compartidos
│   ├── middleware/           # Middlewares Express
│   │   ├── auth.ts           # Autenticación Bearer
│   │   ├── rate-limit.ts     # Rate limiting
│   │   └── cors.ts           # CORS config
│   ├── database/             # Conectores DB
│   │   ├── mongodb.ts
│   │   └── redis.ts
│   ├── server/               # Server builders
│   │   └── express.ts
│   ├── utils/                # Utilidades
│   │   ├── port.ts           # Port finder
│   │   └── shutdown.ts       # Graceful shutdown
│   └── index.ts              # Exports principales
├── examples/                 # Ejemplos de uso
├── package.json
├── tsconfig.json
└── README.md

Scripts Disponibles

# Build del paquete
npm run build

# Build con watch
npm run build:watch

# Build CLI
npm run build:cli

# Build todo
npm run build:all

# Link global
npm link

# Generate feature (si estás en un proyecto)
npm run generate

Desarrollo del CLI

# Build CLI
npm run build:cli

# Link globalmente
npm link

# Usar en cualquier lugar
mcp-generate init

🚀 Setup para Desarrollo

1. Setup Inicial

# Clone repo
git clone https://github.com/apprecio/apprecio-mcp-base.git
cd apprecio-mcp-base

# Instalar dependencias
npm install

# Build
npm run build

# Link global
npm link

2. Crear Proyecto de Prueba

# Generar proyecto
mcp-generate init

# Configurar
cd my-test-project
npm install
npm link apprecio-mcp-base

# Ejecutar
npm run dev

3. Desarrollo Iterativo

# Terminal 1: Watch mode en apprecio-mcp-base
cd apprecio-mcp-base
npm run build:watch

# Terminal 2: Tu proyecto
cd my-test-project
npm run dev

# Los cambios en apprecio-mcp-base se reflejan automáticamente

📚 API Reference

McpBaseServer

abstract class McpBaseServer {
    constructor(options: ServerOptions)
    
    // Métodos abstractos
    protected abstract registerFeatures(): Promise<void>
    
    // Hooks opcionales
    protected async onBeforeStart?(): Promise<void>
    protected async onBeforeShutdown?(): Promise<void>
    
    // Métodos públicos
    getMcpServer(): McpServer
    getConfig(): BaseConfig
    getFeatures(): Map<string, FeatureModule>
    
    // Lifecycle
    async start(httpServer: HttpServer, transport: Transport, port: number): Promise<void>
}

FeatureModule

interface FeatureModule {
    name: string;
    register(mcpServer: McpServer): void;
    initialize?(): Promise<void>;
    cleanup?(): Promise<void>;
}

BaseConfig

class BaseConfig {
    get apiKey(): string
    get mongodbUri(): string | undefined
    get ssePort(): number
    get logLevel(): 'debug' | 'info' | 'warn' | 'error'
    get mcpTimeout(): number
    get sseTimeout(): number
    get corsAllowOrigin(): string
    get rateLimitWindowMs(): number
    get rateLimitMaxRequests(): number
}

🆘 Troubleshooting

Error: Cannot find module 'apprecio-mcp-base'

# Verificar link global
npm list -g apprecio-mcp-base --depth=0

# Si no está linkeado:
cd apprecio-mcp-base
npm run build
npm link

# En tu proyecto:
npm link apprecio-mcp-base

Error: EACCES (Permission Denied)

# En el proyecto generado
./check-permissions.sh

# Arreglar permisos
sudo chown -R $(whoami) .
chmod -R 755 .

Error: npm cache EACCES

# Arreglar caché de npm
sudo chown -R $(whoami) ~/.npm
npm cache clean --force
npm install

Cambios no se reflejan

# Rebuild apprecio-mcp-base
cd apprecio-mcp-base
npm run build

# Los proyectos linkeados ven cambios automáticamente

💡 Best Practices

✅ DO:

  • Usa el CLI para generar proyectos y features
  • Mantén features pequeños y enfocados
  • Usa el logger en lugar de console.log
  • Implementa cleanup en features con recursos
  • Usa TypeScript strict mode
  • Valida inputs con Zod

❌ DON'T:

  • No uses sudo npm install
  • No modifies archivos generados manualmente
  • No uses console.log en producción
  • No olvides implementar cleanup
  • No hardcodees configuración

🎯 Ejemplos

Ver examples/ para:

  • Servidor MCP simple
  • Servidor con MongoDB
  • Servidor con múltiples features
  • Feature con autenticación
  • Feature con validación Zod

📖 Documentación

🤝 Contribuir

  1. Fork el proyecto
  2. Crea una branch: git checkout -b feature/amazing-feature
  3. Commit cambios: git commit -m 'Add amazing feature'
  4. Push: git push origin feature/amazing-feature
  5. Abre un Pull Request

📄 Licencia

MIT © Apprecio

🔗 Links


Hecho con ❤️ por el equipo de Apprecio