Content
<div align="center">
<img src="addin/resources/icon-trimmed.png" alt="JMP Expert" width="128">
</div>
# JMP Expert
> AI-powered JMP expertise — directly in your JMP desktop interface.
[](https://github.com/jtcole/jmp-mcp-expert-system/releases/tag/v1.3.0)
[](https://www.jmp.com/)
[](https://www.python.org/)
[](https://www.djangoproject.com/)
[](LICENSE)
**JMP Expert** is a JMP add-in that brings AI-powered JMP expertise into your desktop workflow. Ask questions about JMP features, generate JSL scripts from natural language, and get instant source-backed answers — all without leaving JMP.
---
## Features
| Capability | Authenticated | BYO-LLM | Demo |
|:---|:---:|:---:|:---:|
| Source-backed Q&A (RAG) | ✓ | ✓ | ✓ |
| Natural Language → JSL | ✓ | ✓ | ✓ |
| Data Table Context Aware | ✓ | ✓ | ✓ |
| Streaming Responses | ✓ | ✓ | ✓ |
| Persistent Chat History | ✓ | — | — |
| Custom Model Selection | — | ✓ | — |
| Rate Limited | — | — | ✓ |
### Three Authentication Modes
- **Authenticated** — Full-featured access with persistent session history and `gpt-4o` by default. No rate limits.
- **BYO-LLM** — Bring your own OpenAI API key. Uses your key in-memory only (never stored server-side). Override the model via `X-Model` header.
- **Demo** — Try it free with no key required. Uses `gpt-4o-mini` with tiered rate limiting.
### What It Can Do
- **Ask anything JMP** — Statistical methods, DOE, scripting, graphing, data management
- **Generate JSL** — Describe what you need and get working JSL code back, with awareness of your open data table
- **Source-backed answers** — Every response includes citations to official JMP documentation
- **Quick queries** — Hit `Ctrl+Shift+J` (Windows) or `Cmd+Shift+J` (Mac) for instant access
---
## Architecture
```
┌─────────────────────────────────┐
│ JMP Add-In / Web App │
│ User sends request │
│ X-API-Key header │
│ X-Model header │
└───────────────┬─────────────────┘
│
▼
╔═══════════════════════════╗
║ @api_key_or_demo ║
║ Key prefix? ║
╚═══╤═══════╤═══════╤═════╝
│ │ │
jmp_live_ sk- (none)
│ │ │
▼ ▼ ▼
┌────────┐┌────────┐┌──────────────┐
│ AUTH ││BYO-LLM ││ DEMO │
│ gpt-4o ││gpt-4o ││ gpt-4o-mini │
│no limit││no limit││ rate limited│
└───┬────┘└───┬────┘└──────┬───────┘
│ │ │
│ │ ┌─────▼──────┐
│ │ │3-Tier Rate │
│ │ │ Limiting │
│ │ │ • 10/hr/IP │
│ │ │ • 500/day │
│ │ │ • 50/hr/24 │
│ │ └─────┬──────┘
│ │ │
└─────────┼────────────┘
▼
┌───────────────────┐
│ Django Backend │
│ stream_rag() │
│ openai_client.py │
│ RAG (20 docs, │
│ 6,392 chunks) │
└───────────────────┘
```
### Request Flow
```
User Add-In @decorator Django OpenAI RAG
│ │ │ │ │ │
│── question ──▶│ │ │ │ │
│ │─ POST /chat ─▶ │ │ │
│ │ +X-API-Key │ │ │ │
│ │ +X-Model │ │ │ │
│ │ │ │ │ │
│ │ ┌───────┴───────┐ │ │ │
│ │ │ Auth check │ │ │ │
│ │ │ • jmp_live_: │ │ │ │
│ │ │ const-time │ │ │ │
│ │ │ • sk-: BYO-LLM│ │ │ │
│ │ │ • none: demo │ │ │ │
│ │ │ +rate check │ │ │ │
│ │ └───────┬───────┘ │ │ │
│ │ │─ pass ─────▶ │ │
│ │ │ │ │ │
│ │ │ │── query ───▶ │
│ │ │ │◀─ chunks ───│ │
│ │ │ │ │ │
│ │ │ │── prompt ──▶ │
│ │ │ │◀─ SSE ─────│ │
│ │ │ │ │ │
│ │◀──── SSE stream ──────────│ │ │
│◀─ answer ────│ │ │ │ │
```
---
## Installation
### Requirements
- **JMP 17 or later**
- macOS or Windows
### Install the Add-In
1. Download [`JMPExpert-1.3.0.jmpaddin`](https://github.com/jtcole/jmp-mcp-expert-system/releases/tag/v1.3.0)
2. In JMP, go to **File → Open**
3. Select the `.jmpaddin` file
4. Click **Install** when prompted
5. JMP Expert appears in the **Add-Ins** menu
### Keyboard Shortcut
| OS | Shortcut |
|:---|:---|
| Windows | `Ctrl+Shift+Q` |
| macOS | `Cmd+Shift+Q` |
---
## Configuration
### BYO-LLM Setup
Use your own OpenAI API key to bypass demo rate limits and choose your model:
1. In JMP, go to **Add-Ins → JMP Expert → Configure LLM**
2. Enter your OpenAI API key (starts with `sk-`)
3. Optionally override the model (e.g., `gpt-4-turbo`, `gpt-4o`)
4. Click **Save**
Your key is stored **locally** in JMP preferences — it is never sent to the JMP Expert server except in the `X-API-Key` header of each request, and the server uses it in-memory only. No logging, no persistence, no storage.
### Authenticated Mode
If you have a JMP-issued API key (`jmp_live_` prefix), enter it the same way. Authenticated mode unlocks persistent chat history and removes all rate limits.
---
## API Reference
### Primary Endpoints
| Method | Path | Purpose |
|:---|:---|:---|
| `GET` | `/api/jmp-expert/status/` | Service status, mode, rate limits, usage stats |
| `POST` | `/api/jmp-expert/chat/` | Chat with SSE streaming and RAG |
| `POST` | `/api/jmp-expert/generate-jsl/` | Natural language → JSL script |
**Authentication:** `X-API-Key` header (required for non-demo; optional for demo mode)
### Demo Backward Compatibility
| Method | Path | Purpose |
|:---|:---|:---|
| `POST` | `/api/jmp-expert/demo/auth/` | Token-based demo authentication |
| `GET` | `/api/jmp-expert/demo/library/` | Read-only document library |
| `POST` | `/api/jmp-expert/demo/chat/` | Demo Q&A |
| `POST` | `/api/jmp-expert/demo/generate-jsl/` | Demo JSL generation |
| `GET` | `/api/jmp-expert/demo/session/` | Demo session history |
### Web Application
| Method | Path | Purpose |
|:---|:---|:---|
| `POST` | `/api/jmp-expert/web/chat/` | Full RAG chat (login required) |
| `GET` | `/api/jmp-expert/web/chat/sessions/` | List sessions |
| `GET` | `/api/jmp-expert/web/chat/sessions/{id}/` | Session detail |
| `POST` | `/api/jmp-expert/web/chat/sessions/{id}/delete/` | Delete session |
| `POST` | `/api/jmp-expert/web/chat/messages/{id}/show-me/` | Generate JSL follow-up |
| `POST` | `/api/jmp-expert/web/chat/messages/{id}/show-me-in-jmp/` | Generate + execute JSL in JMP |
### Document Management
| Method | Path | Purpose |
|:---|:---|:---|
| `GET` | `/api/jmp-expert/documents/` | List user's documents |
| `GET` | `/api/jmp-expert/documents/library/` | All indexed documents |
| `POST` | `/api/jmp-expert/documents/upload/` | Upload PDF |
| `GET` | `/api/jmp-expert/documents/{id}/` | Document detail |
| `POST` | `/api/jmp-expert/documents/{id}/delete/` | Delete document |
| `GET` | `/api/jmp-expert/documents/{id}/pdf/` | Serve original PDF |
| `POST` | `/api/jmp-expert/documents/{id}/reindex/` | Re-process document |
---
## Security
| Concern | Mitigation |
|:---|:---|
| Timing attacks on API key comparison | `hmac.compare_digest` — constant-time, byte-by-byte |
| OpenAI key exposure in logs | Never stored, logged, or persisted (in-memory per request) |
| X-Forwarded-For spoofing | Trust first entry only |
| Rate limit bypass via IP rotation | 3-tier detection includes `/24` subnet blocking |
| Demo mode accessing `gpt-4o` | Explicit model pin to `gpt-4o-mini` in decorator; cannot be overridden |
| CSRF on API endpoints | Token-based authentication replaces CSRF (`@csrf_exempt` on API views) |
| Error message information leakage | Sanitized production error responses; exceptions logged server-side only |
| Input injection | Question/task length capped at 4,000 chars; session keys max 128 chars; all DB access via ORM |
---
## Development
### Prerequisites
- Python 3.10+
- Django 5.x
- An OpenAI API key (or access to a compatible endpoint)
### Local Setup
```bash
# Clone the repository
git clone https://github.com/jtcole/jmp-mcp-expert-system.git
cd jmp-mcp-expert-system
# Create and activate a virtual environment
python3 -m venv env
source env/bin/activate
# Install dependencies
pip install -e ".[dev]"
# Run core tests
python3 -m unittest discover -s tests -t . -p 'test_*.py'
# Run the browser UI (standalone)
python3 scripts/run_web_ui.py
# Open http://127.0.0.1:8765/
# Run the MCP stdio server
python3 scripts/run_mcp_stdio_server.py
# Run the walkthrough example
python3 examples/walkthrough/01_support_session.py
```
### Project Structure
```
├── addin/ # JMP Add-In package
│ ├── addin.def # Add-in metadata (v1.3.0)
│ ├── addin.jmpcust # Menu definitions
│ ├── jmp_expert.jsl # JSL bridge functions
│ └── dist/ # Built .jmpaddin packages
├── agent/ # Orchestrator & response generation
│ └── orchestrator.py
├── core/ # MCP, constitution, PKM, spec-engine primitives
├── modules/ # JMP support tool definitions
│ └── jmp_support_tools/
├── web/ # Headless browser UI server
├── docs/ # Architecture, diagrams, source docs
│ └── sources/ # Curated JMP documentation
├── scripts/ # Sync scripts, run scripts
├── tests/ # Unit test suite
├── examples/ # Walkthrough examples
└── spec/ # JMP expert assistant specification
```
### Building the Add-In
```bash
cd addin
./build_addin.sh
# Output: dist/JMPExpert-1.3.0.jmpaddin
```
---
## Links
- [Download v1.3.0](https://github.com/jtcole/jmp-mcp-expert-system/releases/tag/v1.3.0) — Latest JMP add-in release
- [Live Demo](https://codingenvironment.com) — Try the web app
- [MCP/DSPy Book](https://leanpub.com/mcp-dspy) — The MCP architecture that inspired this project
- [JMP Official Documentation](https://www.jmp.com/support/help/) — Source of the knowledge base
---
## License
MIT © [Cole](https://github.com/jtcole)
Connection Info
You Might Also Like
Train-in-Silence
The first Task-Aware MCP server and automated VRAM calculator for LLM...
stacklit
108,000 lines of code. 4,000 tokens of index. One command makes any repo...
AppClaw
AI-powered mobile automation agent — describe what you want in plain...
pdf-mcp
Production-ready MCP server for PDF processing with intelligent caching....
kotadb
Local-only code intelligence API for AI developer workflows (Bun +...
gemini-api-docs-mcp
A remote HTTP MCP server for searching Google Gemini API documentation.