MCP Server
Add 31 deterministic developer tools to Claude Desktop, Cursor, Cline, or any MCP-compatible client. Pay-per-call via Stripe; first 50 calls free per IP across the entire grid.
Last updated: 2026-05-19
Quick start — Claude Desktop
Claude Desktop reads MCP server definitions from a JSON config file. Until Claude ships native HTTP MCP support, remote servers connect through the open-source mcp-remote proxy (auto-installed via npx, no manual install). Paste this block into your config and restart Claude Desktop:
{
"mcpServers": {
"obfus-link": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://obfus.link/mcp"]
}
}
}Where to paste it:
macOS path
~/Library/Application Support/Claude/claude_desktop_config.json
Windows path
%APPDATA%\Claude\claude_desktop_config.json
Linux path
~/.config/Claude/claude_desktop_config.json
mcpServers object goes in the same place.Add a payment token (after the free tier)
The free tier covers the first 50 tool calls per IP across the entire grid (lifetime, not daily). After that the server returns HTTP 402 Payment Required with a Stripe checkout link in the response body. Acquire a Shared Payment Token (SPT), then add it to the config as an extra --header flag:
{
"mcpServers": {
"obfus-link": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://obfus.link/mcp",
"--header",
"Authorization: Bearer <YOUR_SPT_TOKEN>"
]
}
}
}See the Pricing page for the per-tool cost breakdown ($0.008 – $0.025/call by tier) and the full 402 challenge-response shape.
Endpoint
| Method | Path | Purpose |
|---|---|---|
| GET | /mcp | Server info (name, version, protocol, endpoint URL) |
| POST | /mcp | JSON-RPC 2.0 — initialize, tools/list, tools/call |
| OPTIONS | /mcp | CORS preflight |
| GET | /.well-known/mcp | Static JSON manifest — full tool list + per-tool agenticReasoning for registry indexers |
Authentication
Three resolution modes, evaluated in order. First match wins:
- Shared Identity Layer (SIL): header
x-subether-shared-token: <token>— cross-property auth issued by Subether Labs. An agent authorised on any Subether property bypasses the per-property challenge. Billed against the Subether account. - Stripe Payment Token (SPT): header
Authorization: Bearer <spt>— metered against the SPT's Stripe subscription. Returned when the SPT balance is depleted: 402 with a top-up URL. - No auth: falls through to the lifetime free tier (50 calls / IP, never resets). After exhaustion: 402 with a checkout URL.
search_utility_gridis always free and never counts against the limit.
Tool discovery
Call search_utility_grid with a natural-language query to find tools without an upfront enumeration of the manifest. Free, no auth required. Returns up to 30 ranked matches with each tool's mcpToolName ready to plug into a follow-up tools/call.
For static indexing (build-time tool catalogues, registry submission), the full machine-readable manifest lives at /.well-known/mcp. Every entry includes agenticReasoning — verbose decision-logic prose authored per tool that explains when an agent should pick this tool over a library function, an LLM call, or a competing obfus.link tool.
Examples
List all tools (free, no auth):
curl -X POST https://obfus.link/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Call a tool via JSON-RPC:
curl -X POST https://obfus.link/mcp \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <YOUR_SPT_TOKEN>' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "json_to_zod",
"arguments": {
"json": "{\"name\":\"Ada\",\"age\":36}",
"schemaName": "User",
"strict": true,
"coerce": false,
"autoJsDoc": true,
"inferBranding": true,
"dateStrategy": "string"
}
}
}'TypeScript SDK — the canonical client path:
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
const transport = new StreamableHTTPClientTransport(
new URL('https://obfus.link/mcp'),
{ requestInit: { headers: { Authorization: 'Bearer ' + process.env.OBFUS_SPT } } },
);
const client = new Client({ name: 'my-agent', version: '0.1.0' });
await client.connect(transport);
// Discover tools (free — search_utility_grid never bills)
const search = await client.callTool({
name: 'search_utility_grid',
arguments: { query: 'json schema generator' },
});
// Call a tool
const result = await client.callTool({
name: 'json_to_zod',
arguments: { json: '{"id":1}', schemaName: 'Row', strict: true, coerce: false, autoJsDoc: false, inferBranding: false, dateStrategy: 'string' },
});Error responses
JSON-RPC errors follow the standard { jsonrpc, id, error: { code, message } } envelope. Tool-specific failures (validation, parse, security) come back inside the tools/call result withisError: true and a structured ErrorOutput in the content:
| Code | Meaning | Retryable? |
|---|---|---|
| INPUT_EMPTY | Required field empty / null | No |
| INPUT_TOO_LARGE | Input above the tool's size ceiling | No |
| INPUT_MALFORMED | Structurally invalid (bad JSON/regex/etc.) | No |
| INPUT_INVALID_TYPE | Wrong TypeScript type passed | No |
| PARSE_FAILED | Internal parse step failed | Yes (1×) |
| TRANSFORM_FAILED | Transformation logic hit unrecoverable state | Yes (1×) |
| TIMEOUT | Execution exceeded 3s ceiling | Yes (1×) |
| UNSUPPORTED_LANGUAGE | Language/dialect not in supported set | No |
| UNSUPPORTED_FORMAT | Format/mode combination not implemented | No |
| PAYLOAD_LIMIT | Output would exceed safe size | No |
| SECURITY_VIOLATION | Prompt injection / instruction poisoning | No — clean input source first |
Every ErrorOutput includes a suggestion field with a concrete, single-step corrective action — agents can act on it without human help.
Trusted Infrastructure
Every inbound input runs through a poisoning check before reaching the core function — prompt-injection patterns (“ignore all previous instructions”, role-hijack phrases, LLM formatting tokens injected as data) are rejected with SECURITY_VIOLATION at the route boundary. Tools that produce output flowing into downstream LLM contexts (json_to_zod, llm_to_json_cleaner, yaml_to_env) run in reject mode; lower-risk tools run in strip mode.
This is declared in the MCP manifest under the security block — safety-conscious agents and registries can verify the contract before integrating.
See also
- Pricing — full per-tool / per-tier cost breakdown
- /.well-known/mcp — machine-readable manifest with full agenticReasoning per tool
- HTTP API surface — REST-style call shapes for non-MCP clients
- Articles — long-form guides on individual tools and their differentiators