PocketMCP

Kailash-Sankar/PocketMCP

3.2

If you are the rightful owner of PocketMCP and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

PocketMCP is a lightweight, local-first MCP server designed for efficient semantic search and file processing on small machines.

Tools
4
Resources
0
Prompts
0

PocketMCP

PocketMCP is a lightweight, local-first MCP (Model Context Protocol) server that automatically watches folders, chunks and embeds files locally using Transformers.js with MiniLM, stores vectors in SQLite + sqlite-vec, and exposes semantic search capabilities to VS Code and Cursor. Designed for small machines (I'm running on an Intel N100 with 16GB RAM) with zero external dependencies after initial model download.

Features

  • šŸ” Semantic Search: Find content by meaning, not just keywords
  • šŸ“ Auto-Ingestion: Watches folders and automatically processes new/changed files
  • šŸ“„ Multi-Format Support: PDF, DOCX, Markdown, and plain text files
  • ⚔ Local-First: Runs completely offline after initial model download
  • šŸ—„ļø SQLite Storage: Fast, reliable vector storage with sqlite-vec extension
  • šŸ”§ MCP Integration: Native support for VS Code and Cursor via MCP protocol
  • 🌐 Web Interface: Built-in web tester for validation and manual testing
  • šŸ’¾ Efficient: Designed for resource-constrained environments
  • šŸ”„ Real-time: Debounced file watching with smart concurrency limits
  • šŸ“Š Smart Segmentation: Page-aware PDF processing and section-aware DOCX handling
  • šŸ›”ļø Robust Error Handling: Graceful handling of encrypted, corrupted, or oversized files

Architecture

flowchart TD
    subgraph "MCP Clients"
        A[VS Code] 
        B[Cursor]
    end
    
    subgraph "Web Interface"
        W1[React Frontend<br/>:5173]
        W2[Express API<br/>:5174]
    end
    
    subgraph "PocketMCP Server"
        C[MCP Server<br/>stdio transport]
        D[File Watcher<br/>chokidar]
        E[Text Chunker<br/>~1000 chars]
        F[Embeddings<br/>Transformers.js<br/>MiniLM-L6-v2]
        G[SQLite + sqlite-vec<br/>Vector Database]
    end
    
    subgraph "File System"
        H[Watch Directory<br/>./kb/]
        I[Data Directory<br/>./data/]
    end
    
    A -.->|MCP Tools| C
    B -.->|MCP Tools| C
    W1 -->|HTTP API| W2
    W2 -->|Database Access| G
    C --> D
    D -->|File Changes| E
    E -->|Text Chunks| F
    F -->|384-dim Vectors| G
    G -.->|Search Results| C
    D -.->|Monitors| H
    G -.->|Stores in| I
    
    classDef mcpClient fill:#e1f5fe
    classDef webInterface fill:#fff3e0
    classDef server fill:#f3e5f5
    classDef storage fill:#e8f5e8
    
    class A,B mcpClient
    class W1,W2 webInterface
    class C,D,E,F,G server
    class H,I storage

Performance & Limits

  • Sweet spot: 10K-100K chunks on modest hardware
  • Query latency: Sub-100ms for top_k <= 10 on typical corpora
  • Memory usage: ~100MB for model + minimal overhead per document
  • Concurrency: Limited to 3 simultaneous file operations by default
  • File size limit: 50MB per file (configurable)

Screenshots

Web Server - Stats Web Server - Search Integration - stdio Integration - http

Table of Contents

Quick Start

1. Installation

# Clone or download the project
cd PocketMCP

# Install dependencies
pnpm install

# Setup environment
pnpm setup
# Or manually: cp .env.sample .env

2. Configuration

Edit .env file:

# SQLite database path
SQLITE_PATH=./data/index.db

# Directory to watch for file changes (optional)
WATCH_DIR=./kb

# Embedding model (default is recommended)
MODEL_ID=Xenova/all-MiniLM-L6-v2

# Chunking configuration
CHUNK_SIZE=1000
CHUNK_OVERLAP=120

3. Create Content Directory

# Create directory for your documents
mkdir -p kb

# Add some markdown or text files
echo "# My First Document" > kb/test.md
echo "This is a sample document for testing PocketMCP." >> kb/test.md

4. Start the Server

# Development - MCP server + web interface
pnpm dev

# Production - MCP server only
pnpm build && pnpm start

On first run, the server will download the MiniLM model (~100MB) and then process any files in your watch directory.

Web Tester

PocketMCP includes a comprehensive web interface for testing and validation.

Access Points

Features

šŸ“Š Database Diagnostics Panel
  • Real-time database status monitoring
  • Table counts and vector dimensions
  • SQLite WAL mode verification
  • Error detection and reporting
  • One-click smoke testing
šŸ” Search Panel
  • Interactive semantic search testing
  • LIKE vs Vector search modes
  • Configurable result count (top-K)
  • Detailed result inspection
  • Performance metrics (response time)
šŸ“„ Documents Panel
  • Browse all indexed documents
  • Pagination support
  • Document metadata display
  • Creation and update timestamps
šŸ”Ž Chunk Viewer
  • Detailed chunk inspection modal
  • Full text content display
  • Metadata and offset information
  • Copy-to-clipboard functionality

API Endpoints

EndpointMethodDescription
/healthGETServer health check
/api/db/diagGETDatabase diagnostics
/api/searchPOSTSemantic search
/api/chunk/:idGETGet specific chunk
/api/docsGETList documents

Example API Usage

Search Documents:

curl -X POST http://127.0.0.1:5174/api/search \
  -H "Content-Type: application/json" \
  -d '{"query": "machine learning", "top_k": 5, "mode": "like"}'

Get Diagnostics:

curl http://127.0.0.1:5174/api/db/diag | jq .

šŸ”§ MCP Client Integration

Cursor Integration

  1. Open Cursor Settings → MCP
  2. Add a new server:
{
  "command": "pnpm",
  "args": ["dev:mcp"],
  "cwd": "/path/to/PocketMCP",
  "env": {
    "TRANSPORT": "stdio",
    "SQLITE_PATH": "./data/index.db",
    "WATCH_DIR": "./kb"
  }
}

VS Code Integration

Add to your MCP settings:

{
  "mcpServers": {
    "pocketmcp": {
      "command": "pnpm",
      "args": ["dev:mcp"],
      "cwd": "/path/to/PocketMCP",
      "env": {
        "TRANSPORT": "stdio",
        "SQLITE_PATH": "./data/index.db",
        "WATCH_DIR": "./kb"
      }
    }
  }
}

HTTP Transport (Web Clients)

For web clients or remote access:

{
  "mcpServers": {
    "pocketmcp": {
      "transport": "http",
      "url": "http://localhost:8001/mcp"
    }
  }
}

šŸ“š API Reference

MCP Tools

search

Search for similar content using semantic search.

{
  "query": "machine learning algorithms",
  "top_k": 5,
  "filter": {
    "doc_ids": ["doc_123", "doc_456"]
  }
}
upsert_documents

Insert or update documents programmatically.

{
  "docs": [
    {
      "text": "Your document content here...",
      "external_id": "my_doc_1",
      "title": "Important Notes",
      "metadata": {}
    }
  ]
}
delete_documents

Delete documents by ID.

{
  "doc_ids": ["doc_123"],
  "external_ids": ["my_doc_1"]
}
list_documents

List all documents with pagination.

{
  "page": {
    "limit": 20
  }
}

MCP Resources

PocketMCP provides resource URIs for accessing specific chunks:

  • Format: mcp+doc://<doc_id>#<chunk_id>
  • Returns: Complete chunk data including text, offsets, and metadata

Configuration

Environment Variables

VariableDefaultDescription
SQLITE_PATH./data/index.dbPath to SQLite database file
WATCH_DIR(none)Directory to watch for file changes
MODEL_IDXenova/all-MiniLM-L6-v2Hugging Face model for embeddings
CHUNK_SIZE1000Target chunk size in characters
CHUNK_OVERLAP120Overlap between chunks in characters
PDF_MAX_PAGES300Maximum pages to process in PDF files
PDF_MIN_TEXT_CHARS500Minimum text characters required in PDFs
DOC_MAX_BYTES10000000Maximum file size for DOCX files (10MB)
DOCX_SPLIT_ON_HEADINGSfalseSplit DOCX documents on headings (h1/h2)
NODE_ENVdevelopmentEnvironment mode
VERBOSE_LOGGINGfalseEnable detailed logs
DEBUG_DOTENVfalseEnable dotenv debug output
API_PORT5174Web API server port
API_BIND127.0.0.1API server bind address
TRANSPORTbothMCP transport mode (stdio/http/both)
HTTP_HOST0.0.0.0HTTP server bind address
HTTP_PORT8001MCP server port
LOG_LEVELinfoLogging level (debug/info/warn/error)

Available Scripts

ScriptDescription
pnpm devStart web interface + API server for testing
pnpm dev:mcpStart MCP server (both transports + file watching)
pnpm buildBuild all components
pnpm startStart production MCP server (both transports + file watching)
pnpm setupCreate .env from template
pnpm cleanClean build artifacts and database

Watch Directory

  • WATCH_DIR is optional - if not set, only manual document upserts work
  • Supported files: .md, .txt, .pdf, .docx
  • File filtering: Automatically ignores temp files, .DS_Store, node_modules, etc.
  • Nested directories: Recursively watches all subdirectories

Document Processing

Processing Pipeline: Documents → Segments → Chunks

  1. Documents: Top-level files with metadata
  2. Segments: Logical divisions (PDF pages, DOCX sections, etc.)
  3. Chunks: Text pieces optimized for embedding (~1000 chars)

Status Types: ok, skipped, needs_ocr, too_large, error

Supported File Types

  • Markdown (.md)
  • Plain text (.txt)
  • PDF (.pdf) - Text-based only, no OCR
  • DOCX (.docx) - Microsoft Word documents

Notes:

  • Encrypted/password-protected files are skipped
  • Large files exceeding limits are marked as too_large
  • Scanned PDFs requiring OCR are marked as needs_ocr

Development

Project Structure

PocketMCP/                    # Monorepo root
ā”œā”€ā”€ package.json             # Workspace configuration
ā”œā”€ā”€ pnpm-workspace.yaml      # pnpm workspace setup
ā”œā”€ā”€ .env                     # Environment variables
ā”œā”€ā”€ .env.sample              # Environment template
ā”œā”€ā”€ apps/
│   ā”œā”€ā”€ api/                 # Express API server
│   │   ā”œā”€ā”€ src/
│   │   │   ā”œā”€ā”€ server.ts    # Main API server
│   │   │   └── db.ts        # Database manager
│   │   └── package.json
│   └── web/                 # React + Vite frontend
│       ā”œā”€ā”€ src/
│       │   ā”œā”€ā”€ App.tsx      # Main app component
│       │   ā”œā”€ā”€ store.ts     # Zustand state management
│       │   ā”œā”€ā”€ api.ts       # API client
│       │   └── components/  # UI components
│       └── package.json
ā”œā”€ā”€ src/                     # Original MCP server
│   ā”œā”€ā”€ server.ts            # MCP server and main entry point
│   ā”œā”€ā”€ db.ts                # SQLite database with sqlite-vec
│   ā”œā”€ā”€ embeddings.ts        # Transformers.js embedding pipeline
│   ā”œā”€ā”€ chunker.ts           # Text chunking with sentence awareness
│   ā”œā”€ā”€ ingest.ts            # Generic document ingestion
│   ā”œā”€ā”€ file-ingest.ts       # File-specific ingestion logic
│   └── watcher.ts           # File system watcher with debouncing
ā”œā”€ā”€ data/                    # SQLite database storage
ā”œā”€ā”€ kb/                      # Default watch directory (configurable)
└── README.md

Development Commands

# Install and setup
pnpm install
pnpm setup

# Development
pnpm dev          # Web interface + API
pnpm dev:mcp      # MCP server only

# Production
pnpm build
pnpm start

# Testing
curl http://127.0.0.1:5174/health

Deployment

Docker (Recommended)

Quick Start:

# Pull and run with all services (MCP + API + Web UI)
docker run -d \
  --name pocketmcp \
  --restart unless-stopped \
  -p 8001:8001 \
  -p 5174:5174 \
  -p 5173:5173 \
  -v pocketmcp_data:/app/data \
  -v pocketmcp_kb:/app/kb \
  -v pocketmcp_cache:/app/.cache \
  ghcr.io/kailash-sankar/pocketmcp:latest

Access Points:

  • MCP Server: http://localhost:8001
  • API Server: http://localhost:5174
  • Web UI: http://localhost:5173

Docker Compose:

git clone https://github.com/kailash-sankar/PocketMCP.git
cd PocketMCP
cp .env.sample .env
docker-compose up -d

Portainer Stacks

  1. Go to Stacks → Add stack
  2. Name: pocketmcp
  3. Paste this configuration:
version: '3.8'
services:
  pocketmcp:
    image: ghcr.io/kailash-sankar/pocketmcp:latest
    container_name: pocketmcp
    restart: unless-stopped
    ports:
      - "8001:8001"  # MCP Server
      - "5174:5174"  # API Server  
      - "5173:5173"  # Web UI
    volumes:
      - pocketmcp_data:/app/data
      - pocketmcp_kb:/app/kb  
      - pocketmcp_cache:/app/.cache
    environment:
      - NODE_ENV=production
      - TRANSPORT=both
      - SQLITE_PATH=/app/data/index.db
      - WATCH_DIR=/app/kb
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5173/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

volumes:
  pocketmcp_data:
  pocketmcp_kb:
  pocketmcp_cache:

Direct Installation

# Clone and setup
git clone https://github.com/kailash-sankar/PocketMCP.git
cd PocketMCP
pnpm install
pnpm setup

# Configure environment
cp .env.sample .env
# Edit .env with your settings

# Create content directory
mkdir -p kb

# Build and start
pnpm build
pnpm start

Access Points:

  • MCP Server: http://localhost:8001
  • API Server: http://localhost:5174
  • Web UI: http://localhost:5173

Troubleshooting

Model Download Issues

If the embedding model fails to download:

  • Check internet connection for initial download
  • Model cache location: ~/.cache/huggingface/transformers/
  • Clear cache and retry if needed

SQLite Extension Issues

If sqlite-vec fails to load:

  • Ensure sqlite-vec npm package is installed
  • Check that your system supports the required SQLite version
  • The system automatically falls back to regular SQLite tables if vec0 virtual tables fail

File Watching Issues

  • Files not being detected: Check file extensions and ignore patterns
  • High CPU usage: Increase debounce time with larger debounceMs values
  • Permission errors: Ensure read/write access to watch and data directories

Web Interface Issues

  • API not accessible: Ensure API server is running on port 5174
  • Database not found: Check SQLITE_PATH environment variable
  • CORS errors: API server includes CORS headers for local development

Memory Issues

  • Reduce CHUNK_SIZE for lower memory usage
  • Process fewer files simultaneously by reducing maxConcurrency
  • Consider using a smaller embedding model (though this requires code changes)

Common Error Messages

"Too many parameter values were provided"

  • This was a known issue with sqlite-vec virtual tables, now fixed with automatic fallback

"Failed to load sqlite-vec extension"

  • System automatically falls back to regular SQLite tables with JSON embeddings

"Database file does not exist"

  • Run the MCP server first to create the database, or check the SQLITE_PATH

License

MIT License - see LICENSE file for details.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

Acknowledgments

  • sqlite-vec for fast vector similarity search
  • Transformers.js for local embedding generation
  • Model Context Protocol for standardized tool integration
  • Hugging Face for the MiniLM model
  • React + Vite for the modern web interface
  • TailwindCSS for beautiful, responsive styling