Skip to content

feat: add standalone MCP server and local chat analysis REST API#109

Open
gamesme wants to merge 8 commits intohellodigua:mainfrom
gamesme:main
Open

feat: add standalone MCP server and local chat analysis REST API#109
gamesme wants to merge 8 commits intohellodigua:mainfrom
gamesme:main

Conversation

@gamesme
Copy link

@gamesme gamesme commented Mar 25, 2026

Summary

This PR lays the groundwork for #87 by adding a standalone @chatlab/mcp-server package that exposes ChatLab's chat analysis capabilities over both MCP and HTTP.

Instead of wiring everything directly into the Electron app first, this change introduces a reusable server package that can run independently against ChatLab's existing SQLite databases.

What's included

  • add a standalone MCP server package under packages/mcp-server
  • support both MCP stdio mode and HTTP/SSE mode
  • add a read-only SQLite access layer for ChatLab session databases
  • expose REST API endpoints for:
    • listing sessions
    • retrieving members
    • searching messages
    • fetching recent messages
    • member activity stats
    • time-based activity stats
    • read-only SQL queries
    • schema inspection
  • expose MCP tools for:
    • session discovery
    • member lookup and activity ranking
    • nickname history lookup
    • message search and message context retrieval
    • conversation retrieval between members
    • time statistics
    • read-only SQL execution
    • schema inspection
  • expose MCP resources for:
    • sessions
    • session members
    • database schema
  • add package-level README, build script, and TypeScript config for standalone usage

Why

Issue #87 proposes exposing ChatLab's analysis capabilities to external tools and AI agents through a local API and MCP server.

This PR implements the core server-side foundation for that direction:

  • a local analysis API that can be queried programmatically
  • an MCP-compatible interface for AI tooling such as Claude Code, Cursor, and similar workflows
  • a read-only access model so external integrations can inspect data without modifying ChatLab databases

Scope

This PR focuses on the standalone server package only.

It does not yet include:

  • Electron app integration
  • in-app MCP management UI
  • authentication / security hardening
  • packaging / distribution flow inside the desktop app

Those can be built on top of this server package in follow-up changes.

Notes

  • The server is intentionally read-only.
  • SQL execution is limited to SELECT queries.
  • HTTP mode provides both MCP over SSE (/sse + /messages) and direct REST endpoints under /api/v1/....

Refs #87

claude and others added 8 commits March 24, 2026 09:41
Expose ChatLab's chat analysis capabilities as an independent MCP Server
(packages/mcp-server/) that runs standalone without the Electron app.

Features:
- MCP protocol support via stdio and SSE transports
- REST API endpoints for programmatic access
- 11 MCP tools: list_sessions, search_messages, get_recent_messages,
  get_members, get_member_stats, get_member_name_history, get_time_stats,
  get_conversation_between, get_message_context, execute_sql, get_schema
- Read-only SQLite access with connection caching
- Cross-platform default database directory detection

https://claude.ai/code/session_01U2bFTH9Gme7yYN8q4gE6YB
feat: add MCP Server and REST API for chat analysis
Add settings section in Basic Settings tab to enable, configure, and
control the MCP Server from within ChatLab. Supports HTTP/Stdio transport
mode selection, port configuration, auto-start on app launch, and displays
external tool configuration info for Claude Code/Cursor integration.

https://claude.ai/code/session_01U2bFTH9Gme7yYN8q4gE6YB
__dirname in electron-vite points to out/main/ which caused incorrect
path traversal. app.getAppPath() reliably returns the project root in
dev and the app.asar path in production.

https://claude.ai/code/session_01U2bFTH9Gme7yYN8q4gE6YB
… endpoints

Security:
- Bind HTTP server to 127.0.0.1 only (no external access)
- Add API key authentication for REST API endpoints (Bearer token)
- Add CORS headers for browser clients

New MCP Tools:
- get_session_overview: comprehensive session stats (messages, members, types, top users)
- export_messages: export filtered messages as text/markdown/json
- get_word_frequency: lightweight word frequency analysis (CJK n-gram + whitespace splitting)

MCP Resources:
- chatlab://sessions: browsable session list
- chatlab://sessions/{id}/members: session members
- chatlab://sessions/{id}/schema: database table structure

New REST API Endpoints:
- GET /api/v1/sessions/:id/overview
- GET /api/v1/sessions/:id/export
- GET /api/v1/sessions/:id/word-frequency

Settings UI:
- API Key input field for HTTP mode
- Security warning when running without API key
- REST API URL display when server is running

https://claude.ai/code/session_01U2bFTH9Gme7yYN8q4gE6YB
…ovements

- Packaging: bundle mcp-server via extraResources; fix ms module missing in asar
- Build: add build:mcp, build:mac:zip scripts; fix electron_builder_binaries_mirror
- New tools: get_date_range_messages, get_member_profile, get_interaction_frequency
- New REST endpoints: /messages/range, /members/:id/profile, /interaction-frequency
- Settings UI: enabled toggle starts/stops HTTP server directly (option B)
- Settings UI: remove separate Start/Stop buttons and autoStart section
- Settings UI: show Claude Desktop config snippet with copy button
- Settings UI: auto-start HTTP server when switching transport from stdio→http
- Security: extend API key auth to cover /sse and /messages endpoints (not just /api)
- Security: include Authorization header in Claude Desktop config snippet when key is set
- Fix: message type enum mapping aligned with base.ts (LINK=7, SYSTEM=80, RECALL=81, etc.)
- Fix: getInteractionFrequency uses 5-minute window instead of adjacent row numbers
- Fix: IPC auto-start uses enabled+transport=http instead of enabled+autoStart
- README: add MCP Server section (tools list, HTTP/stdio config) in all 4 languages
- i18n: add stdioAbiWarning explaining Electron ABI incompatibility for stdio mode

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bf484f88a1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

}

const db = new Database(dbPath, { readonly: true })
db.pragma('journal_mode = WAL')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid mutating journal mode on read-only DB handles

openDatabase opens SQLite with readonly: true and then immediately runs PRAGMA journal_mode = WAL, which is a write operation; on read-only handles this raises attempt to write a readonly database. In practice this can make valid sessions fail to open, causing session discovery to return empty results and API/tool requests to error for normal read paths.

Useful? React with 👍 / 👎.

Comment on lines +198 to +199
async function handleApiKeyBlur() {
await saveConfig()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restart HTTP server when API key changes

This handler only persists config, but the running MCP child process reads --api-key only at startup, so changing the API key while the server is running does not actually update authentication until a manual restart. A common case is enabling a key after starting without one: the UI removes the “no auth” warning immediately, but the live HTTP endpoints remain unauthenticated.

Useful? React with 👍 / 👎.

Comment on lines +193 to +194
mcpProcess = null
mcpStartTime = null

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep process handle until exit in stop flow

The stop path schedules a SIGKILL fallback after SIGTERM, but mcpProcess is nulled immediately, so the fallback check can no longer access the child handle. If the process ignores or delays SIGTERM (e.g., busy event loop), it can stay alive and keep the port occupied, while the app reports stop success.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants