Dependency map

September 9, 2026 ยท View on GitHub

Five OptimNow repositories make up the FinOps tooling family. They are separate repos on purpose, but they are not independent: prices flow from one of them into all the others, and one pair shares generated code.

This file answers two questions. What depends on what, and if I change this repo, what else do I need to look at?


The five repositories

RepositoryWhat it isRuntimeDeployed as
cloud-sparkle-compareOptimToken - the price catalogue, web app and public APINode / Vite / Reactoptimtoken.optimnow.io on Vercel
ai-pricing-hub-mcpOptimToken as MCP toolsNode / SkybridgeAlpic
ai-roi-calculatorAI ROI calculator web app, and the engine + METHODOLOGY.mdNode / Reactairoicalculator.optimnow.io
ai-roi-calculator-mcpThe ROI calculator as MCP toolsNode / SkybridgeAlpic
cloud-finops-skillsThis repo. FinOps knowledge, and cloud-finops-mcpPythonPyPI + Fly.io

Two of them are sources of truth. Everything else consumes them:

  • OptimToken is the single source for every price figure in the family.
  • ai-roi-calculator is the single source for the ROI engine and its methodology.

The map

flowchart TD
    SPARKLE["<b>cloud-sparkle-compare</b><br/>OptimToken web + API<br/><i>source of truth: prices</i>"]
    HUBMCP["<b>ai-pricing-hub-mcp</b><br/>pricing MCP"]
    ROI["<b>ai-roi-calculator</b><br/>web app + engine<br/><i>source of truth: ROI engine</i>"]
    ROIMCP["<b>ai-roi-calculator-mcp</b><br/>ROI MCP"]
    SKILL["<b>cloud-finops-skills</b><br/>skill + cloud-finops-mcp"]

    SPARKLE -->|"live prices (runtime)"| HUBMCP
    SPARKLE -->|"live prices (runtime)"| ROIMCP
    SPARKLE -.->|"model snapshot<br/>Mon 06:00 UTC"| ROI
    ROI ==>|"generated engine code<br/>CI-enforced"| ROIMCP
    SKILL -..->|"routes to, documents"| HUBMCP
    SKILL -..->|"routes to, documents"| ROIMCP
    SKILL -..->|"routes to"| SPARKLE

    SPARKLE <-.->|"deep-link handoff (UI)"| ROI

    classDef truth fill:#ACE849,stroke:#2C2C2C,stroke-width:2px,color:#2C2C2C
    classDef svc fill:#7C3AED,stroke:#2C2C2C,color:#fff
    classDef skill fill:#F5F5F5,stroke:#2C2C2C,color:#2C2C2C
    class SPARKLE,ROI truth
    class HUBMCP,ROIMCP svc
    class SKILL skill

Read the arrow weight as coupling strength:

  • ==> generated code. ai-roi-calculator-mcp contains a copy of the calculator's engine, produced by scripts/sync-engine.mjs. Its CI checks out OptimNow/ai-roi-calculator on every PR and fails if the copy has drifted. This is the tightest coupling in the family, and the only one that can fail a build.
  • --> runtime fetch. The MCP servers call the OptimToken API when a tool runs. A change to the API response shape breaks them at request time, not at build time, which means CI will not catch it.
  • -.-> scheduled data pull. A snapshot copied on a cron, not a live call.
  • -..-> documentation only. cloud-finops-skills names these tools and tells the model to call them. There is no code dependency in either direction: nothing in this repo imports, builds against, or calls them at build time.

The Monday cascade

Price data propagates on a deliberate one-hour stagger. Each job runs after the one it depends on.

Time (UTC)RepositoryJobWhat it does
Daily 05:00cloud-sparkle-comparerefresh-llm-fallbackRefreshes the OptimToken catalogue
Mon 05:30cloud-sparkle-comparerefresh-bedrock-matrixRefreshes the Bedrock matrix
Mon 06:00ai-roi-calculatorrefresh-model-snapshotPulls the model snapshot from OptimToken
Mon 07:00ai-roi-calculator-mcpsync-enginePulls engine + snapshot from the calculator

ai-pricing-hub-mcp is not on this cascade. Its static fallback catalogue is regenerated only by running npm run refresh-fallback by hand. That matters, because the fallback is what gets served whenever the live fetch fails, and an unrefreshed fallback ages silently. Read the provenance block's as-of timestamp and its notice, which states the snapshot's age, before trusting a tier-2 response.


If I change this repo, what else do I review?

The table is ordered by blast radius, widest first.

cloud-sparkle-compare (OptimToken)

The riskiest repo in the family: everything downstream reads it.

If you changeAlso reviewWhy
An API response shape (/api/llm-models, /api/pricing) - renamed field, changed nesting, changed meta blockai-pricing-hub-mcp, ai-roi-calculator-mcpBoth parse these responses at runtime. Nothing fails at build time, so the first symptom is a tool silently falling back to stale data
An API URL or routeBoth MCP repos, plus ai-roi-calculatorHard break
Cache TTLs, timeouts, payload sizeai-pricing-hub-mcpIts client timeout is tuned against these response times
Prices or catalogue contents onlyNothingThis is the normal case and propagates by design

ai-roi-calculator

If you changeAlso reviewWhy
Anything under the engine (formulas, presets, constants)ai-roi-calculator-mcp - mandatoryIts CI fails until npm run sync:engine is re-run there and the result committed. Do not merge one without the other
METHODOLOGY.md semantics - a method's definition, an input's meaning, a documented trapcloud-finops-skills -> references/finops-ai-value-management.mdThat reference explains the same methods in prose. It deliberately holds no formulas, but it does describe what each input means
Wording, UI, stylingNothing

ai-roi-calculator-mcp

If you changeAlso reviewWhy
Anything in server/src/lib/StopIt is generated. Change ai-roi-calculator instead, then re-sync
Tool names, signatures, or output shapecloud-finops-skills -> INSTALLATION.mdThe companion-connector section lists the four tools and their parameters
The deployment URLcloud-finops-skills -> INSTALLATION.mdThe connect command is published there

ai-pricing-hub-mcp

If you changeAlso reviewWhy
The provenance block - tier semantics, field names, the stale noticecloud-finops-skills -> SKILL.md / POWER.md "Price figures" rule 5, and INSTALLATION.mdThe skill's dated-price doctrine instructs the model to read those exact fields
Tool names, signatures, output shapecloud-finops-skills -> SKILL.md, POWER.md, INSTALLATION.mdTool names appear in the doctrine and the routing
The deployment URLcloud-finops-skills -> README.md, INSTALLATION.mdPublished in both
The static fallback catalogueNothing, but check the provenance as-of timestampSee the cascade note above

cloud-finops-skills (this repo)

The safest repo to change: nothing downstream depends on it. The dependencies run inward.

If you changeAlso reviewWhy
Reference or playbook contentNothing outside this repoThe intra-repo build hook re-bundles it into cloud-finops-mcp automatically
The MCP tool surface (mcp_server/src/)Nothing outside this repoBut bump versions per the release-train rule in CLAUDE.md
Text that quotes another repo's tool names, URLs, or provenance fieldsVerify against that repoThis is drift in the inward direction: the other repo changed and this one did not follow

Known asymmetries

Worth carrying in your head when reviewing anything here.

  1. Runtime coupling is invisible to CI. Only the ROI calculator to ROI MCP edge is enforced by a build. Every other cross-repo edge is a runtime fetch or a piece of documentation, so a breaking change ships green and surfaces as a degraded answer.
  2. This repo's dependencies are documentation, and documentation drifts silently. Tool names, parameters, endpoint URLs and provenance field names are quoted in SKILL.md, POWER.md, INSTALLATION.md and README.md. Nothing checks them. When an MCP repo changes its surface, this repo does not find out.
  3. Duplicated computation is the recurring failure mode in this family. OptimToken drifted between its website and its MCP; the ROI calculator drifted between its web app and its MCP far enough to return a 7-point different ROI for the same preset. The generated-and-CI-checked sync exists because of the second one. Before adding a capability to a second repo, check whether it can route to the first instead. The reasoning behind the standing decision not to put pricing tools inside cloud-finops-mcp is in docs/ROADMAP.md.

Cloud FinOps Skill by OptimNow - licensed under CC BY-SA 4.0.