Skip to main content
Glama
Alisaqulain

Local MCP Toolkit

by Alisaqulain
README.md
# Local MCP Toolkit

A **local-first** developer toolkit that exposes filesystem, notes, SQLite, and utility operations through a **real Model Context Protocol (MCP)** server — plus a modern dashboard for discovery, testing, and management.

No cloud AI APIs. No API keys. After `npm install`, everything runs on loopback.

## What is MCP?

The [Model Context Protocol](https://modelcontextprotocol.io) is an open protocol for connecting AI assistants and tools to external systems. An **MCP server** registers tools (with schemas); an **MCP client** discovers and invokes them over a **transport** (stdio or Streamable HTTP).

This project uses the official TypeScript SDK (`@modelcontextprotocol/sdk`), not a REST mock that pretends to be MCP.

## Architecture (short)

**One deployable Node process** in production: Fastify serves `/api/*`, `/mcp`, and the Vite-built UI from `apps/web/dist` on a single origin.

| Piece | Role |
| --- | --- |
| Fastify (apps/server) | Single HTTP server — API, MCP Streamable HTTP, static SPA |
| MCP server | Registers tools; Streamable HTTP at `/mcp` + optional stdio |
| MCP client | In-process SDK client → `/mcp` for `tools/list` & `tools/call` |
| React dashboard (apps/web) | Vite app; relative `/api/*` fetches (same origin in production) |
| SQLite | Notes, execution history, settings (`node:sqlite`) |

Development still runs Vite (`:5173`) with a proxy to Fastify (`:3847`). See `docs/ARCHITECTURE.md`, `docs/MCP_IMPLEMENTATION.md`, and `docs/DEPLOYMENT.md`.

## Prerequisites

- Node.js **22.5+** (tested with Node 24; needs built-in `node:sqlite`)
- npm 10+
- Windows, macOS, or Linux

## Install

```bash
npm install
```

Copy environment defaults:

```bash
# PowerShell
Copy-Item .env.example .env

# bash
cp .env.example .env
```

## Run (development)

One command (server + web):

```bash
npm run dev
```

Or separately:

```bash
npm run dev:server   # http://127.0.0.1:3847
npm run dev:web      # http://127.0.0.1:5173
```

Open **http://127.0.0.1:5173**. The web app proxies `/api` and `/mcp` to the backend.

On first load, the UI fetches a session token from `GET /api/session` and sends it as `X-Session-Token`.

## Production (single server)

```bash
npm run build
npm start
```

Or: `npm run start:prod`

This starts **one** Fastify process on `http://127.0.0.1:3847` that serves:

- Dashboard UI (`apps/web/dist`)
- REST API (`/api/*`)
- MCP Streamable HTTP (`/mcp`)

No separate frontend host for local/VPS production.

### Vercel (Services)

Push this repo, then import as a **multi-service** project. `vercel.json` defines `web` (Vite at `/`) and `server` (Fastify at `/api/*` + `/mcp`). Storage is ephemeral on Vercel — see `docs/DEPLOYMENT.md`.

## Stdio MCP server (Cursor / Claude Desktop)

```bash
npm run mcp:stdio -w @local-mcp/server
```

Example Cursor MCP config:

```json
{
  "mcpServers": {
    "local-mcp-toolkit": {
      "command": "npx",
      "args": ["tsx", "apps/server/src/mcp/stdio-entry.ts"],
      "cwd": "E:/mcp project",
      "env": {
        "WORKSPACE_PATH": "./data/workspace",
        "DATABASE_PATH": "./data/db/toolkit.sqlite"
      }
    }
  }
}
```

## Environment variables

| Variable | Default | Notes |
| --- | --- | --- |
| `HOST` | `127.0.0.1` | Loopback only recommended |
| `PORT` | `3847` | API + MCP HTTP |
| `WORKSPACE_PATH` | `./data/workspace` | Sandboxed files root |
| `DATABASE_PATH` | `./data/db/toolkit.sqlite` | App SQLite DB |
| `LOG_LEVEL` | `info` | Pino level |
| `ALLOWED_ORIGINS` | Vite origins | CORS allowlist |
| `SESSION_TOKEN` | auto-generated | Optional fixed token |
| `LOCAL_AI_ENABLED` | `false` | Optional Ollama status only |

See `.env.example` for the full list.

## Tests

```bash
npm run test:unit
npm run test:integration
npm test
npm run test:e2e
```

## Scripts

| Script | Purpose |
| --- | --- |
| `npm run dev` | Start API + web |
| `npm run build` | Build shared, server, web |
| `npm run typecheck` | TypeScript check |
| `npm run lint` | ESLint |
| `npm run format` | Prettier |
| `npm run db:migrate` | Apply SQLite migrations |
| `npm run audit` | Dependency audit |

## Security model

- Loopback bind by default
- Origin allowlist + Host loopback checks (DNS rebinding mitigation)
- Session token for `/api/*`
- Workspace path canonicalization, traversal rejection, symlink escape checks
- Read-only SQL validator (SELECT only)
- No shell execution, no `eval`
- MCP DNS rebinding protection on Streamable HTTP transport

Details: `docs/SECURITY.md`.

## Adding a tool

See `docs/ADDING_TOOLS.md`.

## Troubleshooting

| Issue | Fix |
| --- | --- |
| SQLite errors on old Node | Upgrade to Node 22.5+ / 24 (built-in `node:sqlite`) |
| CORS / 403 Origin | Add your UI origin to `ALLOWED_ORIGINS` |
| 401 Unauthorized | Clear site data or call `/api/session` again |
| Empty tools list | Ensure server is on `:3847` and MCP client can reach `/mcp` |
| File path errors | Use workspace-relative paths only |

## License

MIT
# Local-MCP-Toolkit