Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 104 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@

**The AI operations stack for Rev A Manufacturing.**

One monorepo. One Railway deploy. One MCP endpoint. Three systems working together:

- **REVA-TURBO plugin** — 46 skills that run inside Claude Code for every PM workflow at Rev A (RFQ → quote → China sourcing → compliance → quality → shipping).
- **Nakatomi CRM** (internal) — headless AI-native CRM, Postgres-backed, customized for Rev A's pipeline and custom fields.
- **AutoMem** (internal) — hybrid graph + vector memory (FalkorDB + Qdrant) for durable team-wide knowledge.

A thin **MCP router** is the only publicly exposed service. It speaks the Model Context Protocol to agents and proxies internally to the CRM + memory backends. One URL, one bearer token, one connector config — that's what the plugin and Claude Desktop / Cursor need to know.
One monorepo. One Railway deploy. One MCP endpoint. Three systems working
together:

- **REVA-TURBO plugin** — 48 skills that run inside Claude Code / Claude
Desktop for every PM workflow at Rev A (RFQ → quote → China sourcing →
compliance → quality → shipping).
- **Nakatomi CRM** (internal) — headless AI-native CRM, Postgres-backed,
customized for Rev A's pipeline and custom fields.
- **AutoMem** (internal) — hybrid graph + vector memory (FalkorDB + Qdrant)
for durable team-wide knowledge.

A thin **MCP router** is the only publicly exposed service. It speaks the
Model Context Protocol to agents and proxies internally to the CRM and
memory backends. One URL, one bearer token, one connector config — that's
what the plugin and Claude Desktop / Cursor need to know.

```mermaid
flowchart LR
Plugin["REVA-TURBO plugin<br/>(~/.claude/skills/reva-turbo)"]
Plugin["REVA-TURBO plugin<br/>(~/.claude/plugins/reva-turbo)"]
Claude["Claude Desktop / Cursor"]
subgraph Railway["Single Railway project"]
Router["mcp-router<br/>(public /mcp)"]
Expand All @@ -21,8 +29,8 @@ flowchart LR
PG[("Postgres")]
Falkor[("FalkorDB")]
Qdrant[("Qdrant")]
Router -- "crm.*" --> Nakatomi
Router -- "mem.*" --> AutoMem
Router -- "crm_*" --> Nakatomi
Router -- "mem_*" --> AutoMem
Nakatomi --> PG
AutoMem --> Falkor
AutoMem --> Qdrant
Expand All @@ -35,48 +43,68 @@ flowchart LR

```
RevOps-RevAMfg/
├── plugin/ ← REVA-TURBO Claude Code plugin (46 skills, 20 commands)
│ ├── skills/
│ ├── bin/
│ ├── install.sh ← one-liner plugin installer
│ └── .claude-plugin/
├── plugin/ ← REVA-TURBO Claude plugin (48 skills)
│ ├── skills/ ← one directory per skill (SKILL.md + assets)
│ ├── bin/ ← telemetry, session-track, config helpers
│ ├── setup ← post-install bootstrap
│ ├── install.sh ← curl-able CLI installer (legacy path)
│ ├── build-bundle.sh ← builds dist/reva-turbo-<ver>.zip
│ ├── .claude-plugin/
│ │ └── plugin.json ← manifest + userConfig prompts + mcpServers
│ └── dist/ ← built zips (gitignored; shipped via Releases)
├── services/
│ ├── mcp-router/ ← single unified MCP endpoint (FastAPI + FastMCP)
│ ├── nakatomi-backend/ ← Nakatomi CRM (vendored-by-reference, Rev A seed overlay)
│ └── automem-backend/ ← AutoMem memory (vendored-by-reference)
│ ├── mcp-router/ ← unified MCP endpoint (FastAPI + FastMCP)
│ ├── nakatomi-backend/
│ │ └── seed/reva.py ← Rev A pipeline + custom-field overlay
│ └── automem-backend/ ← AutoMem is vendored-by-reference via Railway
├── railway/
│ ├── template.yaml ← one-click Railway template (1 project, 3 services + 3 plugins)
│ ├── deploy.sh ← CLI deploy for MrDula Solutions admins
│ └── README.md
│ ├── deploy.sh ← phased deploy (init/services/seed/finalize)
│ ├── template.yaml ← reference stack spec (not executable)
│ └── README.md ← deploy reference
└── docs/
├── ARCHITECTURE.md
├── INSTALL.md
└── ROADMAP.md
├── ARCHITECTURE.md, ARCHITECTURE_V2.md, AUTH.md, INSTALL.md, ROADMAP.md
```

## For end users (Rev A PMs)

Your admin deploys the backend once and shares two things with you: the **router URL** (e.g. `https://reva-ops.up.railway.app/mcp`) and a one-time **signup token**. From there it's three steps — no terminal needed.
Your admin deploys the backend once and shares two things with you: the
**router URL** (e.g. `https://mcp-router-production-460a.up.railway.app/mcp`)
and a one-time **signup token**. From there it's three steps — no terminal
needed.

**1. Get your personal API key.** Visit `https://<router>.up.railway.app/signup` in your browser. Enter your name, work email, a password (12+ chars — only used for future key resets), and the signup token. The page shows your `nk_...` key once. Copy it.
**1. Get your personal API key.** Visit `<router-url-without-/mcp>/signup`
in your browser. Enter your name, work email, a password (12+ chars — only
used for future key resets), and the signup token. The page shows your
`nk_...` key once. Copy it.

**2. Download the plugin bundle.** Grab the latest `reva-turbo-<version>.zip` from the project's [GitHub Releases](https://github.com/mrdulasolutions/RevOps-RevAMfg/releases) page.
**2. Download the plugin bundle.** Grab the latest `reva-turbo-<version>.zip`
from the project's [GitHub Releases](https://github.com/mrdulasolutions/RevOps-RevAMfg/releases)
page. (The zip contains a single top-level `reva-turbo/` directory — don't
unzip it before upload.)

**3. Upload it into Claude.** In Claude Desktop, open **Plugins → Personal → Local uploads → `+`** and drop in the zip. On enable, Claude prompts for two values:
**3. Upload it into Claude Desktop.** Open **Plugins → Personal → Local
uploads → `+`** and drop in the zip. On enable, Claude prompts for two
values:

- **`mcp_url`** — paste the router URL your admin shared (the full `/mcp` form)
- **`api_key`** — paste the `nk_...` key from step 1 (stored in your OS keychain — not a plaintext file)
- **`mcp_url`** — the router URL your admin shared (the full `/mcp` form)
- **`api_key`** — the `nk_...` key from step 1 (stored in your OS keychain,
not a plaintext file)

That's it. Run `/reva-turbo:revmyengine` and the engine is connected to the shared CRM and memory. Everything you log is available to the whole team, and every action is attributed to your user on the Nakatomi timeline.
That's it. Run `/reva-turbo:revmyengine` and the engine is connected to the
shared CRM and memory. Everything you log is available to the whole team,
and every action is attributed to your user on the Nakatomi timeline.

> Prefer the terminal? The legacy `install.sh` path still works:
> Prefer the terminal? The legacy CLI path still works for Claude Code
> users:
> ```bash
> curl -fsSL https://raw.githubusercontent.com/mrdulasolutions/RevOps-RevAMfg/main/plugin/install.sh \
> | REVA_MCP_URL=https://<router>.up.railway.app/mcp bash
> ```
> It drops into the same signup wizard and writes `~/.claude/mcp.json` directly. Useful for Claude Code CLI users or CI.
> It drops into the same signup wizard and writes `~/.claude/mcp.json`
> directly.

See [`docs/AUTH.md`](./docs/AUTH.md) for the full auth flow and rotation story.
See [`docs/AUTH.md`](./docs/AUTH.md) for the full auth flow and rotation
story.

## For admins (MrDula Solutions)

Expand All @@ -86,41 +114,63 @@ Deploy the backend for a new customer:
git clone https://github.com/mrdulasolutions/RevOps-RevAMfg.git
cd RevOps-RevAMfg
./railway/deploy.sh --project-name reva-ops --admin-email you@reva.com
# → prints public MCP URL + admin API key
# → prints public MCP URL + admin API key + signup token
```

One Railway project. Three application services (`mcp-router`, `nakatomi-backend`, `automem-backend`). Three managed databases (Postgres, FalkorDB, Qdrant). Wired up automatically via Railway's private network — only `mcp-router` has a public domain.
One Railway project. Three application services (`mcp-router`,
`nakatomi-backend`, `automem-backend`). Three managed databases (Postgres,
FalkorDB, Qdrant). Wired up automatically via Railway's private network —
only `mcp-router` has a public domain.

See [`railway/README.md`](./railway/README.md) for the full deploy story.
The deploy is phased (`init` / `services` / `seed` / `finalize`), so any
individual phase can be re-run if something fails mid-flight. See
[`railway/README.md`](./railway/README.md) for the full story, including
the one-time Railway GitHub App install flow.

## Why one MCP endpoint

Two reasons we run a router instead of exposing Nakatomi's `/mcp` and AutoMem's `/mcp` separately:
Two reasons we run a router instead of exposing Nakatomi's `/mcp` and
AutoMem's `/mcp` separately:

1. **One connector config, not two.** Every MCP client (Claude Desktop, Cursor, the plugin) has to be pointed at every endpoint by hand. Doubling the connector count doubles the onboarding friction for a PM team.
2. **Cross-system tools.** "Remember this ITAR ruling and tag it to Acme's contact" is a memory write *and* a CRM link. A router owns that orchestration (`reva_remember_about_entity`); two isolated MCPs cannot.
1. **One connector config, not two.** Every MCP client (Claude Desktop,
Cursor, the plugin) has to be pointed at every endpoint by hand.
Doubling the connector count doubles the onboarding friction for a PM
team.
2. **Cross-system tools.** "Remember this ITAR ruling and tag it to Acme's
contact" is a memory write *and* a CRM link. A router owns that
orchestration (`reva_remember_about_entity`); two isolated MCPs cannot.

Tool namespaces keep the surface tidy:

| Prefix | Backend | Examples |
|--------|----------|----------------------------------------------------------|
| `crm_` | Nakatomi | `crm_search_contacts`, `crm_create_deal`, `crm_move_deal_stage` |
| `mem_` | AutoMem | `mem_store`, `mem_recall`, `mem_associate` |
| `reva_`| router | `reva_remember_about_entity`, `reva_recall_for_entity` |
| Prefix | Backend | Examples |
|---------|----------|------------------------------------------------------------------|
| `crm_` | Nakatomi | `crm_search_contacts`, `crm_create_deal`, `crm_move_deal_stage` |
| `mem_` | AutoMem | `mem_store`, `mem_recall`, `mem_associate` |
| `reva_` | router | `reva_remember_about_entity`, `reva_recall_for_entity` |

## Rev A customizations

Delivered as overlays, not forks:
Delivered as overlays, not forks. Applied automatically by `railway/deploy.sh`
phase 3 (`seed`):

- **Pipeline** — `Manufacturing RFQ` with 12 stages (RFQ Received → Qualified → Quoted → Accepted → In Manufacturing → Inspection (G2) → Repackage → Shipped → Delivered → Invoiced → Paid → Closed Lost)
- **Custom fields** — `company.compliance`, `company.partner_scorecard`, `deal.quality_gates`, `deal.ncrs`, `deal.part_numbers`, `contact.role`
- **Memory taxonomy** — `reva/rfq`, `reva/quality`, `reva/compliance`, `reva/china-source`, `reva/partner-scorecard`, …
- **Pipeline — `Manufacturing RFQ`** (12 stages): RFQ Received → Qualified
→ Quoted → Accepted → In Manufacturing → Inspection (G2) → Repackage →
Shipped → Delivered → Invoiced → Paid (won) → Closed Lost.
- **Custom fields** (8 total): `company.partner_scorecard`,
`company.compliance`, `company.region`, `contact.role`,
`deal.quality_gates`, `deal.ncrs`, `deal.part_numbers`,
`deal.china_source`. JSON-shaped payloads ride as `text` because
Nakatomi's custom-field schema is scalar-only.
- **Memory taxonomy** — `reva/rfq`, `reva/quality`, `reva/compliance`,
`reva/china-source`, `reva/partner-scorecard`, `reva/ncr`,
`reva/shipping`, `reva/itar`.

All defined in [`services/nakatomi-backend/seed/reva.py`](./services/nakatomi-backend/seed/reva.py) and applied automatically by `railway/deploy.sh`.
All defined in [`services/nakatomi-backend/seed/reva.py`](./services/nakatomi-backend/seed/reva.py).

## Documentation

- [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md) — component layout, data flow, hook system
- [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md) / [`docs/ARCHITECTURE_V2.md`](./docs/ARCHITECTURE_V2.md) — component layout, data flow, hook system
- [`docs/AUTH.md`](./docs/AUTH.md) — signup / rotation story
- [`docs/INSTALL.md`](./docs/INSTALL.md) — plugin install reference (env overrides, offline, troubleshooting)
- [`docs/ROADMAP.md`](./docs/ROADMAP.md) — what's shipped, what's next
- [`plugin/CLIENT.md`](./plugin/CLIENT.md) — Rev A Manufacturing company profile
Expand All @@ -131,4 +181,6 @@ All defined in [`services/nakatomi-backend/seed/reva.py`](./services/nakatomi-ba

---

Built by [MrDula Solutions](https://mrdulasolutions.com) for Rev A Manufacturing. Powered by Claude Code, [Nakatomi](https://github.com/mrdulasolutions/NakatomiCRM), and [AutoMem](https://github.com/mrdulasolutions/automem).
Built by [MrDula Solutions](https://mrdulasolutions.com) for Rev A
Manufacturing. Powered by Claude, [Nakatomi](https://github.com/mrdulasolutions/NakatomiCRM),
and [AutoMem](https://github.com/mrdulasolutions/automem).
27 changes: 7 additions & 20 deletions plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "reva-turbo",
"version": "2.0.0",
"description": "REVA-TURBO Skills Engine — Rev A Manufacturing PM workflow from RFQ intake through customer delivery. 46 skills covering quoting, China sourcing, compliance, quality, and fulfillment.",
"version": "2.1.1",
"description": "REVA-TURBO Skills Engine — Rev A Manufacturing PM workflow from RFQ intake through customer delivery. 48 skills + zero-friction onboarding: PM pastes their nk_… key in chat, plugin wires up the router automatically (no Settings UI hunting). Covers quoting, China sourcing, compliance, quality, and fulfillment.",
"author": {
"name": "Rev A Manufacturing / MrDula Solutions",
"url": "https://github.com/mrdulasolutions"
Expand Down Expand Up @@ -55,27 +55,14 @@
},
"requirements": {
"shell": "bash >= 4",
"optional": {
"node": ">= 18 (for docx report generation)"
}
},
"userConfig": {
"mcp_url": {
"description": "REVA MCP router URL (from your admin). Example: https://reva-ops.up.railway.app/mcp",
"sensitive": false
},
"api_key": {
"description": "Your personal REVA API key (nk_...). Get one at <mcp_url minus /mcp>/signup using the signup token your admin shared.",
"sensitive": true
}
"node": ">= 18 (required — mcp-remote bridges plugin stdio MCP to the HTTP router)"
},
"mcpServers": {
"reva": {
"type": "http",
"url": "${user_config.mcp_url}",
"headers": {
"Authorization": "Bearer ${user_config.api_key}"
}
"command": "bash",
"args": [
"${CLAUDE_PLUGIN_ROOT}/bin/reva-mcp-launch.sh"
]
}
}
}
2 changes: 1 addition & 1 deletion plugin/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.0.0
2.1.1
47 changes: 47 additions & 0 deletions plugin/bin/reva-mcp-launch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env bash
# reva-mcp-launch.sh — stdio MCP launcher for the REVA-TURBO plugin.
#
# Claude Desktop spawns this on startup as the `reva` MCP server. It bridges
# Desktop's stdio transport to the Rev A MCP router over HTTP via the
# `mcp-remote` npm helper.
#
# Why a launcher (and not `${user_config.*}` substitution directly in
# plugin.json like a normal plugin): non-technical PMs don't want to
# navigate Plugins → Settings in Desktop to paste a URL and a key. With
# a launcher, the revmyengine skill can write the creds to a file on
# disk after the PM pastes their `nk_...` key into chat, and Desktop
# re-picks them up on the next app start. One paste, one restart — no
# Settings hunting.
#
# Credential precedence (first match wins):
# 1. $REVA_MCP_URL / $REVA_API_KEY in the environment (CI / advanced)
# 2. ~/.reva-turbo/state/mcp-credentials.env (written by the skill)
# 3. Baked-in production default URL (key must still come from 1 or 2)
#
# If no api_key is found, we exec mcp-remote with an empty bearer token.
# The router returns 401 on initialize, Desktop shows the server as
# errored, and the revmyengine preflight catches it and walks the PM
# through the paste flow. This is the right failure mode — loud enough
# that revmyengine notices, quiet enough not to scare the PM.
set -u

CRED_FILE="${REVA_CRED_FILE:-$HOME/.reva-turbo/state/mcp-credentials.env}"

# Load creds file if present. `set -a` exports everything it defines.
if [ -f "$CRED_FILE" ]; then
set -a
# shellcheck disable=SC1090
. "$CRED_FILE"
set +a
fi

# Fall back to the Rev A production router if the PM hasn't overridden it.
# The /mcp suffix matches the router's mount point in services/mcp-router.
: "${REVA_MCP_URL:=https://mcp-router-production-460a.up.railway.app/mcp}"
: "${REVA_API_KEY:=}"

# Hand off to mcp-remote. `-y` bypasses the npx prompt, which would hang
# Desktop's stdio transport waiting for a y/n that never comes.
exec npx -y mcp-remote \
"$REVA_MCP_URL" \
--header "Authorization: Bearer ${REVA_API_KEY}"
Loading
Loading