Skip to main content

Parlor - a private parlor for AI conversation

Project description

PyPI Version Python Versions Tests License


Parlor

A private parlor for AI conversation.

Self-hosted ChatGPT-style web UI that connects to any OpenAI-compatible API.
Install with pip. Run locally. Own your data.

Quick StartFeaturesThemesSecurityAPI


Why Parlor?

Your company's AI chat UI sucks. You know it. We know it. Parlor replaces it with something you'll actually want to use.

It connects to any OpenAI-compatible endpoint --- your company's internal API, OpenAI, Azure, Ollama, LM Studio, or anything else that speaks the OpenAI protocol. Built to OWASP ASVS L1 standards because your conversations deserve real security, not security theater.

One command. No cloud. No telemetry. No compromise.

pip install parlor

Quick Start

1. Install

pip install parlor

2. Configure --- create ~/.ai-chat/config.yaml:

ai:
  base_url: "https://your-ai-endpoint/v1"
  api_key: "your-api-key"
  model: "gpt-4"

3. Verify your connection:

parlor --test

4. Launch:

parlor

Your browser opens to http://127.0.0.1:8080. That's it. You're done.


Features

Conversations

Create, rename, search, delete Full conversation lifecycle
Full-text search FTS5-powered search across all messages and titles
Fork at any message Explore different directions from any point
Edit & regenerate Fix a message and re-run from there
Export to Markdown One-click download of any conversation
Auto-titles AI generates a title from your first message
Keyboard-first Ctrl+Shift+N new chat, Escape stop generation

Projects

Group conversations under projects with custom system prompts and per-project model selection. Your coding project uses Claude with a developer prompt. Your writing project uses GPT-4 with an editorial voice. Each project is its own world.

Organization

Folders

  • Nested folder hierarchy in the sidebar
  • Collapse/expand to stay organized
  • Rename, delete (conversations preserved)

Tags

  • Color-coded labels on conversations
  • Filter the sidebar by tag
  • Visual at-a-glance categorization

Shared Databases

Connect multiple SQLite databases for team or topic-based separation. Each database is fully independent --- its own conversations, attachments, and history.

  • Visual file browser for selecting database paths
  • Copy conversations between databases
  • Switch databases from the sidebar

Rich Rendering

Markdown     ->  Full GFM with tables, lists, blockquotes
Code blocks  ->  Syntax highlighting + one-click copy
LaTeX math   ->  Inline ($x^2$) and display ($$\int$$)
Images       ->  Inline previews for attached images

File Attachments

Drag-and-drop or click to attach. 30+ file types supported --- code, documents, images, data files. Up to 10 files per message, 10 MB each. Magic-byte verification ensures files are what they claim to be.

MCP Tool Integration

Connect stdio or SSE-based MCP servers. Your AI gains access to external tools --- databases, APIs, file systems, anything with an MCP adapter. Tool calls render with expandable input/output so you see exactly what happened.

mcp_servers:
  - name: "my-tools"
    transport: "stdio"
    command: "npx"
    args: ["-y", "@my-org/mcp-tools"]

Streaming

Real-time token-by-token streaming via Server-Sent Events. Stop generation mid-response with Escape or the stop button. A thinking indicator keeps you informed while the AI processes.

Command Palette

Cmd+K / Ctrl+K opens a Raycast-style command palette. Search conversations, switch themes, create projects, jump to settings --- all without touching the mouse. Fuzzy matching makes it fast.


Themes

Four built-in themes, each with a distinct visual identity. Switch instantly via settings or command palette.

Theme Vibe
Midnight Premium tech dark --- think Linear, Raycast Default
Dawn Warm editorial light --- think Notion in sunlight Light
Aurora Living gradient dark with animated accents Showstopper
Ember Warm luxury dark --- amber by firelight Cozy

Themes persist across sessions. Glassmorphism, multi-layered shadows, micro-animations on hover/focus, gradient text effects, and smooth 0.5s cross-fade transitions between themes.


Responsive Design

Breakpoint Target Behavior
1400px+ Large desktop Wider messages, expanded sidebar
769-1399px Desktop Default layout
768-1024px Tablet Compact sidebar, full-width messages
0-767px Mobile Slide-over sidebar with hamburger menu

Configuration

Config File

~/.ai-chat/config.yaml

ai:
  base_url: "https://your-ai-endpoint/v1"
  api_key: "your-api-key"
  model: "gpt-4"
  system_prompt: "You are a helpful assistant."
  verify_ssl: true  # set false for self-signed certs

app:
  host: "127.0.0.1"
  port: 8080
  data_dir: "~/.ai-chat"

# Optional: shared databases
shared_databases:
  - name: "team-shared"
    path: "~/shared/team.db"

# Optional: MCP tool servers
mcp_servers:
  - name: "my-tools"
    transport: "stdio"
    command: "npx"
    args: ["-y", "@my-org/mcp-tools"]

  - name: "remote-tools"
    transport: "sse"
    url: "https://mcp-server.example.com/sse"

Environment Variables

Every config option has an env var override:

Variable Default Description
AI_CHAT_BASE_URL --- AI API endpoint (required)
AI_CHAT_API_KEY --- API key (required)
AI_CHAT_MODEL gpt-4 Model name
AI_CHAT_SYSTEM_PROMPT You are a helpful assistant. System prompt
AI_CHAT_VERIFY_SSL true SSL certificate verification

Settings UI

Click the gear icon to change model and system prompt at runtime. Available models are fetched live from your API.


CLI

parlor              Launch server and open browser
parlor --test       Test connection, list models, send test prompt, exit
parlor --help       Show help
Example --test output
Config:
  Endpoint: https://your-ai-endpoint/v1
  Model:    gpt-4
  SSL:      enabled

1. Listing models...
   OK - 12 model(s) available
     - gpt-4
     - gpt-4-turbo
     - gpt-3.5-turbo
     ...

2. Sending test prompt to gpt-4...
   OK - Response: Hello! How can I help you today?

All checks passed.

Security

Parlor is hardened for use on corporate networks and shared machines. Not a checkbox exercise --- real, layered defense.

Layer What it does
Authentication Random session token, HttpOnly cookies, HMAC-SHA256 timing-safe comparison
CSRF Per-session tokens validated on all state-changing requests
CSP script-src 'self', frame-ancestors 'none', no inline scripts
Security Headers X-Frame-Options DENY, X-Content-Type-Options nosniff, strict Referrer-Policy, Permissions-Policy
Database Column-allowlisted SQL builder, parameterized queries, 0600 file permissions, path validation
Input Sanitization DOMPurify on all rendered HTML, UUID validation on all IDs
Rate Limiting 120 req/min per IP with LRU eviction
Body Size 15 MB max request
CORS Locked to configured origin
File Safety MIME allowlist + magic-byte verification, path traversal prevention
MCP Safety SSRF protection with DNS resolution, shell metacharacter rejection
SRI SHA-384 hashes on all vendor scripts
API Surface OpenAPI/Swagger docs disabled

Full details in SECURITY.md.


Data Storage

Everything stays on your machine. Nothing phones home.

~/.ai-chat/
  config.yaml          # Configuration          (permissions: 0600)
  chat.db              # SQLite + WAL journal   (permissions: 0600)
  attachments/         # Files by conversation  (permissions: 0700)

The data directory is created with 0700 permissions (owner-only access). Database files are created with 0600 permissions. WAL and SHM sidecar files are locked down too.

Supported File Types

Category Extensions
Code .py .js .ts .java .c .cpp .h .hpp .rs .go .rb .php .sh .bat .ps1 .sql .css
Data .json .yaml .yml .csv .xml .toml .ini .cfg .log
Documents .txt .md .pdf
Images .png .jpg .jpeg .gif .webp

API

Parlor exposes a full REST API. All endpoints require authentication.

Conversations
Method Endpoint Description
GET /api/conversations List (with ?search=, ?project_id=, ?db=)
POST /api/conversations Create
GET /api/conversations/:id Get with messages
PATCH /api/conversations/:id Rename, move to folder, change model
DELETE /api/conversations/:id Delete with attachments
GET /api/conversations/:id/export Export as Markdown
POST /api/conversations/:id/chat Stream chat (SSE)
POST /api/conversations/:id/stop Cancel generation
POST /api/conversations/:id/fork Fork at a message
POST /api/conversations/:id/copy Copy to another database
Messages & Attachments
Method Endpoint Description
PUT /api/messages/:id Edit a message
DELETE /api/messages/:id Delete after position
GET /api/attachments/:id Download attachment
Projects, Folders, Tags
Method Endpoint Description
GET /api/projects List projects
POST /api/projects Create project
PATCH /api/projects/:id Update project
DELETE /api/projects/:id Delete project
GET /api/folders List folders
POST /api/folders Create folder
PATCH /api/folders/:id Update folder
DELETE /api/folders/:id Delete folder
GET /api/tags List tags
POST /api/tags Create tag
PATCH /api/tags/:id Update tag
DELETE /api/tags/:id Delete tag
Config & Infrastructure
Method Endpoint Description
GET /api/config Get current config
PATCH /api/config Update model/system prompt
POST /api/config/validate Test connection
GET /api/models List available models
GET /api/mcp/tools List MCP tools
GET /api/databases List shared databases
POST /api/databases Add shared database
DELETE /api/databases/:name Remove shared database
GET /api/browse Browse filesystem

Development

git clone https://github.com/troylar/parlor.git
cd parlor
pip install -e ".[dev]"

pytest tests/ -v          # Run tests
ruff check src/ tests/    # Lint
ruff format src/ tests/   # Format

Tech Stack

Backend Python 3.10+, FastAPI, Uvicorn
Frontend Vanilla JS, marked.js, highlight.js, KaTeX, DOMPurify
Database SQLite with FTS5 full-text search, WAL journaling
AI OpenAI Python SDK (async streaming)
MCP Model Context Protocol SDK (stdio + SSE)
Streaming Server-Sent Events
Typography Inter + JetBrains Mono (self-hosted, no external requests)

MIT License
Built for people who care about their conversations.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

parlor-0.5.0.tar.gz (634.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

parlor-0.5.0-py3-none-any.whl (641.0 kB view details)

Uploaded Python 3

File details

Details for the file parlor-0.5.0.tar.gz.

File metadata

  • Download URL: parlor-0.5.0.tar.gz
  • Upload date:
  • Size: 634.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for parlor-0.5.0.tar.gz
Algorithm Hash digest
SHA256 f8b1194c26b11cb26db893e5a27e77d0127a315c2088de54d80b974aea317890
MD5 9620319eee34c1a0e38647cde2f3e568
BLAKE2b-256 ba649521ed571544f3ea756bda76332098193d8e9125b32038f7f040acf0fde2

See more details on using hashes here.

File details

Details for the file parlor-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: parlor-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 641.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for parlor-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6cd88e751168913610ea60d78e08611899d0d9d356cdc37da9ffdbe224d8fae6
MD5 8c337250073a241a63f95f45ce02d2bf
BLAKE2b-256 8ccaba85c0fbd4aae8b49d3dabfed19c437b1a7322db3304745fa87698b9a924

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page