Servidor MCP

Stackcut

io.stackcut/stackcut

Qué hace este MCP

Analyzes SaaS and infrastructure stacks, finds lower-cost alternatives, compares vendor pricing, and produces savings or replacement plans.

audit_stack
Audit a stack (code + billing)
Use when the user wants their stack checked as a whole: several subscriptions, the paid services in a codebase, or a portfolio of products ('audit what we pay for', 'what can we cut?'). One line per service with vendor, plan, what they pay, seats, the features they use and usage (or evidence strings); add project for a portfolio and account for a shared bill. Per service: status (eligible = a cheaper path checked end to end; needs_info = likely cheaper but a check is open, so ask its questions; keep; no_recipe), the best path, right_size, overlaps, and levers that are not counted as savings. Totals keep prices the user confirmed apart from modeled list prices. If facts are missing, start_audit says which ones matter first. Send vendor names, feature names, numbers and prices only: never source code, secrets or raw invoices. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': ['services'], 'properties': {'services': {'type': 'array', 'items': {'type': 'object', 'required': ['vendor'], 'properties': {'name': {'type': 'string', 'maxLength': 200, 'description': 'detect.mjs output (ignored)'}, 'plan': {'type': 'string', 'maxLength': 100, 'description': "Their plan, e.g. 'Business Standard' (else read from the name or evidence)"}, 'seats': {'type': 'integer', 'maximum': 100000, 'minimum': 1, 'description': 'Paid seats'}, 'usage': {'type': 'object', 'properties': {'MAU': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'mau': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'mtu': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'apps': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'db_gb': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'files': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'seats': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'sites': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'videos': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'domains': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'inboxes': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'members': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'records': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'contacts': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'monitors': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'projects': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'sso_users': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'storage_gb': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'event_types': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'bandwidth_gb': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'history_days': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'sms_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'video_minutes': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'emails_per_day': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'vectors_stored': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'active_accounts': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'meeting_minutes': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'session_minutes': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'sso_connections': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'tasks_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'emails_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'errors_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'events_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'images_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'keywords_tracked': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'requests_per_day': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'scim_connections': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'tokens_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'call_participants': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'credits_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'gmv_usd_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'payouts_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'searches_per_hour': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'cpu_ms_per_request': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'disputes_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'proxy_gb_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'requests_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'searches_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'concurrent_sessions': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'pageviews_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'responses_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'tokens_in_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'characters_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'tokens_out_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'vcpu_hours_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'video_minutes_stored': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'credits_usd_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'gpu_seconds_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'revenue_usd_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'job_executions_per_day': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'object_reads_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'stream_hours_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'transactions_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'audio_minutes_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'browser_hours_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'cached_tokens_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'object_writes_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'phone_minutes_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'sandbox_hours_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'verifications_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'cache_commands_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'inbound_emails_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'job_executions_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'vector_queries_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'payout_volume_usd_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'vector_read_units_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'vector_write_units_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'video_minutes_delivered_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}}, 'description': 'Their usage, checked against each plan\'s caps (priced with published overage and add-ons). Units: seats, members, mau, emails_per_month, emails_per_day, contacts, domains, events_per_month, pageviews_per_month, errors_per_month, requests_per_month, requests_per_day, searches_per_month, cpu_ms_per_request, db_gb, storage_gb, bandwidth_gb, projects, sites, videos, video_minutes, responses_per_month, tasks_per_month, keywords_tracked, credits_per_month, history_days, apps, files, event_types, monitors, tokens_per_month, images_per_month, audio_minutes_per_month, characters_per_month, transactions_per_month, sandbox_hours_per_month, concurrent_sessions, session_minutes, call_participants, meeting_minutes, records, inboxes, tokens_in_per_month, tokens_out_per_month, cached_tokens_per_month, video_minutes_stored, video_minutes_delivered_per_month, gmv_usd_per_month, payouts_per_month, active_accounts, verifications_per_month, browser_hours_per_month, proxy_gb_per_month, job_executions_per_month, sso_connections, sso_users, inbound_emails_per_month, stream_hours_per_month, vcpu_hours_per_month, credits_usd_per_month, disputes_per_month, payout_volume_usd_per_month, object_writes_per_month, object_reads_per_month, job_executions_per_day, scim_connections, searches_per_hour, sms_per_month, vectors_stored, vector_queries_per_month, cache_commands_per_month, mtu, gpu_seconds_per_month, revenue_usd_per_month, phone_minutes_per_month, vector_read_units_per_month, vector_write_units_per_month (MAU is accepted for mau). Example: {"emails_per_month": 40000, "domains": 4, "db_gb": 3}. get_usage_questions says which units matter for a vendor and where the user finds each number.', 'additionalProperties': False}, 'vendor': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': "Vendor id from the scan (e.g. 'sendgrid') or a product name as on the invoice ('Airtable', 'Slack Pro')"}, 'account': {'type': 'string', 'maxLength': 100, 'minLength': 1, 'description': "Billing account key (e.g. 'supabase-org-main'): lines with the same vendor and key share one bill; different keys are separate bills. Give the bill once"}, 'billing': {'type': 'object', 'properties': {'scope': {'enum': ['dedicated', 'shared', 'unknown'], 'type': 'string', 'maxLength': 2000}, 'source': {'type': 'string', 'maxLength': 1000, 'minLength': 1}, 'account_id': {'type': 'string', 'maxLength': 200, 'minLength': 1}, 'allocated_monthly_usd': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'avoidable_monthly_usd': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'avoidability_confirmed': {'type': 'boolean'}, 'commitment_months_remaining': {'type': 'number', 'maximum': 120, 'minimum': 0}}, 'description': 'Billing evidence: scope (dedicated, shared or unknown), account_id (a non-secret alias; the account key), allocated_monthly_usd (attribution only, never a saving), avoidable_monthly_usd with avoidability_confirmed (what leaving actually removes from the bill; 0 is valid), commitment_months_remaining (non-refundable months left; 0 only when cancellable now) and source (a reference, no private contents). With billing, a path is eligible only once the avoidable amount, scope, commitment and source are all given', 'additionalProperties': False}, 'project': {'type': 'string', 'maxLength': 100, 'minLength': 1, 'description': "Which of their projects or products this line is for (portfolio audits): lines of one vendor across projects are audited as one account. Give each project's own usage on its line and the account's bill once"}, 'category': {'type': 'string', 'maxLength': 100, 'description': 'detect.mjs output (ignored)'}, 'evidence': {'type': 'array', 'items': {'type': 'string', 'maxLength': 500}, 'maxItems': 50, 'description': "Scan evidence labels and usage facts in words ('db 1.5 GB', '40,000 emails/mo', '37 domains')"}, 'confirmed': {'type': 'boolean', 'description': 'true when the user confirmed they pay for this (with plan: its list price counts as confirmed spend). Scanner-only lines are unconfirmed'}, 'confidence': {'type': 'string', 'maxLength': 20, 'description': "detect.mjs output: 'low' (only a config file) means no paid plan is assumed"}, 'in_catalog': {'type': 'boolean', 'description': 'detect.mjs output (ignored)'}, 'service_id': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': 'A distinct bill when the same vendor appears more than once (an account key, like account; lines with the same key are one bill)'}, 'last_active': {'type': 'string', 'maxLength': 100, 'description': "When this resource (project, app, account) was last used: an ISO date ('2026-03-10'), 'never', or '5 months ago'. 90+ days idle or never used gets a cleanup lever"}, 'shared_with': {'type': 'integer', 'maximum': 100000, 'minimum': 1, 'description': "How many products share this bill (one account, org or team), when only this product is audited: moving one product off it saves only what it adds to the bill, never the whole bill. monthly_spend_usd is then the whole account's bill"}, 'active_users': {'type': 'number', 'maximum': 1000000000, 'minimum': 0, 'description': 'People or accounts active in the last 30 days (0 = unused: cleanup levers and sanity checks)'}, 'features_used': {'type': 'array', 'items': {'type': 'string', 'maxLength': 200}, 'maxItems': 50, 'description': "Features the code or the user relies on; sizes and counts ('4,000 contacts') are read as usage"}, 'feature_counts': {'type': 'array', 'items': {'type': 'object'}, 'maxItems': 100, 'description': 'detect.mjs output (ignored)'}, 'files_referencing': {'type': 'integer', 'maximum': 1000000000000, 'minimum': 0, 'description': 'detect.mjs output: marks the line as scan-only (unconfirmed); never read as usage'}, 'monthly_spend_usd': {'type': 'number', 'maximum': 1000000, 'minimum': 0, 'description': 'What they pay per month for it, all seats, if known'}, 'revenue_usd_per_month': {'type': 'number', 'maximum': 1000000000, 'minimum': 0, 'description': "The product's revenue per month (context for sanity checks: no revenue, cost per user, fees vs revenue; never a cap)"}, 'replacement_validation': {'type': 'object', 'required': ['path_id', 'capacity_and_price_confirmed', 'source'], 'properties': {'source': {'type': 'string', 'maxLength': 1000, 'minLength': 1, 'description': 'Where the check comes from (usage report, pricing page, quote); no private contents'}, 'path_id': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': 'The path id (from find_alternatives or audit_stack)'}, 'capacity_and_price_confirmed': {'type': 'boolean', 'description': 'true only after checking the price, capacity, burst limits and required add-ons'}}, 'description': "A replacement path the user checked themselves: its current price, capacity, burst limits and paid add-ons against their usage. It answers that path's capacity checks (never its must-haves) and ranks it first", 'additionalProperties': False}}, 'additionalProperties': False}, 'maxItems': 200, 'minItems': 1}, 'limit_paths': {'type': 'integer', 'default': 3, 'maximum': 8, 'minimum': 1}, 'active_users': {'type': 'number', 'maximum': 1000000000, 'minimum': 0, 'description': 'People or accounts active in the last 30 days (0 = unused: cleanup levers and sanity checks)'}, 'revenue_usd_per_month': {'type': 'number', 'maximum': 1000000000, 'minimum': 0, 'description': "The product's revenue per month (context for sanity checks: no revenue, cost per user, fees vs revenue; never a cap)"}}, 'additionalProperties': False}
choose_stack
Choose the most cost-effective stack
Use when the user is picking vendors for something they're building: 'cheapest database for 20k users', 'Resend or Postmark at 60,000 emails a month?', 'what will auth cost at 10k MAU?'. Give each job with its volumes and must-have features; every tier of every indexed vendor is priced at those volumes and the cheapest valid tier wins. A pick 'fits' only when every volume is within published caps or priced overage, no published limit is broken, each must-have is included in that plan or priced as its add-on, and the price was checked within 120 days; anything else comes back as a check or a question. total keeps proven, estimated and unpriced jobs apart. Pass scales (MAU) for cost curves and break-evens; with no MAU elsewhere, the smallest scale is the MAU priced. budget_monthly_usd tests a budget. For a whole product brief, use plan_stack_from_spec. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': ['needs'], 'properties': {'needs': {'type': 'array', 'items': {'type': 'object', 'required': ['job'], 'properties': {'job': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': "A job id from list_stack_jobs (llm_inference, image_generation_api, video_delivery, object_storage, sandbox_compute, browser_automation, job_queue, auth_b2b, email_inbound, identity_verification, marketplace_payouts, database, auth, hosting, email_transactional, …) or plain words ('send email', 'video hosting (HLS)', 'KYC'). Unknown or ambiguous jobs come back in unsupported_jobs, never as an error"}, 'volume': {'type': 'object', 'required': ['amount', 'unit'], 'properties': {'unit': {'enum': ['seats', 'members', 'mau', 'emails_per_month', 'emails_per_day', 'contacts', 'domains', 'events_per_month', 'pageviews_per_month', 'errors_per_month', 'requests_per_month', 'requests_per_day', 'searches_per_month', 'cpu_ms_per_request', 'db_gb', 'storage_gb', 'bandwidth_gb', 'projects', 'sites', 'videos', 'video_minutes', 'responses_per_month', 'tasks_per_month', 'keywords_tracked', 'credits_per_month', 'history_days', 'apps', 'files', 'event_types', 'monitors', 'tokens_per_month', 'images_per_month', 'audio_minutes_per_month', 'characters_per_month', 'transactions_per_month', 'sandbox_hours_per_month', 'concurrent_sessions', 'session_minutes', 'call_participants', 'meeting_minutes', 'records', 'inboxes', 'tokens_in_per_month', 'tokens_out_per_month', 'cached_tokens_per_month', 'video_minutes_stored', 'video_minutes_delivered_per_month', 'gmv_usd_per_month', 'payouts_per_month', 'active_accounts', 'verifications_per_month', 'browser_hours_per_month', 'proxy_gb_per_month', 'job_executions_per_month', 'sso_connections', 'sso_users', 'inbound_emails_per_month', 'stream_hours_per_month', 'vcpu_hours_per_month', 'credits_usd_per_month', 'disputes_per_month', 'payout_volume_usd_per_month', 'object_writes_per_month', 'object_reads_per_month', 'job_executions_per_day', 'scim_connections', 'searches_per_hour', 'sms_per_month', 'vectors_stored', 'vector_queries_per_month', 'cache_commands_per_month', 'mtu', 'gpu_seconds_per_month', 'revenue_usd_per_month', 'phone_minutes_per_month', 'vector_read_units_per_month', 'vector_write_units_per_month', 'MAU', 'tokens', 'tokens_in', 'tokens_out', 'cached_tokens', 'images', 'video_minutes_delivered', 'gb_stored', 'gb_egress', 'transactions', 'gmv_usd', 'sandbox_seconds', 'sandbox_hours', 'vm_hours', 'vcpu_hours', 'browser_hours', 'proxy_gb', 'job_executions', 'verifications', 'inbound_emails', 'emails', 'events', 'errors', 'exceptions', 'requests', 'pageviews', 'searches', 'payouts', 'credits_usd', 'stream_hours', 'audio_minutes', 'characters', 'payout_volume_usd', 'disputes', 'object_writes', 'object_reads', 'sms', 'vectors', 'vector_queries', 'cache_commands', 'gpu_seconds', 'gpu_hours', 'revenue_usd', 'phone_minutes'], 'type': 'string', 'maxLength': 2000, 'description': 'A units.json unit, or an alias: tokens_in, tokens_out, images, gb_stored, gb_egress, transactions, gmv_usd, sandbox_seconds, sandbox_hours, vcpu_hours, browser_hours, job_executions, verifications, inbound_emails, video_minutes_delivered, sso_connections, sso_users, emails, events, requests, credits_usd, MAU (= mau). *_per_month units are monthly, *_per_day daily, *_gb and video_minutes_stored are totals.'}, 'amount': {'type': 'number', 'maximum': 1000000000000000, 'minimum': 0}}, 'additionalProperties': False}, 'volumes': {'type': 'array', 'items': {'type': 'object', 'required': ['amount', 'unit'], 'properties': {'unit': {'enum': ['seats', 'members', 'mau', 'emails_per_month', 'emails_per_day', 'contacts', 'domains', 'events_per_month', 'pageviews_per_month', 'errors_per_month', 'requests_per_month', 'requests_per_day', 'searches_per_month', 'cpu_ms_per_request', 'db_gb', 'storage_gb', 'bandwidth_gb', 'projects', 'sites', 'videos', 'video_minutes', 'responses_per_month', 'tasks_per_month', 'keywords_tracked', 'credits_per_month', 'history_days', 'apps', 'files', 'event_types', 'monitors', 'tokens_per_month', 'images_per_month', 'audio_minutes_per_month', 'characters_per_month', 'transactions_per_month', 'sandbox_hours_per_month', 'concurrent_sessions', 'session_minutes', 'call_participants', 'meeting_minutes', 'records', 'inboxes', 'tokens_in_per_month', 'tokens_out_per_month', 'cached_tokens_per_month', 'video_minutes_stored', 'video_minutes_delivered_per_month', 'gmv_usd_per_month', 'payouts_per_month', 'active_accounts', 'verifications_per_month', 'browser_hours_per_month', 'proxy_gb_per_month', 'job_executions_per_month', 'sso_connections', 'sso_users', 'inbound_emails_per_month', 'stream_hours_per_month', 'vcpu_hours_per_month', 'credits_usd_per_month', 'disputes_per_month', 'payout_volume_usd_per_month', 'object_writes_per_month', 'object_reads_per_month', 'job_executions_per_day', 'scim_connections', 'searches_per_hour', 'sms_per_month', 'vectors_stored', 'vector_queries_per_month', 'cache_commands_per_month', 'mtu', 'gpu_seconds_per_month', 'revenue_usd_per_month', 'phone_minutes_per_month', 'vector_read_units_per_month', 'vector_write_units_per_month', 'MAU', 'tokens', 'tokens_in', 'tokens_out', 'cached_tokens', 'images', 'video_minutes_delivered', 'gb_stored', 'gb_egress', 'transactions', 'gmv_usd', 'sandbox_seconds', 'sandbox_hours', 'vm_hours', 'vcpu_hours', 'browser_hours', 'proxy_gb', 'job_executions', 'verifications', 'inbound_emails', 'emails', 'events', 'errors', 'exceptions', 'requests', 'pageviews', 'searches', 'payouts', 'credits_usd', 'stream_hours', 'audio_minutes', 'characters', 'payout_volume_usd', 'disputes', 'object_writes', 'object_reads', 'sms', 'vectors', 'vector_queries', 'cache_commands', 'gpu_seconds', 'gpu_hours', 'revenue_usd', 'phone_minutes'], 'type': 'string', 'maxLength': 2000, 'description': 'A units.json unit, or an alias: tokens_in, tokens_out, images, gb_stored, gb_egress, transactions, gmv_usd, sandbox_seconds, sandbox_hours, vcpu_hours, browser_hours, job_executions, verifications, inbound_emails, video_minutes_delivered, sso_connections, sso_users, emails, events, requests, credits_usd, MAU (= mau). *_per_month units are monthly, *_per_day daily, *_gb and video_minutes_stored are totals.'}, 'amount': {'type': 'number', 'maximum': 1000000000000000, 'minimum': 0}}, 'additionalProperties': False}, 'maxItems': 8, 'minItems': 1, 'description': "Several dimensions at once, e.g. [{amount: 15000000, unit: 'tokens_in'}, {amount: 7500000, unit: 'tokens_out'}]"}, 'features': {'type': 'array', 'items': {'type': 'string', 'maxLength': 200, 'minLength': 1}, 'maxItems': 20, 'description': "Must-haves, e.g. ['Custom domain', 'CAPTCHA solving', 'platform holds funds', 'refunds enabled', 'unbounded sessions', '2 vCPU / 4 GiB', 'gpt-6-sol']. Sizes and counts ('30 GB database') are checked as volumes; a model or plan name pins that model; SSO, SOC 2, audit logs and region needs are listed as unverified requirements"}, 'per_user': {'type': 'array', 'items': {'type': 'object', 'required': ['amount', 'unit'], 'properties': {'unit': {'enum': ['seats', 'members', 'mau', 'emails_per_month', 'emails_per_day', 'contacts', 'domains', 'events_per_month', 'pageviews_per_month', 'errors_per_month', 'requests_per_month', 'requests_per_day', 'searches_per_month', 'cpu_ms_per_request', 'db_gb', 'storage_gb', 'bandwidth_gb', 'projects', 'sites', 'videos', 'video_minutes', 'responses_per_month', 'tasks_per_month', 'keywords_tracked', 'credits_per_month', 'history_days', 'apps', 'files', 'event_types', 'monitors', 'tokens_per_month', 'images_per_month', 'audio_minutes_per_month', 'characters_per_month', 'transactions_per_month', 'sandbox_hours_per_month', 'concurrent_sessions', 'session_minutes', 'call_participants', 'meeting_minutes', 'records', 'inboxes', 'tokens_in_per_month', 'tokens_out_per_month', 'cached_tokens_per_month', 'video_minutes_stored', 'video_minutes_delivered_per_month', 'gmv_usd_per_month', 'payouts_per_month', 'active_accounts', 'verifications_per_month', 'browser_hours_per_month', 'proxy_gb_per_month', 'job_executions_per_month', 'sso_connections', 'sso_users', 'inbound_emails_per_month', 'stream_hours_per_month', 'vcpu_hours_per_month', 'credits_usd_per_month', 'disputes_per_month', 'payout_volume_usd_per_month', 'object_writes_per_month', 'object_reads_per_month', 'job_executions_per_day', 'scim_connections', 'searches_per_hour', 'sms_per_month', 'vectors_stored', 'vector_queries_per_month', 'cache_commands_per_month', 'mtu', 'gpu_seconds_per_month', 'revenue_usd_per_month', 'phone_minutes_per_month', 'vector_read_units_per_month', 'vector_write_units_per_month', 'MAU', 'tokens', 'tokens_in', 'tokens_out', 'cached_tokens', 'images', 'video_minutes_delivered', 'gb_stored', 'gb_egress', 'transactions', 'gmv_usd', 'sandbox_seconds', 'sandbox_hours', 'vm_hours', 'vcpu_hours', 'browser_hours', 'proxy_gb', 'job_executions', 'verifications', 'inbound_emails', 'emails', 'events', 'errors', 'exceptions', 'requests', 'pageviews', 'searches', 'payouts', 'credits_usd', 'stream_hours', 'audio_minutes', 'characters', 'payout_volume_usd', 'disputes', 'object_writes', 'object_reads', 'sms', 'vectors', 'vector_queries', 'cache_commands', 'gpu_seconds', 'gpu_hours', 'revenue_usd', 'phone_minutes'], 'type': 'string', 'maxLength': 2000, 'description': 'A units.json unit, or an alias: tokens_in, tokens_out, images, gb_stored, gb_egress, transactions, gmv_usd, sandbox_seconds, sandbox_hours, vcpu_hours, browser_hours, job_executions, verifications, inbound_emails, video_minutes_delivered, sso_connections, sso_users, emails, events, requests, credits_usd, MAU (= mau). *_per_month units are monthly, *_per_day daily, *_gb and video_minutes_stored are totals.'}, 'amount': {'type': 'number', 'maximum': 1000000000000000, 'minimum': 0}}, 'additionalProperties': False}, 'maxItems': 8, 'minItems': 1, 'description': "Volumes per monthly active user per month, e.g. [{amount: 6, unit: 'images'}]; multiplied by MAU (from scales, a mau volume or the project text)"}, 'peak_volume': {'type': 'object', 'required': ['amount', 'unit'], 'properties': {'unit': {'enum': ['emails_per_day', 'requests_per_day', 'requests_per_second'], 'type': 'string', 'maxLength': 2000}, 'amount': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}}, 'description': "Peak or burst requirement (1.6.0), e.g. {amount: 1500, unit: 'emails_per_day'} for a launch day. Checked against a tier's published daily cap where the index has one; otherwise it stays an open check (the index doesn't prove burst or rate limits), so no option is a plain fit", 'additionalProperties': False}, 'sandbox_size': {'type': 'object', 'properties': {'vcpu': {'type': 'number', 'maximum': 512, 'minimum': 0.1}, 'ram_gib': {'type': 'number', 'maximum': 4096, 'minimum': 0.1}}, 'description': 'Sandbox size for sandbox_compute', 'additionalProperties': False}, 'avg_amount_usd': {'type': 'number', 'maximum': 10000000, 'minimum': 0, 'description': 'Average payment in USD; with transactions it prices payment fees'}}, 'additionalProperties': False}, 'maxItems': 12, 'minItems': 1}, 'prefer': {'enum': ['cheapest', 'managed', 'open_source'], 'type': 'string', 'default': 'cheapest', 'maxLength': 2000, 'description': 'managed leaves out self-hosted options'}, 'scales': {'type': 'array', 'items': {'type': 'number', 'maximum': 1000000000, 'minimum': 0.001}, 'maxItems': 6, 'minItems': 1, 'description': 'Price the stack at several scales, e.g. [1000, 20000, 200000] MAU (scale_by mau) or [1, 10, 100] (scale_by multiplier): per-job cost curve, tier changes and break-even points between options'}, 'project': {'type': 'string', 'maxLength': 4000, 'description': "What is being built. Volumes written here ('1,200,000 preview images/mo', '20k MAU') are used and echoed as assumptions. Say 'personal' or 'hobby' if it is non-commercial; otherwise plans that forbid commercial use (e.g. Vercel Hobby) are blocked."}, 'scale_by': {'enum': ['mau', 'multiplier'], 'type': 'string', 'default': 'mau', 'maxLength': 2000, 'description': 'mau: scales are monthly active users (per_user volumes × MAU; other monthly volumes and sizes grow in proportion to the MAU they were given at); multiplier: every monthly volume and size is multiplied'}, 'limit_per_job': {'type': 'integer', 'default': 4, 'maximum': 10, 'minimum': 1}, 'unit_economics': {'type': 'object', 'properties': {'billing': {'enum': ['monthly', 'one_time'], 'type': 'string', 'default': 'monthly', 'maxLength': 2000, 'description': 'one_time: price_usd per purchase, conversion_rate = purchases per MAU per month'}, 'price_usd': {'type': 'number', 'maximum': 1000000, 'minimum': 0, 'description': 'What a paying user pays'}, 'conversion_rate': {'type': 'number', 'maximum': 1, 'minimum': 0, 'description': 'Share of MAU who pay, e.g. 0.03'}, 'revenue_per_mau': {'type': 'number', 'maximum': 10000, 'minimum': 0, 'description': 'Average monthly revenue per MAU (instead of price_usd × conversion_rate)'}, 'variable_cost_alert_pct': {'type': 'number', 'default': 20, 'maximum': 100, 'minimum': 1, 'description': 'Flag jobs whose monthly cost is above this % of revenue'}}, 'description': 'Revenue model for gross margin per scale: price_usd with conversion_rate, or revenue_per_mau', 'additionalProperties': False}, 'budget_monthly_usd': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}}, 'additionalProperties': False}
find_alternatives
Find alternatives for a subscription
Use when the user names one product they pay for and asks for something cheaper, whether it's worth it, or what to switch to: 'cheaper than Typeform?', 'is Semrush worth $139 a month for us?', 'we pay $90 for SendGrid'. Pass what they pay (monthly_spend_usd), seats, the features they use and their usage (usage, or evidence such as '40,000 emails/mo') so each plan's caps can be checked. Returns ranked paths re-costed at their price, including a cheaper plan of the same vendor (right_size). A path with fit 'fits' passed every check; a 'check' path is a candidate with open checks, so ask its questions before recommending it. status, why and questions say what is still missing. Savings are modeled from public list prices. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': ['vendor'], 'properties': {'plan': {'type': 'string', 'maxLength': 100, 'description': "Their plan, e.g. 'Essential' (else read from the vendor name)"}, 'limit': {'type': 'integer', 'default': 8, 'maximum': 20, 'minimum': 1}, 'seats': {'type': 'integer', 'maximum': 100000, 'minimum': 1, 'description': 'Paid seats; per-seat prices on both sides scale with it'}, 'usage': {'type': 'object', 'properties': {'MAU': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'mau': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'mtu': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'apps': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'db_gb': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'files': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'seats': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'sites': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'videos': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'domains': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'inboxes': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'members': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'records': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'contacts': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'monitors': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'projects': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'sso_users': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'storage_gb': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'event_types': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'bandwidth_gb': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'history_days': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'sms_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'video_minutes': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'emails_per_day': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'vectors_stored': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'active_accounts': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'meeting_minutes': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'session_minutes': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'sso_connections': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'tasks_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'emails_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'errors_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'events_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'images_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'keywords_tracked': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'requests_per_day': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'scim_connections': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'tokens_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'call_participants': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'credits_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'gmv_usd_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'payouts_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'searches_per_hour': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'cpu_ms_per_request': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'disputes_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'proxy_gb_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'requests_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'searches_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'concurrent_sessions': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'pageviews_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'responses_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'tokens_in_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'characters_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'tokens_out_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'vcpu_hours_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'video_minutes_stored': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'credits_usd_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'gpu_seconds_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'revenue_usd_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'job_executions_per_day': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'object_reads_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'stream_hours_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'transactions_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'audio_minutes_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'browser_hours_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'cached_tokens_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'object_writes_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'phone_minutes_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'sandbox_hours_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'verifications_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'cache_commands_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'inbound_emails_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'job_executions_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'vector_queries_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'payout_volume_usd_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'vector_read_units_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'vector_write_units_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'video_minutes_delivered_per_month': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}}, 'description': 'Their usage, checked against each plan\'s caps (priced with published overage and add-ons). Units: seats, members, mau, emails_per_month, emails_per_day, contacts, domains, events_per_month, pageviews_per_month, errors_per_month, requests_per_month, requests_per_day, searches_per_month, cpu_ms_per_request, db_gb, storage_gb, bandwidth_gb, projects, sites, videos, video_minutes, responses_per_month, tasks_per_month, keywords_tracked, credits_per_month, history_days, apps, files, event_types, monitors, tokens_per_month, images_per_month, audio_minutes_per_month, characters_per_month, transactions_per_month, sandbox_hours_per_month, concurrent_sessions, session_minutes, call_participants, meeting_minutes, records, inboxes, tokens_in_per_month, tokens_out_per_month, cached_tokens_per_month, video_minutes_stored, video_minutes_delivered_per_month, gmv_usd_per_month, payouts_per_month, active_accounts, verifications_per_month, browser_hours_per_month, proxy_gb_per_month, job_executions_per_month, sso_connections, sso_users, inbound_emails_per_month, stream_hours_per_month, vcpu_hours_per_month, credits_usd_per_month, disputes_per_month, payout_volume_usd_per_month, object_writes_per_month, object_reads_per_month, job_executions_per_day, scim_connections, searches_per_hour, sms_per_month, vectors_stored, vector_queries_per_month, cache_commands_per_month, mtu, gpu_seconds_per_month, revenue_usd_per_month, phone_minutes_per_month, vector_read_units_per_month, vector_write_units_per_month (MAU is accepted for mau). Example: {"emails_per_month": 40000, "domains": 4, "db_gb": 3}. get_usage_questions says which units matter for a vendor and where the user finds each number.', 'additionalProperties': False}, 'vendor': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': "Product name as on the invoice, e.g. 'Typeform', 'Slack Pro', 'HubSpot Sales Hub Starter'"}, 'billing': {'type': 'object', 'properties': {'scope': {'enum': ['dedicated', 'shared', 'unknown'], 'type': 'string', 'maxLength': 2000}, 'source': {'type': 'string', 'maxLength': 1000, 'minLength': 1}, 'account_id': {'type': 'string', 'maxLength': 200, 'minLength': 1}, 'allocated_monthly_usd': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'avoidable_monthly_usd': {'type': 'number', 'maximum': 1000000000000, 'minimum': 0}, 'avoidability_confirmed': {'type': 'boolean'}, 'commitment_months_remaining': {'type': 'number', 'maximum': 120, 'minimum': 0}}, 'description': 'Billing evidence: scope (dedicated, shared or unknown), account_id (a non-secret alias; the account key), allocated_monthly_usd (attribution only, never a saving), avoidable_monthly_usd with avoidability_confirmed (what leaving actually removes from the bill; 0 is valid), commitment_months_remaining (non-refundable months left; 0 only when cancellable now) and source (a reference, no private contents). With billing, a path is eligible only once the avoidable amount, scope, commitment and source are all given', 'additionalProperties': False}, 'evidence': {'type': 'array', 'items': {'type': 'string', 'maxLength': 500}, 'maxItems': 50, 'description': "Usage facts in words, read best effort: 'db 1.5 GB', '40,000 emails/mo', '37 domains', '3,000 MAU', 'shared by 40 projects'"}, 'confirmed': {'type': 'boolean', 'description': 'true when the user confirmed they pay for this (with plan: its list price counts as confirmed spend). Scanner-only lines are unconfirmed'}, 'last_active': {'type': 'string', 'maxLength': 100, 'description': "When this resource (project, app, account) was last used: an ISO date ('2026-03-10'), 'never', or '5 months ago'. 90+ days idle or never used gets a cleanup lever"}, 'shared_with': {'type': 'integer', 'maximum': 100000, 'minimum': 1, 'description': "How many products share this bill (one account, org or team), when only this product is audited: moving one product off it saves only what it adds to the bill, never the whole bill. monthly_spend_usd is then the whole account's bill"}, 'active_users': {'type': 'number', 'maximum': 1000000000, 'minimum': 0, 'description': 'People or accounts active in the last 30 days (0 = unused: cleanup levers and sanity checks)'}, 'features_used': {'type': 'array', 'items': {'type': 'string', 'maxLength': 200}, 'maxItems': 50, 'description': "Features they actually use; sizes and counts ('4,000 contacts', 'videos over 5 minutes') are read as usage"}, 'monthly_spend_usd': {'type': 'number', 'maximum': 1000000, 'minimum': 0, 'description': 'What they pay per month today, all seats (replaces the modeled baseline)'}, 'revenue_usd_per_month': {'type': 'number', 'maximum': 1000000000, 'minimum': 0, 'description': "The product's revenue per month (context for sanity checks: no revenue, cost per user, fees vs revenue; never a cap)"}, 'replacement_validation': {'type': 'object', 'required': ['path_id', 'capacity_and_price_confirmed', 'source'], 'properties': {'source': {'type': 'string', 'maxLength': 1000, 'minLength': 1, 'description': 'Where the check comes from (usage report, pricing page, quote); no private contents'}, 'path_id': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': 'The path id (from find_alternatives or audit_stack)'}, 'capacity_and_price_confirmed': {'type': 'boolean', 'description': 'true only after checking the price, capacity, burst limits and required add-ons'}}, 'description': "A replacement path the user checked themselves: its current price, capacity, burst limits and paid add-ons against their usage. It answers that path's capacity checks (never its must-haves) and ranks it first", 'additionalProperties': False}}, 'additionalProperties': False}
get_build_packet
Get a build packet (Replace with AI)
Use when the user wants to replace a tool by building their own (Replace with AI): returns SPEC.md, AGENTS.md and the runbook files a coding agent builds from, for a recipe with a build path. A recipe without one returns the assessment files for validating a switch or downgrade instead, never a spec to clone a service. Check packet_kind and next_step before acting. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': ['recipe_id'], 'properties': {'recipe_id': {'type': 'string', 'maxLength': 200, 'minLength': 1}}, 'additionalProperties': False}
get_detection_rules
Get code detection rules
Rules for finding paid services in a codebase on the user's own machine: package names, environment variable name patterns, config files, API hosts and feature patterns for about 100 vendors. Apply them locally and send only the vendor and feature names you found to audit_stack, never code or secret values. Names without rules come back under unknown. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': [], 'properties': {'vendors': {'type': 'array', 'items': {'type': 'string', 'maxLength': 200, 'minLength': 1}, 'maxItems': 200, 'description': 'Only these vendors, by id or name (default: all)'}}, 'additionalProperties': False}
get_exit_plan
How to cancel a subscription
Use when the user wants to cancel, unsubscribe from, pause or pay less for something they subscribe to: streaming, music, news, dating, cloud storage, AI tools, apps or business software ('cancel YouTube TV', 'how do I get out of Adobe', 'stop my Audible'). Returns Stackcut's exit plan: every way to cancel by who bills them (the company, Apple, Google Play, a partner or a contract), the steps with the words to expect on screen, when access ends, notice periods, fees and refunds, what to export first, cheaper ways to keep it, and notes for an agent, each fact sourced to the vendor's own page with a check date. Pass billed_by when known (the name on their card statement or receipt) and renewal_date to get the last safe day to cancel. Never cancel for the user without their go-ahead: they sign in, see any offer, and confirm the final step. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': ['service'], 'properties': {'service': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': "The subscription, e.g. 'YouTube TV', 'Adobe Creative Cloud', 'disneyplus.com'"}, 'billed_by': {'enum': ['direct_web', 'direct_app', 'apple_app_store', 'google_play', 'amazon', 'roku', 'paypal', 'carrier_or_isp', 'reseller_or_partner', 'sales_contract', 'unknown'], 'type': 'string', 'maxLength': 2000, 'description': "Who charges them (their card statement or receipt says): the company itself (direct_web), Apple, Google Play, Amazon, a phone/TV provider, a partner, or a business contract. Leave out or 'unknown' to get every route and the question to ask"}, 'renewal_date': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'maxLength': 2000, 'description': 'Next renewal date, YYYY-MM-DD: adds the last safe day to cancel from the documented notice period'}}, 'additionalProperties': False}
get_my_plan
Get the user's Stackcut savings plan
Use only when the user gives you a Stackcut agent code (it starts with sca_; they copy it from 'Send to my agent' on stackcut.io). Returns their own savings plan: every subscription with its verdict, the proven saving, the proof (receipts, card charges or a sourced price), steps and checks. Walk them through it from the biggest proven saving down and ask before any cancel, purchase or sign-up. The code is read-only and expires. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': ['code'], 'properties': {'code': {'type': 'string', 'maxLength': 200, 'description': 'The agent code from stackcut.io, e.g. sca_…'}}, 'additionalProperties': False}
get_recipe
Get a recipe
Full detail for one recipe from search_recipes: every replacement path with modeled first-year savings, monthly cost, setup time and upkeep, what is out of scope, checks to run before switching, how to leave the current vendor (cancel steps, refunds, exports, what you lose), step-by-step playbooks, sources, and Stackcut's own lab results where they exist (not customer results). Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': "Recipe id from search_recipes, e.g. 'crm-pipeline'"}}, 'additionalProperties': False}
get_usage_questions
Usage questions for vendors
Before an audit: which usage numbers decide each vendor's answer (emails a month, domains, database size, seats…), where the user finds each one (dashboard page, API, export), and ready-to-ask questions. Units already stated in context are marked as given. Pass the answers to audit_stack or find_alternatives as usage and features_used. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': ['vendors'], 'properties': {'context': {'type': 'string', 'maxLength': 2000, 'description': "Optional: what is already known, in words (e.g. 'about 40,000 emails/mo, 4 domains'); units it states are marked as given and not asked again"}, 'vendors': {'type': 'array', 'items': {'type': 'string', 'maxLength': 200, 'minLength': 1}, 'maxItems': 30, 'minItems': 1, 'description': "Vendors they pay for, by name or id, e.g. ['Resend', 'Supabase Pro']"}}, 'additionalProperties': False}
get_workflow_recipe
Get an end-to-end workflow recipe
One runbook from search_workflow_recipes in full: the evidence to collect, keep/downsize/consolidate/migrate/build/retire decisions, ordered steps, acceptance tests, rollout, rollback, maintenance, costs still unresolved, and scoped starter templates with their download digest. A reviewed playbook is not a completed customer migration. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': "Workflow id from search_workflow_recipes, e.g. 'portfolio-shared-billing'"}}, 'additionalProperties': False}
leaderboard
Savings leaderboard
The top replacement paths across the catalog by modeled first-year savings, payback months, or how often people and agents used them. Leaves out partial replacements unless include_partial, and never lists trials, one-time credits, expiring or non-commercial plans. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'default': 10, 'maximum': 50, 'minimum': 1}, 'metric': {'enum': ['savings', 'payback', 'popular'], 'type': 'string', 'default': 'savings', 'maxLength': 2000}, 'category': {'type': 'string', 'maxLength': 100, 'minLength': 1}, 'path_type': {'enum': ['switch', 'downgrade', 'open_source', 'per_use', 'agent_skill', 'build', 'bundled'], 'type': 'string', 'maxLength': 2000}, 'include_partial': {'type': 'boolean', 'default': False}}, 'additionalProperties': False}
list_categories
List categories
The catalog's categories with how many recipes each has and the best modeled first-year saving in each. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': False}
list_stack_jobs
List stack jobs
The jobs choose_stack can compare (database, auth, hosting, transactional and inbound email, object storage, LLM APIs, payments, sandboxes, browser automation, queues…) with how many vendors each has, plus the volume units and aliases it accepts. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': False}
plan_stack_from_spec
Plan a stack from a product brief
Use when the user shares a product brief or spec and asks what to build it with or what it will cost. Works out the jobs the brief needs (what it rules out, plans for later or already has is never priced), the volumes from its numbers or listed default rates, and its budget; prices the stack at several scales with choose_stack; and returns SPEC.md, AGENTS.md and a manifest for a coding agent. Keyword rules over the brief, no model call: when total.hypothetical is true, confirm the assumed jobs and volumes with the user before quoting the cost. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': ['spec'], 'properties': {'spec': {'type': 'string', 'maxLength': 20000, 'minLength': 1, 'description': 'The product brief (markdown or plain text, up to 20,000 characters): what it does, who uses it, how it makes money, any numbers you know (users, conversion, prices, volumes). Never paste secrets or personal data.'}, 'prefer': {'enum': ['cheapest', 'managed', 'open_source'], 'type': 'string', 'default': 'cheapest', 'maxLength': 2000}, 'scales': {'type': 'array', 'items': {'type': 'number', 'maximum': 1000000000, 'minimum': 1}, 'default': [1000, 20000, 200000], 'maxItems': 5, 'minItems': 1, 'description': 'MAU targets to price, default [1000, 20000, 200000]'}, 'add_jobs': {'type': 'array', 'items': {'type': 'string', 'maxLength': 200, 'minLength': 1}, 'maxItems': 12, 'description': "Jobs to add that the brief doesn't mention"}, 'overrides': {'type': 'array', 'items': {'type': 'object', 'required': ['job', 'unit', 'amount'], 'properties': {'job': {'type': 'string', 'maxLength': 200, 'minLength': 1}, 'unit': {'enum': ['seats', 'members', 'mau', 'emails_per_month', 'emails_per_day', 'contacts', 'domains', 'events_per_month', 'pageviews_per_month', 'errors_per_month', 'requests_per_month', 'requests_per_day', 'searches_per_month', 'cpu_ms_per_request', 'db_gb', 'storage_gb', 'bandwidth_gb', 'projects', 'sites', 'videos', 'video_minutes', 'responses_per_month', 'tasks_per_month', 'keywords_tracked', 'credits_per_month', 'history_days', 'apps', 'files', 'event_types', 'monitors', 'tokens_per_month', 'images_per_month', 'audio_minutes_per_month', 'characters_per_month', 'transactions_per_month', 'sandbox_hours_per_month', 'concurrent_sessions', 'session_minutes', 'call_participants', 'meeting_minutes', 'records', 'inboxes', 'tokens_in_per_month', 'tokens_out_per_month', 'cached_tokens_per_month', 'video_minutes_stored', 'video_minutes_delivered_per_month', 'gmv_usd_per_month', 'payouts_per_month', 'active_accounts', 'verifications_per_month', 'browser_hours_per_month', 'proxy_gb_per_month', 'job_executions_per_month', 'sso_connections', 'sso_users', 'inbound_emails_per_month', 'stream_hours_per_month', 'vcpu_hours_per_month', 'credits_usd_per_month', 'disputes_per_month', 'payout_volume_usd_per_month', 'object_writes_per_month', 'object_reads_per_month', 'job_executions_per_day', 'scim_connections', 'searches_per_hour', 'sms_per_month', 'vectors_stored', 'vector_queries_per_month', 'cache_commands_per_month', 'mtu', 'gpu_seconds_per_month', 'revenue_usd_per_month', 'phone_minutes_per_month', 'vector_read_units_per_month', 'vector_write_units_per_month', 'MAU', 'tokens', 'tokens_in', 'tokens_out', 'cached_tokens', 'images', 'video_minutes_delivered', 'gb_stored', 'gb_egress', 'transactions', 'gmv_usd', 'sandbox_seconds', 'sandbox_hours', 'vm_hours', 'vcpu_hours', 'browser_hours', 'proxy_gb', 'job_executions', 'verifications', 'inbound_emails', 'emails', 'events', 'errors', 'exceptions', 'requests', 'pageviews', 'searches', 'payouts', 'credits_usd', 'stream_hours', 'audio_minutes', 'characters', 'payout_volume_usd', 'disputes', 'object_writes', 'object_reads', 'sms', 'vectors', 'vector_queries', 'cache_commands', 'gpu_seconds', 'gpu_hours', 'revenue_usd', 'phone_minutes'], 'type': 'string', 'maxLength': 2000}, 'basis': {'enum': ['per_user', 'total'], 'type': 'string', 'default': 'per_user', 'maxLength': 2000}, 'amount': {'type': 'number', 'maximum': 1000000000000000, 'minimum': 0}}, 'additionalProperties': False}, 'maxItems': 40, 'description': 'Edit the derived assumptions: a volume per MAU per month (per_user) or a fixed monthly total for a job'}, 'exclude_jobs': {'type': 'array', 'items': {'type': 'string', 'maxLength': 200, 'minLength': 1}, 'maxItems': 20, 'description': 'Derived jobs to drop (job ids)'}, 'limit_per_job': {'type': 'integer', 'default': 3, 'maximum': 10, 'minimum': 1}, 'unit_economics': {'type': 'object', 'properties': {'billing': {'enum': ['monthly', 'one_time'], 'type': 'string', 'default': 'monthly', 'maxLength': 2000, 'description': 'one_time: price_usd per purchase, conversion_rate = purchases per MAU per month'}, 'price_usd': {'type': 'number', 'maximum': 1000000, 'minimum': 0, 'description': 'What a paying user pays'}, 'conversion_rate': {'type': 'number', 'maximum': 1, 'minimum': 0, 'description': 'Share of MAU who pay, e.g. 0.03'}, 'revenue_per_mau': {'type': 'number', 'maximum': 10000, 'minimum': 0, 'description': 'Average monthly revenue per MAU (instead of price_usd × conversion_rate)'}, 'variable_cost_alert_pct': {'type': 'number', 'default': 20, 'maximum': 100, 'minimum': 1, 'description': 'Flag jobs whose monthly cost is above this % of revenue'}}, 'description': 'Revenue model for gross margin per scale: price_usd with conversion_rate, or revenue_per_mau', 'additionalProperties': False}}, 'additionalProperties': False}
report_exit_outcome
Report how a cancellation went
Only after the user confirms what happened: record that a cancellation went through, that they kept the service for less, that they got stuck, or that the steps had changed (and at which step). Adds one to anonymous public counters that keep the cancel library current; stores no personal data and no free text. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Esquema de entrada
{'type': 'object', 'required': ['service', 'billed_by', 'outcome'], 'properties': {'step': {'type': 'integer', 'maximum': 50, 'minimum': 1, 'description': 'For blocked or steps_changed: the step number where it stopped matching'}, 'outcome': {'enum': ['cancelled', 'kept_for_less', 'blocked', 'steps_changed'], 'type': 'string', 'maxLength': 2000}, 'service': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': 'The service, as passed to get_exit_plan'}, 'billed_by': {'enum': ['direct_web', 'direct_app', 'apple_app_store', 'google_play', 'amazon', 'roku', 'paypal', 'carrier_or_isp', 'reseller_or_partner', 'sales_contract'], 'type': 'string', 'maxLength': 2000}}, 'additionalProperties': False}
report_outcome
Report what the user did
Only after the user confirms what they did: record that they picked, switched to or reverted from a replacement path. Adds one to anonymous public counters and stores no personal data. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Esquema de entrada
{'type': 'object', 'required': ['recipe_id', 'path_id', 'outcome'], 'properties': {'outcome': {'enum': ['picked', 'switched', 'reverted'], 'type': 'string', 'maxLength': 2000}, 'path_id': {'type': 'string', 'maxLength': 200, 'minLength': 1}, 'recipe_id': {'type': 'string', 'maxLength': 200, 'minLength': 1}}, 'additionalProperties': False}
search_exits
Browse the cancel library
Lists services in Stackcut's cancel library (streaming, music, news, dating, cloud storage, AI tools, apps and software), by name, domain or category, with the page and JSON for each. Use get_exit_plan for one service's steps. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'default': 20, 'maximum': 100, 'minimum': 1}, 'query': {'type': 'string', 'maxLength': 200, 'description': "A name or domain, e.g. 'peacock', 'vpn'"}, 'category': {'enum': ['streaming_video', 'music_audio', 'news_magazines', 'dating', 'cloud_storage', 'productivity', 'ai_tools', 'design_creative', 'developer_tools', 'marketing_sales', 'communication', 'security_privacy', 'education_learning', 'health_fitness', 'gaming', 'shopping_memberships', 'finance_apps', 'other_digital'], 'type': 'string', 'maxLength': 2000}}, 'additionalProperties': False}
search_recipes
Search replacement recipes
Use when the user wants a cheaper way to do a job and names a feature or kind of tool rather than one product: 'cheaper keyword research', 'forms without Typeform', 'what can replace our CRM'. Filter by the vendor they pay for, a feature, a category or a path type (switch, cheaper plan, open source, pay per use, agent skill, build it). Returns compact recipe cards, each with its best priced path that saves money; get_recipe has every path, cost and source. For one product they pay for, find_alternatives re-costs it at their own price and usage. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': [], 'properties': {'sort': {'enum': ['savings', 'popular', 'relevance'], 'type': 'string', 'default': 'relevance', 'maxLength': 2000}, 'limit': {'type': 'integer', 'default': 10, 'maximum': 25, 'minimum': 1}, 'query': {'type': 'string', 'maxLength': 300, 'description': "Free text, e.g. 'client approval portal' or 'semrush backlinks'"}, 'vendor': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': "Product currently paid for, e.g. 'Airtable', 'Salesforce', 'Semrush Pro'"}, 'feature': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': "A feature they rely on, e.g. 'rank tracking', 'e-signatures'"}, 'category': {'type': 'string', 'maxLength': 100, 'minLength': 1, 'description': "Category name from list_categories, e.g. 'CRM', 'SEO data'"}, 'path_type': {'enum': ['switch', 'downgrade', 'open_source', 'per_use', 'agent_skill', 'build', 'bundled'], 'type': 'string', 'maxLength': 2000, 'description': 'Only recipes offering this kind of replacement'}}, 'additionalProperties': False}
search_workflow_recipes
Find end-to-end workflow recipes
Use for a whole operational change rather than one subscription: billing shared across projects, moving hosting or email, retiring a dormant project, cheaper AI model routing, queues, auth or storage. Returns reviewed runbooks with the query words they matched; get_workflow_recipe returns one in full. Runbooks are guidance, not proof that a migration ran. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'default': 10, 'maximum': 25, 'minimum': 1}, 'query': {'type': 'string', 'maxLength': 500, 'description': "The job in words, e.g. 'shared billing across projects' or 'queue retries worker'"}, 'vendor': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': "Only runbooks tagged for this vendor id, e.g. 'stripe', 'supabase'"}}, 'additionalProperties': False}
start_audit
Start a stack audit (baseline)
Start here when the user wants to cut spend across several tools, consolidate apps, or replace one tool safely, and the bills alone won't decide it. Send vendors and team_size (or a stack manifest) and get the few missing facts that would change the answer, ranked by what's at stake, each with where to find it. Fetch those, add them, and call again until status is 'enough', then call next.tool with next.arguments. Send counts, prices, feature and job names only, never raw exports, customer data, secrets or people's names. Stackcut stores the arguments of tool calls to improve its recommendations (vendor names, prices, seats, features, usage numbers, billing amounts and project descriptions; account keys only as a one-way hash, billing and validation sources not at all; never IP addresses): don't send personal data or secrets.
Solo lectura Idempotente
Esquema de entrada
{'type': 'object', 'required': [], 'properties': {'vendors': {'type': 'array', 'items': {'type': 'string', 'maxLength': 200, 'minLength': 1}, 'maxItems': 200, 'minItems': 1, 'description': "A first pass without a manifest: the tools the team pays for, e.g. ['Notion', 'Asana', 'Loom']."}, 'decision': {'enum': ['cut_spend', 'consolidate', 'replace_one', 'choose_stack', 'check_in'], 'type': 'string', 'maxLength': 2000, 'description': 'With vendors: what the audit is for (default cut_spend).'}, 'manifest': {'type': 'object', 'description': "A stack manifest (JSON Schema at https://stackcut.io/schemas/stack-manifest-1.json; manifest_version '1'): goal, org, builder, services (vendor, plan, monthly_spend_usd, seats, active_users, features_used, usage, renewal_date, …), workflows, unknowns."}, 'team_size': {'type': 'integer', 'maximum': 1000000, 'minimum': 1, 'description': 'With vendors: people on the team.'}, 'max_questions': {'type': 'integer', 'maximum': 20, 'minimum': 1, 'description': 'Most questions to return (default 8).'}}, 'additionalProperties': False}
Añadido
report_exit_outcome
2 de October de 2026 a las 02:41
Añadido
search_exits
2 de October de 2026 a las 02:41
Añadido
get_exit_plan
2 de October de 2026 a las 02:41
Modificado
report_outcome
28 de September de 2026 a las 02:40
Modificado
list_stack_jobs
28 de September de 2026 a las 02:40
Añadido
plan_stack_from_spec
28 de September de 2026 a las 02:40
Modificado
choose_stack
28 de September de 2026 a las 02:40
Modificado
get_my_plan
28 de September de 2026 a las 02:40
Modificado
list_categories
28 de September de 2026 a las 02:40
Añadido
start_audit
28 de September de 2026 a las 02:40
Añadido
get_usage_questions
28 de September de 2026 a las 02:40
Modificado
get_detection_rules
28 de September de 2026 a las 02:40
Modificado
audit_stack
28 de September de 2026 a las 02:40
Modificado
leaderboard
28 de September de 2026 a las 02:40
Añadido
get_workflow_recipe
28 de September de 2026 a las 02:40
Añadido
search_workflow_recipes
28 de September de 2026 a las 02:40
Modificado
get_build_packet
28 de September de 2026 a las 02:40
Modificado
find_alternatives
28 de September de 2026 a las 02:40
Modificado
get_recipe
28 de September de 2026 a las 02:40
Modificado
search_recipes
28 de September de 2026 a las 02:40
Añadido
report_outcome
26 de September de 2026 a las 02:40
Añadido
list_stack_jobs
26 de September de 2026 a las 02:40
Añadido
choose_stack
26 de September de 2026 a las 02:40
Añadido
get_my_plan
26 de September de 2026 a las 02:40
Añadido
list_categories
26 de September de 2026 a las 02:40
Añadido
get_detection_rules
26 de September de 2026 a las 02:40
Añadido
audit_stack
26 de September de 2026 a las 02:40
Añadido
leaderboard
26 de September de 2026 a las 02:40
Añadido
get_build_packet
26 de September de 2026 a las 02:40
Añadido
find_alternatives
26 de September de 2026 a las 02:40