mcp-note-app
Enables Google Gemini AI agents to manage notes (create, read, update, delete, search, tag) through MCP tools.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-note-appCreate a note titled 'Meeting notes' with content 'Discuss Q2 goals'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.
Related MCP server: Bruin
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-flashby 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:allOr 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.txtInstall the root orchestration dependency only if needed:
npm install2. 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-productionCreate agent/.env if you plan to use the Gemini agent:
GEMINI_API_KEY=your-gemini-api-keyOptional stdio transport variables for the agent:
MCP_STDIO_CMD=npx
MCP_STDIO_ARGS=tsx,server/src/index.tsDo not commit
.envfiles, API keys, JWT secrets, or local SQLite database files.
3. Start the app
Start backend and frontend together:
npm run devOr run them separately:
npm run dev:server
npm run dev:clientThen open the frontend at http://localhost:5173.
4. Start the AI agent
Make sure the backend is running first, then run:
npm run dev:agentOne-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 |
| Install server, client, and Python agent dependencies. |
| Create |
| Start backend and frontend concurrently. |
| Start only the Express/MCP server. |
| Start only the Vite frontend. |
| Start the Python Gemini MCP agent. |
| Build server and client. |
| Type-check/build backend. |
| Type-check/build frontend. |
| Run frontend unit tests with Vitest. |
| 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 scriptsEnvironment Variables
Server
Variable | Default | Description |
|
| Express server port. |
|
| Runtime environment. |
| required | Secret for JWT signing. Must be at least 32 characters. |
|
| Access token lifetime. |
|
| Refresh token lifetime. |
|
| SQLite database path, relative to |
|
| Allowed frontend origin. |
| required | Development API key used by |
Agent
Variable | Default | Description |
| required for agent | Google Gemini API key. |
|
| Command used for agent stdio transport. |
|
| Comma-separated stdio command args. |
API Endpoints
Method | Path | Auth | Description |
|
| API key | Login with |
|
| Refresh token | Body: |
|
| JWT | List notes. Query params: |
|
| JWT | Create a note with |
|
| JWT | Get one note. |
|
| JWT | Update note fields. |
|
| JWT | Delete a note. |
|
| none | SSE stream for frontend refresh events. |
|
| none | MCP SSE connection endpoint. |
|
| none | MCP JSON-RPC message endpoint. |
|
| 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 with optional search query, |
| Read a single note by ID. |
| Create a note with title, optional content, and optional tags. |
| Update selected fields on an existing 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:agentDirect Python invocation:
agent/.venv/bin/python agent/agent.py --transport sse --url http://localhost:3000/sseOne-shot mode:
agent/.venv/bin/python agent/agent.py --one-shot "List my notes about planning"Output formats:
# Script-friendly text, the default for --one-shot
agent/.venv/bin/python agent/agent.py --one-shot "List my notes" --format plain
# Rich Markdown, tool status, and note tables
agent/.venv/bin/python agent/agent.py --one-shot "List my notes" --format pretty
# One JSON object for scripts and integrations
agent/.venv/bin/python agent/agent.py --one-shot "List my notes" --format jsonInteractive mode uses the rich terminal renderer by default. It supports persistent command
history, completion for slash commands, and multiline prompts: press Esc then Enter to
insert a newline, and press Enter to submit. Prompts in the same running process share
conversation context, including relevant tool calls and results. Use /reset to forget the
model context, or /history to inspect a bounded summary. Context is automatically trimmed
at complete turn boundaries when it exceeds the memory budget; it is lost when the process
exits. Use /help to view available commands.
Note IDs are full UUIDs. For delete, update, or read requests, you can identify a note by
title instead of copying an ID: the agent will search with list_notes and use the exact ID
from that result. Never use a shortened ID from a manually copied table value.
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.5-flash)
--api-key KEY Gemini API key; prefer GEMINI_API_KEY in agent/.env
--one-shot QUERY Single query mode
--format FORMAT Output format: plain, pretty, or json
--verbose Show connection, turn, and tool-result details
--no-color Disable ANSI color in pretty output
--history-file PATH Override the interactive prompt history path
--memory-max-chars N Approximate maximum model context size across turns (default: 24000)Interactive commands:
/help Show command help
/tools List available MCP tools
/clear Clear the terminal
/reset Forget the current model conversation
/history Show a summary of model conversation memory
/format [FORMAT] View or set plain, pretty, or json output
/model [MODEL] View or set the Gemini model for future prompts
/verbose [on|off] View or set detailed logging
/quit Exit the agentFrontend Notes
The Vite dev server runs on
http://localhost:5173and 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.useSSElistens 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-uiFor targeted changes:
npm run build --prefix server
npm run build --prefix client-uiTroubleshooting
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-productionChange this in server/.env for any non-local environment.
This server cannot be deployed
Maintenance
Related MCP Connectors
Google Keep-style notes app with an MCP server for AI agents to read/write notes.
Markdown-based note-taking with a hosted MCP server. Your notes serve you and your AI.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Agent-native notes, tasks, dev-docs, vaults, sync & handoffs. MCP + OpenAPI dual surface.
Related MCP Servers
- FlicenseBqualityDmaintenanceA learning-focused MCP server that demonstrates core MCP concepts through a simple notepad application, enabling users to create, update, delete, and search notes while exploring tools, resources, and prompts functionality.4-
- AlicenseNot gradedqualityCmaintenanceMCP server for AI agents to read, write, and organize notes in a local-first, human-in-the-loop note-taking app.02MIT
- FlicenseNot gradedqualityCmaintenanceMCP server for a JWT-authenticated note-taking API, exposing CRUD tools for notes.-
- FlicenseNot gradedqualityCmaintenanceMCP server for a minimal note-taking app with text and images per user, enabling CRUD operations via Claude.-