# Multi-Tenant ODOO MCP — Project Handoff ## Live Server - **Backend URL:** `https://odoo-mcp.thedomainnest.com/` - **Stack:** Python 3.11, FastAPI, uvicorn, SQLite, MCP (SSE transport) - **Local repo path:** `e:\MCS_Repos\nodejs_web_dev\mcp_multitenant\Multi-Tenant-ODOO-MCP` --- ## Project Structure ``` Multi-Tenant-ODOO-MCP/ ├── src/mt_odoo_mcp/ │ ├── api/routes.py # REST API endpoints (signup, login, credentials) │ ├── auth/ # Auth service, models, crypto (bcrypt + Fernet) │ ├── client/ # Odoo XML-RPC connection + RPC helpers │ ├── tools/ # 60+ MCP tools (connection, discovery, CRUD, workflow, smart) │ ├── config.py # Settings loaded from .env │ ├── server.py # FastAPI app + MCP SSE transport │ ├── database.py # SQLite init │ └── registry.py # Per-user connection manager registry ├── frontend/ # Next.js 14 frontend (see below) ├── .env # Server environment variables ├── pyproject.toml # Python dependencies └── HANDOFF.md # This file ``` --- ## What's Been Done ### Backend (Python/FastAPI) | # | Fix / Feature | File | |---|--------------|------| | ✅ | Fixed bcrypt 5.0 compatibility — replaced passlib with direct bcrypt | `auth/service.py` | | ✅ | Fixed missing `email-validator` dependency | `pyproject.toml` | | ✅ | Fixed bad config import in auth service | `auth/service.py` | | ✅ | Added `CORSMiddleware` — allows browser requests from frontend | `server.py` | | ✅ | Added `public_url` and `cors_origins` config fields | `config.py` | | ✅ | Fixed hardcoded `http://:/mcp/sse` in signup & regen-key API responses | `api/routes.py` | ### Frontend (Next.js 14) **Location:** `frontend/` | # | Page / File | Description | |---|-------------|-------------| | ✅ | Landing page | Hero, Features, How It Works, Pricing, Footer | | ✅ | Navbar | Responsive with mobile menu | | ✅ | Pricing section | 4 tiers — Starter $19, Pro $49, Agency $149, Enterprise Custom | | ✅ | Signup page | Form → API key reveal with copy-to-clipboard | | ✅ | Login page | Email + password form | | ✅ | Dashboard layout | Dark sidebar, all nav items, mobile responsive | | ✅ | Dashboard home | Stats cards, usage chart, quick actions, recent activity log | | ✅ | Odoo Connections page | List, add, and delete Odoo instances | | ✅ | MCP Endpoints page | URL + token copy buttons, Claude/Codex/Cursor setup JSON config | | ✅ | Billing page | Current plan, plan switcher, invoice history | | ✅ | Stripe Checkout API route | Creates Stripe Checkout session with 7-day trial | | ✅ | Stripe Webhook API route | Handles subscription created/updated/cancelled events | | ✅ | Typed API client | All calls wired to live backend | `frontend/src/lib/api.ts` | | ✅ | `.env.local` | Configured to point to `https://odoo-mcp.thedomainnest.com` | | ✅ | Production build | `next build` passes with zero errors | --- ## What Still Needs To Be Done ### 🔴 Critical — Must Do Before Frontend Works #### 1. Deploy backend changes to the server Three Python files were changed locally and must be pushed to the server: - `src/mt_odoo_mcp/server.py` - `src/mt_odoo_mcp/config.py` - `src/mt_odoo_mcp/api/routes.py` **Add these 2 lines to the server `.env` file:** ```env PUBLIC_URL=https://odoo-mcp.thedomainnest.com CORS_ORIGINS=http://localhost:3000,https://YOUR-FRONTEND-DOMAIN.com ``` Then restart the service: ```bash # whichever process manager is used on the server: systemctl restart odoo-mcp # or pm2 restart odoo-mcp ``` #### 2. Change SECRET_KEY on the server The current `SECRET_KEY` in `.env` is still the default placeholder — this is a security risk. ```env SECRET_KEY= ``` --- ### 🟡 Stripe Integration #### 3. Create Stripe products and prices In the Stripe Dashboard → Products, create 3 recurring monthly products: | Product | Price | |---------|-------| | Starter | $19/month | | Pro | $49/month | | Agency | $149/month | Copy the `price_xxx` IDs and fill in `frontend/.env.local`: ```env NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_... STRIPE_SECRET_KEY=sk_live_... STRIPE_WEBHOOK_SECRET=whsec_... STRIPE_PRICE_STARTER=price_... STRIPE_PRICE_PRO=price_... STRIPE_PRICE_AGENCY=price_... ``` #### 4. Add subscription fields to the backend users table Add these columns to the SQLite `users` table: ```sql ALTER TABLE users ADD COLUMN plan TEXT DEFAULT 'free'; ALTER TABLE users ADD COLUMN subscription_status TEXT DEFAULT 'inactive'; ALTER TABLE users ADD COLUMN stripe_customer_id TEXT; ``` Add a new API endpoint `PATCH /api/admin/subscription` (internal, called by the webhook) that updates these fields when Stripe confirms payment. #### 5. Wire Stripe webhook to backend The webhook handler at `frontend/src/app/api/stripe/webhook/route.ts` already parses Stripe events. Add a `fetch()` call inside the switch cases to hit the backend endpoint from step 4. #### 6. Gate MCP access on subscription status In `server.py`, inside the `/mcp/sse` endpoint, after the user is looked up, add a check: ```python if user.subscription_status not in ('active', 'trialing'): raise HTTPException(status_code=403, detail="Active subscription required.") ``` --- ### 🟢 Remaining Dashboard Pages | Page | Route | Description | |------|-------|-------------| | AI Setup Guides | `/dashboard/guides` | Step-by-step setup for Claude, Codex, Cursor, Windsurf | | Tools & Permissions | `/dashboard/tools` | Toggle which Odoo tools are enabled per module | | Usage | `/dashboard/usage` | Detailed usage graphs with date range filter | | Logs | `/dashboard/logs` | Activity log table with search and filters | | API Tokens | `/dashboard/tokens` | View key prefix, rotate API key button | | Team | `/dashboard/team` | Invite team members (needs backend multi-user support) | | Settings | `/dashboard/settings` | Change password, account preferences | --- ### 🟢 Deploy Frontend ```bash cd frontend npm install -g vercel vercel --prod ``` - Set all env vars from `frontend/.env.local` inside Vercel project settings - After deploy, add the Vercel domain to `CORS_ORIGINS` in the server `.env` and restart --- ## How to Run Locally ### Backend (already running on server — skip if not developing backend) ```bash pip install -e . cp .env.example .env # fill in values python -m mt_odoo_mcp ``` ### Frontend ```bash cd frontend npm install npm run dev # → http://localhost:3000 # API calls go to https://odoo-mcp.thedomainnest.com ``` --- ## API Reference (Backend) | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | `GET` | `/health` | None | Health check | | `POST` | `/api/signup` | None | Create account, returns API key | | `POST` | `/api/login` | None | Verify credentials | | `GET` | `/api/me` | Bearer | Current user + Odoo instances | | `POST` | `/api/api-key/regenerate` | Bearer | Rotate API key | | `POST` | `/api/credentials` | Bearer | Add/update Odoo instance | | `GET` | `/api/credentials` | Bearer | List Odoo instances | | `DELETE` | `/api/credentials/{name}` | Bearer | Remove Odoo instance | | `GET` | `/mcp/sse` | Bearer | MCP SSE connection (used by AI clients) | **Auth header format:** `Authorization: Bearer mtom_xxxxx...` --- ## MCP Client Config (Claude Code / Claude Desktop) ```json { "mcpServers": { "odoo-mcp": { "type": "sse", "url": "https://odoo-mcp.thedomainnest.com/mcp/sse", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } } ``` Or via CLI: ```bash claude mcp add --transport sse odoo-mcp https://odoo-mcp.thedomainnest.com/mcp/sse \ -H "Authorization: Bearer YOUR_API_KEY" ``` --- ## Implementation Priority for Colleague 1. **Deploy backend changes + update `.env` on server → restart** ← unblocks everything 2. **Test signup → dashboard → add Odoo connection** end to end 3. **Set up Stripe**, fill in price IDs in `frontend/.env.local` 4. **Add subscription columns** to SQLite + `/api/admin/subscription` endpoint 5. **Wire webhook** to backend endpoint 6. **Deploy frontend** to Vercel 7. **Build remaining dashboard pages** (guides, tools, usage, logs, tokens, settings)