journal-mcp-server
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., "@journal-mcp-servershow me my mood summary for this week"
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.
journal-mcp-server
A remote MCP server I pulled out of my ReflectAI journaling app. It lets Claude, or any MCP client, read and write journal entries over HTTP, with OAuth 2.0 sign-in so it works in Claude's connector settings.
I built it to work through agent tool design, permission scoping and OAuth end to end.
What this is
ReflectAI stores daily entries with a happiness score (1–10). This MCP layer lets an AI assistant, connected via claude.ai or Claude Desktop, read, write, and analyse those entries on behalf of the owner.
Design choices
One owner, one agent. No multi-tenancy, but the auth model still uses proper OAuth 2.0 so it works with Claude's connector UI without a custom SDK.
Bearer token pinned to the OAuth secret. The issued
access_tokenis the same value as the bearer token the/mcproute checks, so the OAuth consent flow and the API auth layer share a single secret and there's no separate token store.Stateless transport. Each HTTP request creates a fresh MCP session. No WebSocket, no persistent server-side session.
Storage behind an interface. The
JournalStoreinterface lets you swap the backing store (in-memory → SQLite → Postgres) without touching the tool definitions.
Related MCP server: ai-journal
Architecture
claude.ai / Claude Desktop
│
│ POST /mcp (Bearer token)
▼
┌─────────────────────────────────────────┐
│ Express app │
│ │
│ mcpAuth middleware │ ← validates bearer token,
│ │ │ sets req.mcpUserId
│ ▼ │
│ handleMcpRequest() │ ← creates MCP session per request
│ │ │
│ ▼ │
│ McpServer (Streamable HTTP transport) │
│ │ │
│ ▼ │
│ JournalStore interface │ ← swappable backing store
└─────────────────────────────────────────┘
OAuth endpoints (same server):
GET /.well-known/oauth-authorization-server → RFC 8414 metadata
GET /oauth/authorize → consent page
POST /oauth/authorize → issue auth code
POST /oauth/token → exchange code for tokenTools
Tool | Description |
| Create a journal entry for a given date (one per day). Returns an error if an entry already exists for that date. |
| Return the N most recent entries, newest first. |
| Fetch a single entry by date (YYYY-MM-DD). |
| Case-insensitive keyword search across all entry content, newest first. |
| Aggregate happiness scores across a date range: average, min, max, and a count by score tier (low/mid/high). |
All tools are defined with Zod schemas so the MCP SDK generates accurate JSON Schema for the agent's tool-use call.
Each tool also declares all four MCP behaviour hints, so a host can tell reads from writes before calling:
Tool |
|
|
|
|
| false | false | false | false |
The four read tools | true | false | true | false |
Auth model
Bearer token (primary)
Every POST /mcp request must include:
Authorization: Bearer <MCP_TOKEN>On a 401 the server returns a WWW-Authenticate header pointing to the OAuth metadata URL, which allows MCP clients that support dynamic discovery to start the OAuth flow automatically.
OAuth 2.0 (for claude.ai connector UI)
Claude's connector UI only accepts OAuth credentials, not raw bearer tokens. This server implements a minimal Authorization Code flow (RFC 6749) with PKCE (RFC 7636) and server metadata (RFC 8414):
Claude fetches
/.well-known/oauth-authorization-serverto discover endpoints.Claude redirects the user to
/oauth/authorize, a consent page served by this server.The user clicks Allow. The server issues a one-time auth code (5-minute TTL).
Claude exchanges the code at
/oauth/token. The server validates PKCE and returnsMCP_TOKENas theaccess_token.Claude uses the token as a bearer token on all subsequent
/mcpcalls.
Credentials to enter in Claude's connector UI:
Field | Value |
OAuth Client ID |
|
OAuth Client Secret | your |
Remote MCP Server URL |
|
Transport
Streamable HTTP (MCP spec §3.2). The server creates a fresh StreamableHTTPServerTransport for every request. This is the simplest MCP transport: no WebSocket handshake, no persistent connection, and it works through any HTTP reverse proxy.
Running locally
# 1. Install dependencies
npm install
# 2. Configure secrets
cp .env.example .env
# Edit .env — set MCP_TOKEN, MCP_USER_EMAIL, OAUTH_CLIENT_ID
# 3. Start the dev server (auto-reloads on file changes)
npm run devThe server starts on port 3000 by default. Test with:
# Should return 401 with WWW-Authenticate header
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
# Should return tool list
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your MCP_TOKEN>" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
# OAuth metadata
curl http://localhost:3000/.well-known/oauth-authorization-serverTests
npm testThe tests call each tool through the MCP SDK's in-memory transport, backed by InMemoryJournalStore. No server, port, or secrets are needed.
Swapping the backing store
The JournalStore interface in src/journalStore.ts is the only contract the MCP tools depend on. To use a real database:
Implement
JournalStoreagainst your ORM or query builder of choice.Pass your implementation to
handleMcpRequest(store, req, res)insrc/server.ts.
The InMemoryJournalStore included here is suitable for local development and testing; data is lost on server restart.
Environment variables
Variable | Required | Description |
| ✅ | Bearer token for |
| ✅ | Owner identifier, used as the |
| ✅ | OAuth |
| optional | HTTP port, defaults to |
Related projects
ReflectAI: the journaling app this server came from. Live at reflectai.net.
Riley-Claude-Skills: my Claude skills library.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Private journal MCP server to search, analyze, and create Dabble Me entries securely via OAuth.
MCP server for Argo RPG Platform — connects AI assistants to campaign data via OAuth2
OAuth-protected, read-only-by-default MCP server for provenance-labeled QuillCaddie project memory.
- StytchOAuthdev.stytch.mcp
The Stytch MCP server is a reference implementation that demonstrates remote MCP server authentication and authorization using Stytch Connected Apps. It provides OAuth 2.1-compliant authorization (including PKCE), Dynamic Client Registration, and validates Stytch-issued access tokens to enable AI agents to securely interact with external services through permissioned access, supporting scopes like openid, email, profile, and manage:project_data.
Related MCP Servers
- AlicenseBqualityAmaintenanceA local-first MCP server that enables AI agents to read user-authorized Google Health API v4 data from Fitbit, Pixel Watch, and partners via OAuth, with tokens never leaving the machine.26226 npm70MIT
- AlicenseNot gradedqualityCmaintenanceA local MCP server for journaling, organizing, and recalling your work. It captures entries as plain markdown files, indexes them for full-text and structured search, and enables querying via natural language.18 PyPI1MIT
- AlicenseAqualityDmaintenanceMCP server for JournalOwl that enables AI-powered journaling integration, allowing users to create, search, and browse journal entries, access weekly reviews, and get personalized suggestions directly from their AI assistant.710 npmMIT
- AlicenseNot gradedqualityDmaintenanceMCP server for structured reflection and self-modeling over Everlog diary exports, enabling agents to query local diary evidence and maintain versioned artifacts of threads, moments, beliefs, and decisions.MIT