Skip to main content
Glama
rileytrottier23

journal-mcp-server

journal-mcp-server

A reference implementation of a remote MCP (Model Context Protocol) server extracted from a personal journaling app. It exposes journal read/write operations as typed tools that any MCP-compatible agent (Claude, GPT, etc.) can call over HTTP.

Built to demonstrate agent tool design, permission scoping, and OAuth 2.0 integration in a real-world single-user scenario.


What this is

The journaling app this was extracted from 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.

The interesting design challenges this solves:

  • One owner, one agent. No multi-tenancy required, but the auth model still uses proper OAuth 2.0 so it works with Claude's connector UI without any custom SDK.

  • Bearer token pinned to OAuth secret. The issued access_token is the same value as the bearer token the /mcp route checks, so the OAuth consent flow and the API auth layer are a single secret — no separate token store.

  • Stateless transport. Each HTTP request creates a fresh MCP session. No WebSocket, no persistent server-side session.

  • Storage abstracted behind an interface. The JournalStore interface 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 token

Tools

Tool

Description

create_entry

Create a journal entry for a given date (one per day). Returns an error if an entry already exists for that date.

list_recent_entries

Return the N most recent entries, newest first.

get_entry

Fetch a single entry by date (YYYY-MM-DD).

search_entries

Case-insensitive keyword search across all entry content, newest first.

get_mood_summary

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.


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 kick off 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):

  1. Claude fetches /.well-known/oauth-authorization-server to discover endpoints.

  2. Claude redirects the user to /oauth/authorize — a consent page served by this server.

  3. The user clicks Allow. The server issues a one-time auth code (5-minute TTL).

  4. Claude exchanges the code at /oauth/token. The server validates PKCE and returns MCP_TOKEN as the access_token.

  5. Claude uses the token as a bearer token on all subsequent /mcp calls.

Credentials to enter in Claude's connector UI:

Field

Value

OAuth Client ID

claude (or whatever you set OAUTH_CLIENT_ID to)

OAuth Client Secret

your MCP_TOKEN value

Remote MCP Server URL

https://your-domain.com/mcp


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, 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 dev

The 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-server

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:

  1. Implement JournalStore against your ORM or query builder of choice.

  2. Pass your implementation to handleMcpRequest(store, req, res) in src/server.ts.

The InMemoryJournalStore included here is suitable for local development and testing — data is lost on server restart.


Environment variables

Variable

Required

Description

MCP_TOKEN

Bearer token for /mcp. Also issued as the OAuth access_token.

MCP_USER_EMAIL

Owner identifier — used as the userId passed to JournalStore.

OAUTH_CLIENT_ID

OAuth client_id (e.g. claude).

PORT

optional

HTTP port, defaults to 3000.


  • Riley-Claude-Skills — Riley's versioned Claude Skills portfolio: reusable instruction sets for PM workflows, personal finance, and more.


License

MIT

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    A 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.
    26
    810
    40
    MIT
  • A
    license
    -
    quality
    B
    maintenance
    A 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.
    1
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    MCP 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.
    7
    9
    MIT
  • A
    license
    -
    quality
    C
    maintenance
    MCP 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

View all related MCP servers

Related MCP Connectors

  • MCP server for Argo RPG Platform — connects AI assistants to campaign data via OAuth2

  • Person-owned, portable AI memory as a remote MCP server, readable and writable by any MCP client.

  • MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rileytrottier23/journal-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server