Key takeaways
- Install
mcp-marketplace-licenseand add one line to gate your entire server or individual tools - The SDK reads
MCP_LICENSE_KEYfrom environment and verifies against the API - Mock the SDK in automated tests to avoid network calls
How licensing works on MCP Marketplace
When someone buys a paid MCP server on the marketplace, they receive a license key. That key unlocks the server's premium tools. The mcp-marketplace-license SDK handles all the verification: you add a few lines of code and the rest is automatic.
Here is the lifecycle:
- Purchase. Buyer pays on MCP Marketplace.
- Key issued. Marketplace generates a unique license key starting with
mcp_live_. - Key stored. Buyer sets
MCP_LICENSE_KEYas an environment variable in their MCP config. - Verification. Your server uses the SDK to verify the key on startup or per-tool call.
Installing the SDK
pip install mcp-marketplace-license
Works with any Python 3.10+ project.
Basic usage
Gate the entire server
The simplest approach: if the key is invalid, the server does not start:
from mcp.server.fastmcp import FastMCP
from mcp_marketplace_license import with_license
mcp = FastMCP("my-server")
@mcp.tool()
def my_tool(query: str) -> str:
return do_thing(query)
with_license(mcp, slug="my-server")
One line. If the key is missing or invalid, the user sees a clear error message telling them how to get a key.
Gate individual tools (freemium)
For servers with both free and pro tools:
from mcp_marketplace_license import verify_license
import json
def require_license(tool_name: str) -> str | None:
"""Returns None if licensed, or an error message if not."""
result = verify_license(slug="my-server")
if result.get("valid"):
return None
return json.dumps({
"error": "premium_required",
"message": f"'{tool_name}' requires a license key. "
"Set MCP_LICENSE_KEY in your environment.",
})
@mcp.tool()
def free_tool(query: str) -> str:
# No license check: available to everyone
return do_free_thing(query)
@mcp.tool()
def pro_tool(query: str) -> str:
err = require_license("pro_tool")
if err:
return err
return do_pro_thing(query)
Free tools work immediately. Pro tools return a helpful error if no valid key is present.
The verify_license function
from mcp_marketplace_license import verify_license
result = verify_license(slug="my-server")
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
slug | str | required | Your server's slug on MCP Marketplace |
key | str | None | None | License key to verify. If None, reads from MCP_LICENSE_KEY env var |
Return value
The function returns a dictionary. The two fields you need:
result["valid"]:Trueif the key is active,Falseotherwiseresult["reason"]: why it failed (e.g.,"expired","missing_key")
Check result["valid"] to decide whether to allow access.
Environment variables
The SDK reads one environment variable:
| Variable | Description |
|---|---|
MCP_LICENSE_KEY | The buyer's license key (starts with mcp_live_) |
Users set this in their MCP config:
{
"mcpServers": {
"your-server": {
"command": "your-server",
"env": {
"MCP_LICENSE_KEY": "mcp_live_..."
}
}
}
}
Supporting legacy variable names
If your server used a different variable name before adopting the SDK, you can support both:
import os
# Support legacy MYSERVER_LICENSE_KEY alongside the standard MCP_LICENSE_KEY
if not os.environ.get("MCP_LICENSE_KEY") and os.environ.get("MYSERVER_LICENSE_KEY"):
os.environ["MCP_LICENSE_KEY"] = os.environ["MYSERVER_LICENSE_KEY"]
Using with MCP Creator
If you scaffold your server with MCP Creator and paid=true, all of this is wired up automatically. Available for both TypeScript (mcp-creator-typescript) and Python (mcp-creator-python):
scaffold_server(
package_name="my-paid-mcp",
tools=["free_tool", "pro_tool"],
paid=true,
paid_tools=["pro_tool"]
)
The generated project includes:
- License SDK in dependencies (
@mcp_marketplace/licensefor TypeScript,mcp-marketplace-licensefor Python) - License verification wired into tool handlers
MCP_LICENSE_KEYin.env.example- License setup instructions in
README.md
No manual SDK integration needed.
Testing license verification
During development, you need to test both licensed and unlicensed states.
Without a real key
Set MCP_LICENSE_KEY to any value and the SDK will verify it against the API, returning invalid. This lets you confirm your gating logic works correctly.
With a test key
Use your own purchased key to test the full happy path. Set MCP_LICENSE_KEY in your environment and run your server locally.
In automated tests
Mock the SDK to avoid network calls in tests:
from unittest.mock import patch
@patch("mcp_marketplace_license.verify_license")
def test_pro_tool_with_valid_key(mock_verify):
mock_verify.return_value = {"valid": True, "reason": "active"}
result = pro_tool("test query")
assert "premium_required" not in result
@patch("mcp_marketplace_license.verify_license")
def test_pro_tool_without_key(mock_verify):
mock_verify.return_value = {"valid": False, "reason": "missing_key"}
result = pro_tool("test query")
assert "premium_required" in result
Security notes
Keys are API tokens, not secrets. License keys are set in environment variables in MCP config files. They identify a buyer and grant access, similar to an API key.
Verification is server-side. The SDK calls the MCP Marketplace verification API. There is no client-side validation to bypass.
Do not hardcode keys. Keys should always come from environment variables, never from source code. The SDK reads MCP_LICENSE_KEY from the environment by default.
Next steps
- How to monetize your MCP server: the full guide to pricing models
- Free vs Pro: structuring your freemium tiers
- Remote MCP servers: hosting and authentication for remote servers
- MCP Creator: scaffold paid servers with AI in TypeScript or Python
- How to build an MCP server: the full build guide before adding licensing