Metadata-Version: 2.4
Name: cloudsense-customer-compass
Version: 0.22.0
Summary: MCP server for CloudSense customer upgrade assessment, analysis, and impact verification.
License-Expression: MIT
Requires-Python: >=3.10
Requires-Dist: mcp>=1.0.0
Requires-Dist: pymupdf>=1.24.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# CloudSense Customer Compass

MCP server for CloudSense customer upgrade assessment, analysis, and impact verification.

| | |
|---|---|
| **Package** | `cloudsense-customer-compass` |
| **Version** | `0.22.0` |
| **Python** | `>=3.10` |
| **License** | MIT |

## Prerequisites

- **`uv`** (recommended) — install with `curl -LsSf https://astral.sh/uv/install.sh | sh` (macOS/Linux) or `brew install uv` if you have Homebrew. Handles Python automatically, no separate Python install needed. See [uv installation docs](https://docs.astral.sh/uv/getting-started/installation/) for other options.
- **Or** Python 3.10+ if you prefer `pip`/`pipx`
- Salesforce CLI (`sf`) — [install](https://developer.salesforce.com/tools/salesforcecli)

## Installation

```bash
# Via uvx (recommended — no Python install needed, always runs latest)
uvx cloudsense-customer-compass

# Or via pipx (requires Python 3.10+)
pipx run cloudsense-customer-compass

# Or install globally via pip (requires Python 3.10+)
pip install cloudsense-customer-compass
```

## MCP Configuration

### Cursor IDE

Go to **Settings → MCP Servers** and add:

```json
{
  "mcpServers": {
    "CloudSense Customer Compass": {
      "command": "uvx",
      "args": ["cloudsense-customer-compass"]
    }
  }
}
```

### Claude Desktop

Add to your config file:

- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux:** `~/.config/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "CloudSense Customer Compass": {
      "command": "uvx",
      "args": ["cloudsense-customer-compass"]
    }
  }
}
```

### Claude CLI

```bash
claude mcp add "CloudSense Customer Compass" -- uvx cloudsense-customer-compass
```

## Available Tools

### Connection & Cache

| Tool | Description |
|------|-------------|
| `connect_lma` | Authorize the CloudSense LMA Salesforce org. First tool to call for any workflow. |
| `check_compass_data` | Verify that local reference data (packages, seasonal releases, version mappings) is fresh. Returns VALID, STALE, or MISSING status. Called automatically at session start. |
| `load_compass_data` | Refresh the local reference data cache. Fetches packages, seasonal releases, and version mappings from the Packaging Environment. Auto-refreshes every 24 hours. |

### Customer & Portfolio

| Tool | Description |
|------|-------------|
| `find_customer` | Search for a customer by name. Returns matches with region and industry for disambiguation. On confirmation, returns full account profile (industry, region, parent company, description, website, LinkedIn). |
| `get_customer_licenses` | Retrieve all production and sandbox licenses for a customer. Returns per-package summary with seat utilization, version currency (installed vs. latest available), seasonal release positioning, expiry, and org breakdown. Writes to `customers/<slug>/licenses.json`. |
| `get_portfolio_data` | Fetch all active/trial production licenses with built-in health scoring. Enriched with seat utilization, version currency (installed vs. latest available), per-package expiry, and account context. Computes composite health scores (renewal risk, version currency, seat utilization, product breadth) using editable rules from `portfolio/scoring-rules.md`. Classifies churned, partner, and internal accounts. Saves timestamped snapshots for trend analysis. |

### Upgrade Assessment

| Tool | Description |
|------|-------------|
| `get_upgrade_path` | Generate per-package upgrade roadmaps from installed version to a target release. Shows version gaps, seasonal release mapping, intermediate versions, and cloud service flags. Supports targeted release (e.g. "to R36") for phased upgrades. |
| `get_release_info` | Retrieve release notes, user guides, and JS API docs. Three modes: **Customer upgrade** (installed → target range), **Customer installed-only** (docs at current versions), **Browse** (any release range). Writes organized link files to `release-docs/`. |
| `download_release_docs` | Download actual PDF/document files from Google Drive links created by `get_release_info`. Parallel downloads (4 concurrent), resumable (existing files skipped automatically). |
| `extract_doc_text` | Extract readable text from downloaded PDFs and DOCX files. Saves `.txt` files alongside originals so the AI can search and analyze the content. Already-extracted files are skipped on re-run. |
| `verify_upgrade_analysis` | Track upgrade analysis completeness. Scans `release-docs/` for source `.txt` files and `upgrade-analysis/` for generated reports. Returns a per-package checklist (DONE/TODO) with a GATE check that blocks the comprehensive report until all packages are covered. |

### Customer Org Integration (Technical Impact Analysis)

| Tool | Description |
|------|-------------|
| `connect_customer_org` | Authorize a customer Salesforce sandbox for metadata retrieval. Accepts a flexible org identifier (alias, org ID, or URL). Hard-blocks production orgs. Compares sandbox packages against production license data to highlight discrepancies. |
| `list_metadata` | Discover metadata component counts for a given type in the connected sandbox. Returns member names and count. AI calls this in parallel for multiple types to plan retrieval chunking. |
| `retrieve_metadata` | Retrieve metadata components from the sandbox — one batch per call. AI controls chunking and parallelism. Updates `metadata-manifest.json` for resumability across sessions. |
| `scan_customer_code` | Scan retrieved metadata for CloudSense namespace references. Produces a typed dependency inventory (API_CALL, TRIGGER, OBJECT_DML, FIELD_REF, SOQL_REF, LWC_IMPORT, TEST_ONLY) — no risk labels. Risk is determined by the AI when cross-referencing with release notes. |

### Reporting & Feedback

| Tool | Description |
|------|-------------|
| `save_report` | Save AI-generated analysis, insights, or discussion notes as a shareable markdown file. Works across any MCP client (Cursor, Claude Desktop, etc.). |
| `generate_visual_report` | Generate a self-contained HTML visual report with Chart.js charts. AI builds the layout on the fly using a CSS design system — KPI cards, styled tables, tags, progress bars, and interactive charts. Auto-opens in the browser; print-to-PDF ready. |
| `generate_assessment_pdf` | Combine all upgrade assessment markdown reports (executive summary, per-package reports, upgrade sequence, pre-upgrade checklist) into a single professionally styled PDF with cover page and page numbers. Ready to share with stakeholders or attach to Jira tickets. |
| `submit_feedback` | Submit a bug report or feature request. The AI detects when you mention an issue or suggest a feature and offers to send it to the team. |

## Workflows

### Single Customer Analysis

```
connect_lma              → Authorize the CloudSense LMA org
find_customer            → Search by name, confirm (returns full account profile)
get_customer_licenses    → License, package, org summary + seat utilization
                           + version currency (installed vs. latest available)
```

### Portfolio Analysis

```
connect_lma              → Authorize the CloudSense LMA org
get_portfolio_data       → Full portfolio snapshot with built-in health scores
                           (renewal risk, version currency, seats, product breadth)
                           Auto-creates portfolio/scoring-rules.md on first run
                           Saves timestamped snapshot + detects changes
save_report              → Persist ranked insights as shareable markdown
generate_visual_report   → Interactive HTML report with charts and KPIs
```

### Upgrade Assessment (Automated Pipeline)

Tell Compass: *"Run an upgrade assessment for Starhub to R37"* — the full pipeline runs automatically:

```
get_upgrade_path         → Per-package upgrade roadmap (versions, gaps, dependencies)
get_release_info         → Retrieve release note + user guide links
download_release_docs    → Download actual documents from Google Drive (chunked)
extract_doc_text         → Extract text from PDFs/DOCX for AI analysis
verify_upgrade_analysis  → Build manifest of packages to analyze (gate check)
AI analysis              → Read extracted text, generate per-package reports
                           with inline source citations for every finding
verify_upgrade_analysis  → Confirm all packages covered → GATE: PASSED
AI executive summary     → Risk level, upgrade sequence, pre-upgrade checklist
generate_assessment_pdf  → (optional) Single PDF of the full assessment
```

Output structure:
```
customers/<slug>/
├── upgrade-path.json                    # roadmap artifact
├── release-docs/                        # downloaded documents
│   ├── CloudSense_CPQ_(Configurator)/
│   │   ├── R35/
│   │   │   ├── release-notes.md         # link file
│   │   │   ├── RN_Configurator__xxx.pdf # downloaded doc
│   │   │   └── RN_Configurator__xxx.txt # extracted text
│   │   └── R37/
│   └── Orchestrator/
├── upgrade-analysis/                    # AI-generated reports
│   ├── 01-configurator.md              # per-package deep dive
│   ├── 02-orchestrator.md
│   ├── upgrade-sequence.md             # recommended install order
│   └── pre-upgrade-checklist.md        # actionable checklist
└── upgrade-assessment-YYYY-MM-DD.md    # executive summary
```

### Release Documentation (Standalone)

Access documentation without a full upgrade assessment:

```
# Get docs for a customer's installed versions
"Download all docs for Starhub"
→ get_release_info (installed-only mode) → download_release_docs

# Compare releases (no customer context needed)
"What changed between R35 and R37?"
→ get_release_info (browse mode) → download_release_docs → extract_doc_text → AI analysis

# Targeted retrieval
"Get me the R37 user guide for Configurator"
→ get_release_info (browse, filtered) → download_release_docs
```

### Customising Health Scores

Edit `portfolio/scoring-rules.md` to change weights, thresholds, core
packages, opportunity detection rules, or report persona templates.
Changes take effect on the next `get_portfolio_data` call. You can also
override any rule conversationally (e.g. "for this analysis, treat csbb
as critical") or run what-if scenarios ("what if we drop R35 support?").

### Technical Impact Analysis (NEW)

After an upgrade assessment, connect a customer sandbox to analyze what the upgrade means for their customizations:

```
connect_customer_org     → Authorize sandbox (blocks production orgs)
                           Compares sandbox vs production packages
list_metadata            → Discover component counts (AI calls in parallel)
                           "5,357 Apex classes, 42 triggers, 89 flows..."
retrieve_metadata        → Pull code in AI-orchestrated parallel chunks
                           Resumable via metadata-manifest.json
scan_customer_code       → Map all CS namespace references (typed inventory)
AI Impact Assessment     → Cross-reference inventory with release notes
                           Build Impact Matrix: CRITICAL / HIGH / LOW /
                           UNVERIFIED per entity
```

Output structure:
```
customers/<slug>/
├── org-connection.json                 # sandbox connection + package comparison
└── metadata/
    ├── sfdx-project.json
    ├── discovery/                      # from list_metadata
    │   ├── ApexClass.json
    │   ├── ApexTrigger.json
    │   └── CustomObject.json
    ├── metadata-manifest.json          # retrieval tracking (resumable)
    ├── cs-references.json              # dependency inventory
    └── force-app/                      # retrieved metadata
        └── main/default/
            ├── classes/
            ├── triggers/
            └── flows/
```

### Coming Soon

```
get_repo_mapping         → Map CS packages to GitHub source repositories
clone_package_repo       → Blobless clone of package repos for source analysis
diff_package_changes     → Git diff between versions for definitive evidence
```

With repo diffs, the Impact Matrix upgrades from "UNVERIFIED" entries to definitive "NO IMPACT" or "CHANGED" — backed by code-level evidence.

A separate MCP for executing assessment actions directly into customer orgs is also in development.

## Workspace Output Structure

Tools write their output to a structured workspace directory:

```
workspace/
├── assessment.json                     # LMA connection info
├── .cache/                             # reference data cache
│   ├── compass-data.json               # packages, seasonal releases, versions
│   └── cs-namespace-mapping.json       # package mappings
├── customers/                          # per-customer data
│   ├── nbn-co-ltd/
│   │   ├── licenses.json               # license + version currency data
│   │   ├── upgrade-path.json           # upgrade roadmap artifact
│   │   ├── org-connection.json         # sandbox connection + package comparison
│   │   ├── release-docs/               # downloaded release documentation
│   │   │   ├── CloudSense_CPQ_(Configurator)/
│   │   │   │   ├── R35/
│   │   │   │   └── R37/
│   │   │   ├── Orchestrator/
│   │   │   └── index.md
│   │   ├── metadata/                   # retrieved customer metadata
│   │   │   ├── sfdx-project.json
│   │   │   ├── discovery/              # from list_metadata
│   │   │   │   ├── ApexClass.json
│   │   │   │   └── ApexTrigger.json
│   │   │   ├── metadata-manifest.json  # retrieval tracking (resumable)
│   │   │   ├── cs-references.json      # dependency inventory
│   │   │   └── force-app/              # retrieved source files
│   │   ├── upgrade-analysis/           # AI-generated per-package reports
│   │   │   ├── 01-configurator.md
│   │   │   ├── 02-orchestrator.md
│   │   │   ├── upgrade-sequence.md
│   │   │   └── pre-upgrade-checklist.md
│   │   ├── upgrade-assessment-2026-03-23.md  # executive summary
│   │   ├── NBN-Co-Ltd-Upgrade-Assessment-2026-03-23.pdf  # combined PDF
│   │   └── analysis-2026-03-14.md
│   └── starhub-ltd/
│       └── licenses.json
├── release-docs/                       # non-customer release docs (browse mode)
├── portfolio/                          # cross-customer analysis
│   ├── scoring-rules.md                # editable health scoring rules
│   ├── portfolio-data.json
│   └── history/                        # timestamped snapshots
│       ├── portfolio-data-2026-03-01.json
│       └── portfolio-data-2026-03-14.json
└── .visual-reports/                    # HTML reports (browser viewer)
    ├── apac-portfolio-2026-03-16.html
    └── nbn-co-analysis-2026-03-16.html
```

## Safety

- **Read-only** against customer Salesforce orgs — never deploys, inserts, updates, or deletes
- **Whitelist-enforced** — only approved `sf` CLI subcommands can execute
- **LMA queries** scoped to `Account` and `sfLma__*` objects only
- **Customer org queries** limited to CloudSense configuration objects
- All sf CLI commands are logged for auditability

## Usage Telemetry

Built-in telemetry logs every tool call to a shared Google Sheet so the
team can see who's using what and how often. Telemetry is **on by default**
and requires no configuration from individual team members.

To opt out, add `CLOUDSENSE_TELEMETRY=off` to the `env` block in your MCP
server config:

```json
{
  "mcpServers": {
    "CloudSense Customer Compass": {
      "command": "uvx",
      "args": ["cloudsense-customer-compass"],
      "env": {
        "CLOUDSENSE_TELEMETRY": "off"
      }
    }
  }
}
```

### What Gets Logged

Each tool call sends: timestamp, OS username, hostname, server version,
tool name, sanitized arguments (sensitive fields like `password`, `token`,
`secret`, `key`, `working_directory` are redacted), duration, status
(success/error), and result size. Session start/end events are also logged.

## Troubleshooting

> **SF CLI not detected?** If the tool says it can't find the Salesforce CLI,
> try restarting Cursor. If that doesn't help, open a terminal and run
> `sf org login web --alias cs-lma`, then try again.

## Known Issues

See [docs/known-issues.md](docs/known-issues.md) for full details.

- **Concurrent tool calls crash the server** (KI-001) — Running tools from
  multiple tabs simultaneously can freeze and crash the MCP server. Use one
  tab at a time for LMA queries. Fix planned for a post-MVP release.
- **SF CLI not found on Windows** (KI-002) — Cursor may not inherit the
  system PATH on Windows, causing `sf` to not be found. v0.11.1 auto-detects
  common install locations. If that fails, login manually in your terminal
  and the tool will pick up the authorized org.

## Development

```bash
python3 -m pip install -e ".[dev]"

# Run server locally
python3 -m cloudsense_customer_compass.server

# Run tests
pytest

# Build & publish
python3 -m build
uv publish dist/*
```
