PyaePhyo-Win

MCP Note App

Community PyaePhyo-Win
Updated

MCP Note App

A full-stack note-taking application with a React UI, Express/SQLite backend, real-time Server-Sent Events, JWT auth, and AI agent integration through the Model Context Protocol (MCP).

What You Get

  • Create, edit, delete, tag, and search notes in a modern React interface.
  • Live UI refreshes through SSE when notes change through REST or MCP tools.
  • JWT-protected REST note routes with local API-key login.
  • MCP SSE transport for AI clients and a Python Gemini-powered CLI agent.
  • SQLite persistence via a repository layer.

Architecture

┌─────────────────┐     MCP/SSE      ┌──────────────────┐
│  Python Agent   │ ◄──────────────► │                  │
│  (Gemini AI)    │                  │  Node.js Server  │
│                 │     Tools        │  (MCP + REST)    │
└─────────────────┘                  │                  │
                                     │    SQLite DB     │
┌─────────────────┐     REST/SSE     │                  │
│  React Frontend │ ◄──────────────► │                  │
│ (Vite+Tailwind) │                  └──────────────────┘
└─────────────────┘
  • Backend: TypeScript, Express, MCP server, SQLite (better-sqlite3), Zod, JWT.
  • Frontend: React 18, Vite, Tailwind CSS, TanStack React Query, Zustand, SSE.
  • Agent: Python MCP client connected to Google Gemini (gemini-2.5-flash by default).

Prerequisites

  • Node.js 20+ recommended.
  • npm.
  • Python 3.10+ recommended.
  • A Gemini API key for the optional Python agent.

Quick Start

1. Install dependencies

Install everything from the repository root:

npm run install:all

Or install each layer manually:

npm install --prefix server
npm install --prefix client-ui
python3 -m venv agent/.venv
agent/.venv/bin/python -m pip install -r agent/requirements.txt

Install the root orchestration dependency only if needed:

npm install

2. Configure environment

Create server/.env:

PORT=3000
NODE_ENV=development
JWT_SECRET=change-this-to-a-long-random-secret-at-least-32-chars
JWT_EXPIRY=15m
JWT_REFRESH_EXPIRY=7d
DATABASE_PATH=./data/notes.db
CORS_ORIGIN=http://localhost:5173
AUTH_TOKEN=dev-auth-token-change-in-production

Create agent/.env if you plan to use the Gemini agent:

GEMINI_API_KEY=your-gemini-api-key

Optional stdio transport variables for the agent:

MCP_STDIO_CMD=npx
MCP_STDIO_ARGS=tsx,server/src/index.ts

Do not commit .env files, API keys, JWT secrets, or local SQLite database files.

3. Start the app

Start backend and frontend together:

npm run dev

Or run them separately:

npm run dev:server
npm run dev:client

Then open the frontend at http://localhost:5173.

4. Start the AI agent

Make sure the backend is running first, then run:

npm run dev:agent

One-shot example:

agent/.venv/bin/python agent/agent.py --one-shot "Create a note titled Demo with content Hello from Gemini"

Scripts

Run these from the repository root unless noted otherwise.

Command Description
npm run install:all Install server, client, and Python agent dependencies.
npm run install:agent Create agent/.venv and install Python dependencies.
npm run dev Start backend and frontend concurrently.
npm run dev:server Start only the Express/MCP server.
npm run dev:client Start only the Vite frontend.
npm run dev:agent Start the Python Gemini MCP agent.
npm run build Build server and client.
npm run build --prefix server Type-check/build backend.
npm run build --prefix client-ui Type-check/build frontend.
npm run test --prefix client-ui Run frontend unit tests with Vitest.
npm run test:e2e --prefix client-ui Run Playwright end-to-end tests.

Project Structure

mcp-note-app/
├── server/                          # Express REST API, MCP server, SQLite persistence
│   ├── src/
│   │   ├── auth/                    # JWT signing and verification
│   │   ├── config/                  # Environment validation
│   │   ├── db/                      # SQLite connection and schema
│   │   ├── events/                  # Event bus and SSE handlers
│   │   ├── mcp/                     # MCP tool server and transports
│   │   ├── middleware/              # Auth, CORS, error handling
│   │   ├── repositories/            # NoteRepository + SQLite implementation
│   │   ├── routes/                  # Notes REST routes and live updates
│   │   ├── types.ts                 # Zod schemas and shared backend types
│   │   └── index.ts                 # Express entry point
│   └── package.json
├── client-ui/                       # React frontend
│   ├── e2e/                         # Playwright tests
│   ├── src/
│   │   ├── components/              # Presentational and UI components
│   │   ├── hooks/                   # React Query and SSE hooks
│   │   ├── services/                # API client and query client
│   │   ├── stores/                  # Zustand auth/UI state
│   │   ├── test/                    # Vitest setup and component tests
│   │   ├── types/                   # Frontend note types
│   │   ├── App.tsx
│   │   └── main.tsx
│   └── package.json
├── agent/                           # Python MCP + Gemini CLI agent
│   ├── agent.py
│   ├── mcp_gemini_adapter.py
│   └── requirements.txt
├── AGENTS.md                        # Coding-agent project guidance
├── README.md
└── package.json                     # Root orchestration scripts

Environment Variables

Server

Variable Default Description
PORT 3000 Express server port.
NODE_ENV development Runtime environment.
JWT_SECRET required Secret for JWT signing. Must be at least 32 characters.
JWT_EXPIRY 15m Access token lifetime.
JWT_REFRESH_EXPIRY 7d Refresh token lifetime.
DATABASE_PATH ./data/notes.db SQLite database path, relative to server/ when running server scripts.
CORS_ORIGIN http://localhost:5173 Allowed frontend origin.
AUTH_TOKEN required Development API key used by /api/login.

Agent

Variable Default Description
GEMINI_API_KEY required for agent Google Gemini API key.
MCP_STDIO_CMD npx Command used for agent stdio transport.
MCP_STDIO_ARGS tsx,server/src/index.ts Comma-separated stdio command args.

API Endpoints

Method Path Auth Description
POST /api/login API key Login with { "apiKey": "..." }; returns access and refresh tokens.
POST /api/refresh Refresh token Body: { "refreshToken": "..." }; returns a new access token.
GET /api/notes JWT List notes. Query params: query, limit, offset.
POST /api/notes JWT Create a note with title, optional content, optional tags.
GET /api/notes/:id JWT Get one note.
PUT /api/notes/:id JWT Update note fields.
DELETE /api/notes/:id JWT Delete a note.
GET /api/live-updates none SSE stream for frontend refresh events.
GET /sse none MCP SSE connection endpoint.
POST /messages none MCP JSON-RPC message endpoint.
GET /api/health none Health check.

Note payloads

Create note:

{
  "title": "Meeting notes",
  "content": "Discuss launch plan",
  "tags": ["work", "planning"]
}

Update note:

{
  "title": "Updated title",
  "content": "Updated content",
  "tags": ["updated"]
}

MCP Tools

The MCP server exposes these tools to AI clients:

Tool Description
list_notes List notes with optional search query, limit, and offset.
read_note Read a single note by ID.
create_note Create a note with title, optional content, and optional tags.
update_note Update selected fields on an existing note.
delete_note Delete a note by ID.

REST and MCP mutations both emit note update events so connected frontends can refresh through SSE.

Agent Usage

Interactive mode:

npm run dev:agent

Direct Python invocation:

agent/.venv/bin/python agent/agent.py --transport sse --url http://localhost:3000/sse

One-shot mode:

agent/.venv/bin/python agent/agent.py --one-shot "List my notes about planning"

Options:

--transport sse|stdio   Transport protocol (default: sse)
--url URL               MCP server URL (default: http://localhost:3000/sse)
--model MODEL           Gemini model (default: gemini-2.0-flash)
--api-key KEY           Gemini API key; prefer GEMINI_API_KEY in agent/.env
--one-shot QUERY        Single query mode

Frontend Notes

  • The Vite dev server runs on http://localhost:5173 and proxies API calls to the backend.
  • The app logs in with the development API key by default for local use.
  • Note operations use React Query and invalidate ['notes'] after mutations.
  • useSSE listens for backend update events and refreshes note queries live.

Validation

Recommended checks before committing application changes:

npm run build
npm run test --prefix client-ui
npm run test:e2e --prefix client-ui

For targeted changes:

npm run build --prefix server
npm run build --prefix client-ui

Troubleshooting

Server fails on startup with environment errors

Check server/.env. JWT_SECRET must be at least 32 characters and AUTH_TOKEN must be set.

Frontend cannot load notes

Make sure the backend is running on http://localhost:3000, the frontend is running through Vite, and CORS_ORIGIN matches http://localhost:5173.

Agent asks for a Gemini key

Create agent/.env with GEMINI_API_KEY=..., or pass --api-key for a one-off run.

Agent cannot connect to MCP

Start the backend first and verify http://localhost:3000/api/health returns {"status":"ok",...}. The default MCP endpoint is http://localhost:3000/sse.

Development Login

Default local API key:

dev-auth-token-change-in-production

Change this in server/.env for any non-local environment.

MCP Server · Populars

MCP Server · New

    livecontext-ai

    LiveContext

    The AI automation platform, self-hosted. Describe the job in chat and LiveContext builds it: readable workflows, scoped AI agents, and small apps your team uses. Chat, Workflow, Agent and App on one canvas.

    Community livecontext-ai
    timescale

    rsigma

    A complete Sigma detection engineering toolkit: parser, linter, evaluator, correlation engine, conversion framework, streaming daemon, MCP and LSP servers :crab:

    Community timescale
    Agent360dk

    Browser MCP by Agent360

    Drive your real, logged-in Chrome from any AI agent (Claude Code, Cursor, VS Code) — works where headless dies. Reads emailed login codes from your Gmail, solves CAPTCHAs, 34 tools. MIT, local-only.

    Community Agent360dk
    devlint

    GitWand

    The Git client that actually resolves conflicts — 10 deterministic patterns auto-resolve the trivial 95%, full trace on the rest. Native (Tauri 2 + Rust), free, MIT.

    Community devlint
    BETAER-08

    amdb

    Turn your codebase into AI context — entirely on your machine. Single-binary MCP server with AST parsing, call graph, and local embeddings.

    Community BETAER-08