FinOps MCP Servers — Usage Guide

Source on GitHub ↗

Page 1 of 7 · Intro & Getting Started

Two MCP servers for FinOps

This repository ships an independent, unofficial agentic interface to the FinOps Foundation's published guidance: one MCP server for the FinOps Framework, one for the FOCUS™ specification. Both are read-only, offline, version-pinned, and label every derived answer as unofficial. This page gets them running in your client and shows the first call against each.

finops-framework-mcp · 11 tools · data v2.1.1 finops-focus-mcp · 9 tools · FOCUS 1.0 + 1.2
github.com/aaronmsoto/finops-framework-mcp ↗

Everything on this site is open source: both servers, the crawlers that build their data, the committed data artifacts, and the pages of this guide. MIT-licensed code, CC BY 4.0 content. Issues and pull requests welcome.

1

What this repo is

An LLM asked “how mature is our Allocation practice?” or “which FOCUS columns do I need for effective savings rate?” will happily improvise. These two servers exist so it doesn't have to: they serve the Foundation's own text, structured, with the source URL and licence attached to every response.

Each server is the same three decoupled parts — and the last two run with no network access at all:

crawler ──▶ markdown-canonical data artifact ──▶ stdio MCP server
  • Official by default. Out of the box the framework server serves only content published on finops.org/framework, restructured — no invented relationships between capabilities, no maturity levels beyond the Foundation's Crawl / Walk / Run.
  • Unofficial work is labelled, not hidden. The FOCUS server's KPI mapping, KPI calculation and 1.0→1.2 diff ship in the default surface but carry UNOFFICIAL in-text and official: false in structured output.
  • Reproducible. The data artifacts are committed; cli.js derive regenerates every JSON file from the canonical markdown offline, and the servers validate the artifact at startup and refuse to run on a bad one.
  • Version-pinned. FOCUS answers are always scoped to a spec version rather than blended across releases.

framework · get_framework_info {} · focus · list_versions {} · both list-tools

2

The two servers, side by side counts from live probes

Every number in these two cards was read out of a live server response, not a hand-maintained list.

finops-framework-mcp

The FinOps Framework · finops.org/framework · data v2.1.1, crawled 2026-07-23

The operating model: what a capability is, its official Crawl/Walk/Run assessment prose, who does what in it, and which KPIs it publishes.

6
Principles
3
Phases (Inform / Optimize / Operate)
4
Domains
22
Capabilities
11
Personas (6 core + 5 allied)
5
Technology Categories
3
Maturity levels
88
KPI library entries
11
tools
4
prompts
44
resources listed + 4 URI templates (finops://)

finops-focus-mcp

The FOCUS™ specification · versions 1.0 and 1.2 · latest 1.2

The data contract: what each billing column means in a given spec version, its normative MUST/SHOULD requirements, and what changed between releases.

1.0
43 columns, 9 attributes (source tag v1.0)
1.2
57 columns, 9 attributes (source tag v1.2) — the default
9
tools
3
prompts
125
resources listed + 4 URI templates (focus://)

FOCUS columns by feature level

Spec versionMandatoryConditionalRecommendedTotal
1.02120243
1.22132457

The mandatory count is identical in both versions — all 14 columns 1.2 adds land in the Conditional and Recommended tiers. The FOCUS server page walks the full 1.0→1.2 diff.

framework · get_framework_info {} · list-prompts · list-resources · list-resource-templates

focus · list_versions {} · list_columns {version, feature_level} × 6 · list-prompts · list-resources

3

Getting started — install

Both servers are published on npm — finops-framework-mcp and finops-focus-mcp, each a stdio binary — so an MCP client only ever needs a command and its arguments, and there is nothing to clone or build. Each package carries its own data artifact, so both run offline after install. Node >=22 is required by both.

# run either server directly — stdio, nothing to configure
npx -y finops-framework-mcp
npx -y finops-focus-mcp

# or from a clone of this repo
npm install && npm run build && npm run server

The framework server loads the data artifact packaged with its release (data/framework); point it at a locally-refreshed artifact with FINOPS_MCP_DATA or the first CLI argument.

Claude Code — one command per server

claude mcp add finops-framework -- npx -y finops-framework-mcp
claude mcp add focus-spec -- npx -y finops-focus-mcp

Claude Code — project-scoped .mcp.json

Commit this at the repo root to give everyone on the project both servers:

{
  "mcpServers": {
    "finops-framework": {
      "command": "npx",
      "args": ["-y", "finops-framework-mcp"]
    },
    "focus-spec": {
      "command": "npx",
      "args": ["-y", "finops-focus-mcp"]
    }
  }
}

Claude Desktop — claude_desktop_config.json

{
  "mcpServers": {
    "finops-framework": {
      "command": "npx",
      "args": ["-y", "finops-framework-mcp"]
    },
    "focus-spec": {
      "command": "npx",
      "args": ["-y", "finops-focus-mcp"]
    }
  }
}

Same shape either way — any generic stdio MCP client takes the identical {"command": "npx", "args": ["-y", "finops-focus-mcp"]} pair. (-y skips npx's first-run install prompt, which can hang non-interactive MCP clients.)

4

Or run them remotely — the Cloudflare Worker

Both servers are also deployable over Streamable HTTP from a single bundled Cloudflare Worker (src/workers/), which serves them at two paths:

POST /mcp/framework POST /mcp/focus

The Worker builds a fresh MCP server and transport per request — stateless by design: no session state persists across requests or isolates, and there is no user-supplied data path (calculate_kpi computes only over the bundled samples, exactly as the stdio servers do). Both data artifacts are compiled into the bundle at build time; nothing reachable from the Worker entry point touches node:fs at runtime, and a test statically walks the import graph to keep it that way.

Two operational notes before you point a browser at it. Requests with no Origin header — stdio-bridged and server-to-server MCP clients — are always allowed; browser requests need their origin on the Worker's ALLOWED_ORIGINS allowlist, which is also what drives CORS. And there is deliberately no authentication and no rate limiting: the Worker serves only public, read-only content with no per-user state behind it.

There is no public hosted endpoint to point you at here — deploying is a human approval point in this repo, so the URL is whatever the operator's own wrangler deploy produces. A deployment smoke test looks like this:

curl -s "$WORKER_URL/mcp/focus" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

source: docs/deploy-worker.md (owner deployment checklist)

5

Your first call against each server official

Both servers publish a “start here” tool. Below is real, unedited output from each — captured through the repo's own MCP client bridge, which is the same stdio protocol your client will speak.

finops-focus-mcp · list_versions

Call this first: it tells you which version values every other FOCUS tool will accept.

$ node evals/framework/mcp-call.mjs --server=focus call list_versions '{}'
{
  "content": [
    {
      "type": "text",
      "text": "- 1.0: 43 columns, 9 attributes (source v1.0)\n- 1.2 (latest): 57 columns, 9 attributes (source v1.2)"
    }
  ],
  "structuredContent": {
    "latest": "1.2",
    "versions": [
      {
        "spec_version": "1.0",
        "source_tag": "v1.0",
        "data_version": "1.0.1",
        "is_latest": false,
        "counts": {
          "attributes": 9,
          "columns": 43
        }
      },
      {
        "spec_version": "1.2",
        "source_tag": "v1.2",
        "data_version": "1.0.1",
        "is_latest": true,
        "counts": {
          "attributes": 9,
          "columns": 57
        }
      }
    ]
  }
}

focus · list_versions {}

finops-framework-mcp · get_capability

Capability documents are large, so get_capability is section-selectable via include — here, the summary alone. Note the two things that come back on every official response: a source_url pointing at the page the text came from, and the CC BY 4.0 attribution footer.

$ node evals/framework/mcp-call.mjs call get_capability \
    '{"capability":"anomaly-management","include":["summary"]}'
{
  "content": [
    {
      "type": "text",
      "text": "{\n  \"slug\": \"anomaly-management\",\n  \"title\": \"Anomaly Management\",\n  \"domain\": \"understand-usage-and-cost\",\n  \"sections\": {\n    \"summary\": \"Detect, identify, alert and manage unexpected or unforecasted technology cost and usage irregularities in a timely manner to lower risk and ensure cost-effective operations.\"\n  },\n  \"uri\": \"finops://framework/capabilities/anomaly-management\",\n  \"source_url\": \"https://www.finops.org/framework/capabilities/anomaly-management/\",\n  \"license\": \"CC-BY-4.0\"\n}\n\n---\nSource: https://www.finops.org/framework/capabilities/anomaly-management/ — © FinOps Foundation, licensed CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). Content restructured and adapted by finops-framework-mcp (data v2.1.1, crawled 2026-07-23); unofficial extensions are always marked."
    },
    {
      "name": "anomaly-management",
      "uri": "finops://framework/capabilities/anomaly-management",
      "description": "Full anomaly-management capability document",
      "mimeType": "text/markdown",
      "type": "resource_link"
    }
  ],
  "structuredContent": {
    "slug": "anomaly-management",
    "title": "Anomaly Management",
    "domain": "understand-usage-and-cost",
    "sections": {
      "summary": "Detect, identify, alert and manage unexpected or unforecasted technology cost and usage irregularities in a timely manner to lower risk and ensure cost-effective operations."
    },
    "uri": "finops://framework/capabilities/anomaly-management",
    "source_url": "https://www.finops.org/framework/capabilities/anomaly-management/",
    "license": "CC-BY-4.0"
  }
}

framework · get_capability {capability: "anomaly-management", include: ["summary"]}

Don't know a slug? Don't guess

Both servers ship a ranked keyword search whose whole job is turning words into slugs you can feed to the other tools — search_framework {query} on one side, search_focus {query, version} on the other. Each hit returns a slug and a resource URI. And if you'd rather orient than search, get_framework_info {} returns the framework's structure and a short navigation guide in one call:

“Look up anything by keyword: search_framework. Browse: list_capabilities (filter by domain or persona), then get_capability with an include list to control size.”

framework · get_framework_info {} → content[0].text, “How to navigate”

6

Where to go next

Two reference pages, then four worked examples that use both servers together — three planned walkthroughs and one live, unscripted Q&A session. Every number and quote on all six is produced the same way as the transcripts above.

finops-framework-mcp reference

The data model (domains → capabilities → KPIs / personas / maturity), the 11 tools grouped discover → read → search → assess, prompts, finops:// resource URIs, pagination, and how official content is marked. Worked demo: Anomaly Management, end to end.

finops-focus-mcp reference

The version model, the 9 tools grouped versions → columns / attributes → requirements → search → diff → unofficial KPI mapping, prompts and focus:// resources. Worked demo: BilledCost at both versions plus the 1.0→1.2 diff.

Worked example · Showback

Understand Usage & Cost → Allocation and Reporting & Analytics → the exact FOCUS columns a showback report needs → a real showback table computed from the bundled official sample data.

Worked example · Rate Optimization (ESR)

Capability → four featured KPIs → the six FOCUS columns that feed them at 1.0 vs 1.2 → effective savings rate computed on the official sample — and what the server does when a KPI isn't computable.

Worked example · Forecasting journey

A maturity journey to Walk-level Forecasting: verbatim official Crawl→Walk requirements, supporting capabilities and KPIs, then the FOCUS columns that feed a forecasting pipeline.

Worked example · Quick Q&A

Four unscripted prompts in one live session: capabilities by domain, a capability summary, a Crawl→Walk maturity gap with validating KPIs, and starter Unit Economics KPIs from FOCUS 1.2.

The one-minute version

Install both bins (npx -y finops-framework-mcp, npx -y finops-focus-mcp), register them in your client with the same command/args pair, then start every session with get_framework_info {} and list_versions {}. Ask the framework server what good looks like; ask the FOCUS server which columns prove it. Anything the servers derived rather than quoted arrives already labelled unofficial — believe the label.