Skip to main content
Glama

estimate_cost

Estimate the monthly cloud bill for an architecture specification. Returns per-component cost breakdown, total monthly cost, data-transfer costs, and currency. Deterministic and works offline with no network calls.

Instructions

Estimate the monthly cloud bill for an architecture spec.

Returns a structured estimate with per-component breakdown, total monthly cost, data-transfer costs, and currency. Deterministic: same spec + tier yields same result.

When to use: You need the numeric bill for one architecture on one provider+tier combination. For multi-provider comparison of just the costs, use compare_provider_costs. For side-by-side architecture + cost comparison across providers, use compare_providers + this tool.

Behavior: Pure computation — no LLM, no network, no API costs. Works offline. Does not deploy or touch cloud resources.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
spec_jsonYesArchSpec to price. Pricing is resolved per-component against a bundled SQLite catalog (no network calls), with formula dispatch for serverless/managed services and a static fallback for rare ones.
pricing_tierNoPricing tier multiplier applied to compute and data-store components. Values: 'on_demand' (1.0x), 'reserved_1yr' (0.6x), 'reserved_3yr' (0.4x), 'spot' (0.3x).on_demand

Implementation Reference

  • The MCP tool handler for 'estimate_cost'. Takes an ArchSpec dict and pricing_tier, validates with ArchSpec.model_validate, then calls CostEngine().estimate() to compute monthly cost breakdown. Returns CostEstimate dict.
    def estimate_cost(
        spec_json: Annotated[
            dict,
            Field(
                description=(
                    "ArchSpec to price. Pricing is resolved per-component against a "
                    "bundled SQLite catalog (no network calls), with formula dispatch "
                    "for serverless/managed services and a static fallback for rare ones."
                ),
            ),
        ],
        pricing_tier: Annotated[
            str,
            Field(
                description=(
                    "Pricing tier multiplier applied to compute and data-store components. "
                    "Values: 'on_demand' (1.0x), 'reserved_1yr' (0.6x), "
                    "'reserved_3yr' (0.4x), 'spot' (0.3x)."
                ),
                examples=["on_demand", "reserved_1yr", "reserved_3yr", "spot"],
            ),
        ] = "on_demand",
    ) -> dict:
        """Estimate the monthly cloud bill for an architecture spec.
    
        Returns a structured estimate with per-component breakdown, total
        monthly cost, data-transfer costs, and currency. Deterministic: same
        spec + tier yields same result.
    
        When to use: You need the numeric bill for one architecture on one
        provider+tier combination. For multi-provider comparison of just the
        costs, use `compare_provider_costs`. For side-by-side architecture +
        cost comparison across providers, use `compare_providers` + this tool.
    
        Behavior: Pure computation — no LLM, no network, no API costs. Works
        offline. Does not deploy or touch cloud resources.
        """
        from cloudwright.cost import CostEngine
        from cloudwright.spec import ArchSpec
    
        spec = ArchSpec.model_validate(spec_json)
        estimate = CostEngine().estimate(spec, pricing_tier=pricing_tier)
        return estimate.model_dump(exclude_none=True)
  • Tool registration via @mcp.tool() decorator on the estimate_cost function inside the register() function.
    def register(mcp: FastMCP) -> None:
        @mcp.tool()
  • Input schema: spec_json (dict, ArchSpec) and pricing_tier (str, default 'on_demand', choices: on_demand/reserved_1yr/reserved_3yr/spot).
    def estimate_cost(
        spec_json: Annotated[
            dict,
            Field(
                description=(
                    "ArchSpec to price. Pricing is resolved per-component against a "
                    "bundled SQLite catalog (no network calls), with formula dispatch "
                    "for serverless/managed services and a static fallback for rare ones."
                ),
            ),
        ],
        pricing_tier: Annotated[
            str,
            Field(
                description=(
                    "Pricing tier multiplier applied to compute and data-store components. "
                    "Values: 'on_demand' (1.0x), 'reserved_1yr' (0.6x), "
                    "'reserved_3yr' (0.4x), 'spot' (0.3x)."
                ),
                examples=["on_demand", "reserved_1yr", "reserved_3yr", "spot"],
            ),
        ] = "on_demand",
    ) -> dict:
  • CostEstimate return type schema: monthly_total, breakdown (list of ComponentCost), data_transfer_monthly, currency, as_of.
    class CostEstimate(BaseModel):
        monthly_total: float
        breakdown: list[ComponentCost] = Field(default_factory=list)
        data_transfer_monthly: float = 0.0
        currency: str = "USD"
        as_of: str = Field(default_factory=lambda: date.today().isoformat())
  • CostEngine.estimate() method — the core logic that prices each component via _price_component (3-tier resolution: catalog DB, registry formulas, static fallback), sums data transfer costs, and returns a CostEstimate.
    class CostEngine:
        def __init__(self, catalog: Catalog | None = None, registry: ServiceRegistry | None = None):
            self.catalog = catalog or Catalog()
            self.registry = registry or get_registry()
    
        def estimate(
            self,
            spec: ArchSpec,
            pricing_tier: str = "on_demand",
            workload_profile: str | None = None,
        ) -> CostEstimate:
            """Price every component in an ArchSpec and return a full breakdown.
    
            Args:
                spec: The architecture specification to price.
                pricing_tier: Pricing model — on_demand, reserved_1yr, reserved_3yr, spot.
                workload_profile: Optional sizing profile — small, medium, large, enterprise.
                    When set, applies realistic defaults for request volumes, storage sizes,
                    node counts, and data transfer that match production workloads.
            """
            breakdown: list[ComponentCost] = []
    
            for comp in spec.components:
                effective = _apply_profile(comp, workload_profile) if workload_profile else comp
                monthly = self._price_component(effective, spec.provider, spec.region, pricing_tier)
                hourly = round(monthly / 730, 4) if monthly > 0 else None
                notes = self._cost_notes(effective)
                breakdown.append(
                    ComponentCost(
                        component_id=comp.id,
                        service=comp.service,
                        monthly=monthly,
                        hourly=hourly,
                        notes=notes,
                    )
                )
    
            component_total = round(sum(c.monthly for c in breakdown), 2)
            data_transfer = self._estimate_data_transfer(spec, workload_profile=workload_profile)
            total = round(component_total + data_transfer, 2)
    
            return CostEstimate(
                monthly_total=total,
                breakdown=breakdown,
                data_transfer_monthly=data_transfer,
                currency="USD",
                as_of=date.today().isoformat(),
            )
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Since annotations are absent, the description fully discloses behavioral traits: deterministic computation, no LLM/network/API calls, works offline, and does not deploy. This transparency goes well beyond minimal requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is structured with clear sections (overview, return info, determinism, usage, behavior). Every sentence adds value; no fluff. Well front-loaded with the core purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (nested spec_json, pricing tiers), the description covers return structure, determinism, offline operation, and usage boundaries. No output schema is present, but the description describes the output comprehensively, making it complete for agent understanding.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema has 100% parameter coverage, so baseline is 3. However, the description adds meaningful context: explains pricing resolution via a bundled SQLite catalog with formula dispatch and fallback, and describes the pricing tier multiplier values, which adds value beyond schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'Estimate the monthly cloud bill for an architecture spec,' specifying the verb (estimate) and resource (monthly cloud bill). It distinguishes from siblings by explicitly naming `compare_provider_costs` and `compare_providers` as alternatives for multi-provider scenarios.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a clear 'When to use' section stating the tool is for a single provider+tier combination, and explicitly names two sibling tools for multi-provider comparisons, offering both inclusion and exclusion criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/xmpuspus/cloudwright'

If you have feedback or need assistance with the MCP directory API, please join our Discord server