Skip to main content
Glama
babuvenky76

Wealth Management MCP

by babuvenky76
README.md
# Wealth Management MCP

A standalone Model Context Protocol (MCP) server for **wealth management**: portfolio health analysis, rebalance simulation, and trade execution. Built with [NitroStack](https://nitrostack.ai) so you can run this module independently or integrate it into larger AI-assisted workflows.

---

## Summary

This server exposes a single MCP tool, `wealth_management`, with four actions: **list_customers** (dashboard of sample customers), **health_analysis**, **simulate_rebalance**, and **execute_rebalance**. It connects to MongoDB (local or Atlas) for portfolio data, supports optional JSON schema validation on the portfolios collection, and demonstrates guards, caching, rate limiting, and event handling. Ideal for advisors, dashboards, or AI agents that need portfolio insights and rebalance workflows.

---

## Tech Stack

| Layer        | Technology |
|-------------|------------|
| Runtime     | Node.js 18+ |
| Language    | TypeScript (ESM) |
| Framework   | NitroStack (MCP) |
| Database    | MongoDB 7 (local or Atlas) |
| Validation  | Zod |
| Config      | dotenv, `.env` |

---

## Business Pain Point

Advisors and operations teams need to:

- Quickly assess portfolio health and drift from target allocation.
- Simulate rebalance trades before executing.
- Execute rebalances with proper controls (clearance, rate limits).

Manual workflows and scattered tools make this slow and error-prone. This module delivers a single, AI-friendly API so assistants and dashboards can drive the full flow from analysis to execution.

---

## Why NitroStack

- **One tool, multiple actions** — Single `wealth_management` tool with `action` parameter; less surface area for clients and canvas limits.
- **Guards & rate limiting** — Manager clearance and throttling on `execute_rebalance`; health/simulate remain self-serve.
- **Caching** — Cached health results to avoid repeated DB hits.
- **Events** — `trade.executed` emission for downstream systems (e.g. audit, notifications).
- **Minimal boilerplate** — Focus on domain logic; NitroStack handles MCP protocol, validation, and wiring.

---

## Solution Architecture

```
┌─────────────────┐     stdio / MCP      ┌──────────────────┐
│  Client (Studio, │ ◄──────────────────► │  Wealth Mgmt MCP │
│  AI, Dashboard)  │                      │  (this server)   │
└─────────────────┘                      └────────┬─────────┘
                                                  │
                      ┌───────────────────────────┼───────────────────────────┐
                      │                           │                           │
                      ▼                           ▼                           ▼
              wealth_management             DatabaseService              Events
              (health_analysis,             (MongoDB: local              (trade.executed)
               simulate_rebalance,           or Atlas)
               execute_rebalance)
```

- **Tools:** `wealth_management` — actions: `list_customers`, `search_customers` (MongoDB full-text), `health_analysis`, `simulate_rebalance`, `execute_rebalance`; `clientId` required for the last three.
- **Data:** MongoDB; connection prefers `MONGODB_ATLAS_URI` when set, else `MONGODB_URI`.
- **Seeding:** `npm run seed:portfolios` creates the `portfolios`, `governing_rules`, and `search_synonyms` collections and a **text index** on `portfolios` for search.

### MongoDB search (customer dashboard)

The customer dashboard uses MongoDB’s **full-text and aggregation** features via the `search_customers` action:

| Feature | MongoDB usage |
|--------|----------------|
| **Full-text search** | `$text: { $search: query }` on a **text index** (`clientName`, `clientId`). |
| **Relevance scoring** | `$meta: "textScore"` in aggregation; results sorted by score. |
| **Synonym support** | `search_synonyms` collection maps terms (e.g. `agg` → `aggressive`); query is expanded before `$search`. |
| **Autocomplete** | Optional `autocompletePrefix` with `$regex: ^prefix` on `clientName` and `clientId`. |
| **Faceted search** | `$facet` aggregation returns result set plus **facet counts** by `riskProfile` and `currency`. |
| **Highlighting** | API returns `searchTerms`; the widget highlights matching terms in the result list. |

Spell correction (e.g. fuzzy matching) is available with **MongoDB Atlas Search**; this module uses the core server text index and synonym expansion. Run `npm run seed:portfolios` to create the text index and seed synonyms.

### Governing rules (HNI policy)

Recommendations and rebalance suggestions follow **organizational governing rules** stored in the `governing_rules` collection. These policies ensure the wealth analyzer stays within firm guardrails for HNIs:

| Rule type | Purpose |
|-----------|--------|
| **Rebalance threshold (%)** | Only recommend rebalancing when drift from target exceeds this (e.g. 5%); avoids churn. |
| **Minimum trade size (%)** | Do not suggest trades that move less than this % of portfolio. |
| **Single-position concentration cap (%)** | No single position may exceed this % (e.g. 25%). |
| **Asset-class bounds** | Min/max allocation per category (equity, fixed-income, cash, alternative) by risk profile (conservative, balanced, aggressive). |

Health analysis and rebalance simulation both use these rules: recommendation text cites the policy (e.g. “Per policy, equity is held within 40–60% for balanced clients”), and simulated trades are only proposed when drift exceeds the threshold and trade size meets the minimum. Rules can be edited in MongoDB to match your organization’s compliance and risk appetite.

---

## Pre-requisites

- **Node.js** 18 or later
- **MongoDB** — Local via Docker (e.g. [Colima](https://github.com/abiosoft/colima) or Docker Desktop, port 27018) or [MongoDB Atlas](https://cloud.mongodb.com)

---

## Setup

```bash
npm install
cp .env.example .env
```

Edit `.env`:

- **Local/Docker:** Set `MONGODB_URI=mongodb://127.0.0.1:27018/mcp_wealth`. Leave `MONGODB_ATLAS_URI` empty.
- **Atlas:** Set `MONGODB_ATLAS_URI=mongodb+srv://<user>:<password>@<cluster>.mongodb.net/mcp_wealth?retryWrites=true&w=majority`.

Seed the database (creates `portfolios` and `governing_rules` collections with sample data):

```bash
npm run seed:portfolios
```

---

## Run

**Development**

```bash
npm run dev
```

**Production**

```bash
npm run build
npm start
```

---

## Environment

| Variable            | Description                                      | Default / priority |
|--------------------|--------------------------------------------------|--------------------|
| `PORT`             | Server port                                     | 3000 |
| `MONGODB_ATLAS_URI`| Full Atlas SRV URI (user + password). Used first when set. | — |
| `MONGODB_URI`      | Local or Docker MongoDB connection              | `mongodb://127.0.0.1:27018/mcp_wealth` |

---

## How to Deploy

1. **Build:** `npm run build` (output in `dist/`).
2. **Configure:** Set `PORT`, `MONGODB_ATLAS_URI` or `MONGODB_URI` in the environment (or `.env`).
3. **Seed (once):** Run `npm run seed:portfolios` against the target database.
4. **Run:** `node dist/index.js` or `npm start`. For process managers (e.g. systemd, PM2), use the same command and ensure the working directory is the project root so `.env` and paths resolve correctly.
5. **Connect:** Point your MCP client (e.g. NitroStack Studio) at this project directory so it uses the same config and dependencies.

---

## Troubleshooting

### Connection failed / Broken pipe (Nitro Studio)

If Nitro Studio shows **"Connection Failed"** or **"Failed to initialize MCP connection after 5 attempts: Failed to flush stdin: Broken pipe"**, use this checklist.

1. **Project path in Nitro Studio must be this module folder**
   - In Studio, set the **project path** to the folder that contains `package.json` and `src/` for this server.
   - Example (Wealth Management):  
     `.../NitroStack/module-repos/wealth-management`  
   - Do **not** point at the parent `NitroStack` or `module-repos` folder; Studio must run `npm run dev` (or equivalent) from inside `wealth-management`.

2. **Check the bootstrap error log**
   - Open a terminal and run (from this module folder):
     ```bash
     cd path/to/module-repos/wealth-management
     cat .mcp-bootstrap-error.log
     ```
   - If the file exists, it contains the error that caused the server to exit. Fix that first (e.g. missing `.env`, wrong MongoDB URI, port in use).

3. **Run the server in a terminal** to see stderr live:
   ```bash
   cd path/to/module-repos/wealth-management
   npm run dev
   ```
   - If the process exits, the last lines on stderr are the cause.
   - Common causes:
     - Missing or incorrect `.env` — copy from `.env.example`, set `MONGODB_URI` or `MONGODB_ATLAS_URI`.
     - MongoDB not reachable — if using Colima run `colima start`, then `docker compose up -d` from this folder; or fix Atlas URI/network.
     - Port in use — set `PORT` in `.env` to another port (e.g. 3001).

4. **Rebuild after code changes**
   - If you changed `src/`, run `npm run build` (or rely on `npm run dev` which builds and watches). Then try connecting again from Studio.

### Widget shows no assets / “Run wealth_management…” or backend error

If the **Portfolio Health** widget does not show the list of assets (current value, target, manual adjustment), the tool is often returning an error instead of portfolio data.

1. **Check the tool output** in Studio: if you see `"status": "ERROR"` or `"message": "Database fetch failed..."`, the server could not read from MongoDB.
2. **Start MongoDB** (if local): If you use Colima, run `colima start` first. Then from this module folder run `docker compose up -d`.
3. **Seed the database:** `npm run seed:portfolios` (creates the `portfolios` collection and sample clients `client-IND-001`, `client-US-001`, `client-TECH-001`).
4. **Check `.env`:** Set `MONGODB_URI` or `MONGODB_ATLAS_URI` correctly and restart the server.
5. **Run the tool again** with `action: "health_analysis"` and `clientId: "client-IND-001"`. The widget should then show the asset list with current value, recommended target, and “Your target” for manual overrides.

### MongoDB / seeding

- **Docker (local):** From this module folder run `docker compose up -d`. MongoDB listens on port 27018; set `MONGODB_URI` accordingly.
  - **Using Colima:** Start the runtime first (`colima start`), then run `docker compose up -d` in this folder.
- **Atlas:** Use the full SRV string in `MONGODB_ATLAS_URI`; it takes priority over `MONGODB_URI`.

---

## Testing

For a step-by-step test plan (install, seed, build, run, call tools), see [TESTING.md](TESTING.md).

---

## Tools Reference

| Tool                | Description |
|---------------------|-------------|
| `wealth_management` | Use `action`: `list_customers`, `search_customers` (full-text, facets, synonyms), `health_analysis`, `simulate_rebalance`, or `execute_rebalance`. Widget: dashboard with MongoDB search (relevance, facets, highlighting); double-click or “View details” shows full detail at bottom. |

---

## License

MIT. See [LICENSE](LICENSE) in this repository.

---

## Next Enhancements

- **Portfolio-health widget** — Add a `widgets/` app and build so the `portfolio-health` UI can be re-enabled (e.g. from the monorepo backup). The tool runs without it; Studio shows JSON output.
- Real broker/OMS integration for `execute_rebalance`.
- Multi-tenant and role-based access (beyond manager clearance).
- Optional REST/HTTP transport alongside stdio.
- More asset classes and constraints in rebalance simulation.

---

## Contributing

Contributions are welcome. Please open an issue to discuss larger changes, and ensure tests and docs stay updated. When submitting changes, keep the same structure: one `wealth_management` tool with actions, MongoDB for persistence, and NitroStack patterns (guards, cache, events).

---

## Conclusion

This module provides a production-style wealth management MCP server with clear separation of analysis, simulation, and execution. You can run it standalone, deploy it next to your existing stack, or use it as a reference for building other NitroStack-based MCP servers.

For more on NitroStack: [nitrostack.ai](https://nitrostack.ai) | [Docs](https://docs.nitrostack.ai).