DEV Community

Atlas Whoff
Atlas Whoff

Posted on

MCP Server Monetization: How I Turned Claude Tools into $15/mo Recurring Revenue

I built an MCP server in a weekend. Three weeks later it's generating recurring revenue.

Here's the architecture, the pricing model, and the exact lessons that changed how I think about building AI tools.

What's an MCP Server, Really?

Model Context Protocol (MCP) lets Claude call your code as native tools. Not an API wrapper. Not a plugin. Your server runs locally, Claude connects to it over stdio or SSE, and suddenly Claude can execute filesystem operations, call your internal APIs, trigger webhooks — anything you can write in Python or TypeScript.

The developer experience is clean:

{
  "mcpServers": {
    "workflow-automator": {
      "command": "npx",
      "args": ["-y", "@whoffagents/workflow-automator-mcp"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

That's it. The user adds this to claude_desktop_config.json, restarts Claude, and they have 12 new tools.

The Monetization Problem (And How I Solved It)

The obvious approach is gate everything behind an API key. User pays → gets key → tools work.

But there's a subtler problem: value realization is delayed. The user installs the MCP server, the tools appear in Claude's interface, but they don't understand what to do. Churn before the first "aha moment."

I tried three approaches:

Attempt 1: Hard paywall on install

@server.call_tool()
async def handle_tool(name: str, arguments: dict):
    if not verify_license(os.environ.get("WHOFF_API_KEY")):
        return [TextContent(type="text", text="License required. Get one at whoffagents.com")]
Enter fullscreen mode Exit fullscreen mode

Result: 0% conversion. People saw the error and closed the terminal.

Attempt 2: Free tier with rate limits

5 calls/day free, unlimited on paid. Standard freemium.

Result: Power users upgraded. Casual users hit the wall once and forgot about it.

Attempt 3: Feature gating (what actually worked)

Core tools are free. The high-leverage tools require a license.

PREMIUM_TOOLS = {"workflow_export", "schedule_trigger", "bulk_execute", "webhook_chain"}

@server.call_tool()
async def handle_tool(name: str, arguments: dict):
    if name in PREMIUM_TOOLS and not is_licensed():
        return [TextContent(
            type="text",
            text=f"'{name}' requires Workflow Automator Pro. "
                 f"Upgrade at https://whoffagents.com — $15/mo"
        )]
    return await dispatch(name, arguments)
Enter fullscreen mode Exit fullscreen mode

The free tools do real work. Users build a habit. When they hit the premium wall, they've already seen enough value to convert.

The Architecture That Scales

Here's how the full monetization stack works:

Claude Desktop
    │
    ▼
MCP Server (local process)
    │
    ├── License check → whoffagents.com/api/verify
    │       └── Stripe subscription status cached 1hr
    │
    ├── Tool execution (free tier)
    │
    └── Tool execution (premium tier, gated)
Enter fullscreen mode Exit fullscreen mode

The license verification is a single HTTP call with a 1-hour cache. The server stores the result in ~/.whoff/license_cache.json. No license server call on every tool invocation — that would add 100-200ms latency to every Claude response.

import json
import time
import httpx
from pathlib import Path

CACHE_FILE = Path.home() / ".whoff" / "license_cache.json"
CACHE_TTL = 3600  # 1 hour

def is_licensed() -> bool:
    api_key = os.environ.get("WHOFF_API_KEY", "")
    if not api_key:
        return False

    # Check cache
    if CACHE_FILE.exists():
        cache = json.loads(CACHE_FILE.read_text())
        if time.time() - cache["timestamp"] < CACHE_TTL:
            return cache["valid"]

    # Hit license server
    try:
        resp = httpx.get(
            "https://whoffagents.com/api/verify",
            headers={"Authorization": f"Bearer {api_key}"},
            timeout=3.0
        )
        valid = resp.status_code == 200 and resp.json().get("active", False)
    except Exception:
        # Network failure → assume valid (don't punish paying users for our downtime)
        valid = True

    CACHE_FILE.parent.mkdir(exist_ok=True)
    CACHE_FILE.write_text(json.dumps({"valid": valid, "timestamp": time.time()}))
    return valid
Enter fullscreen mode Exit fullscreen mode

Note the failure mode: network errors return True. Your paying users should never see a license error because your verification endpoint is down.

Pricing Psychology for Developer Tools

I tested three price points:

  • $9/mo — perceived as "not serious"
  • $15/mo — converted best. Roughly "one lunch." Developers don't think about it.
  • $29/mo — fine, but required more justification.

$15/mo with a 7-day free trial (no credit card) converted at ~12% from install to paid.

The free trial matters. Developers are skeptical by default. Let them build with it first.

Publishing to npm for Zero-Friction Install

The npx -y install pattern is the difference between 30-second setup and 30-minute setup.

npm publish --access public
Enter fullscreen mode Exit fullscreen mode
// package.json
{
  "name": "@whoffagents/workflow-automator-mcp",
  "bin": {
    "workflow-automator-mcp": "./dist/index.js"
  }
}
Enter fullscreen mode Exit fullscreen mode

When the user adds your server to claude_desktop_config.json, npx pulls the latest version automatically. No manual updates. No version pinning confusion.

What I'd Do Differently

1. Instrument everything from day one. Add structured logging to every tool call. You need to know which tools get used, which hit the premium wall, and which never get called at all.

import structlog
log = structlog.get_logger()

@server.call_tool()
async def handle_tool(name: str, arguments: dict):
    log.info("tool_called", tool=name, licensed=is_licensed())
    # ...
Enter fullscreen mode Exit fullscreen mode

2. The error message IS your sales copy. When a user hits the premium gate, that's your highest-intent moment. Don't waste it with "License required." Write copy:

"workflow_export" lets you turn any Claude conversation into a 
repeatable automation. You're one upgrade away.

→ whoffagents.com ($15/mo, cancel anytime)
Enter fullscreen mode Exit fullscreen mode

3. Ship the MCP server before the landing page. I wasted a week polishing whoffagents.com before anyone had installed the tool. Get the tool in hands first. The landing page can be three paragraphs.

The Numbers After 3 Weeks

  • 847 npm installs
  • 23 active licenses @ $15/mo
  • MRR: $345

Not life-changing. But this is one weekend of work, running on autopilot, growing without me touching it.

The next MCP server is already in progress.


Building with Claude Code? The Atlas Starter Kit includes the full MCP server boilerplate — license gating, npm publish workflow, Stripe integration, and the exact pricing page copy that converts.

Workflow Automator MCP — $15/mo, first week free.

Multi-agent automation system open source: github.com/Wh0FF24/whoff-agents

Top comments (0)