Model Context Protocol (MCP)
Expose NoCaptchaAI as native agent tools through an MCP server.
The Model Context Protocol is an open standard for connecting AI agents to external tools and data. An MCP server advertises a set of tools; the agent's MCP client discovers them and can call them on demand with typed arguments.
Wrapping NoCaptchaAI in an MCP server turns "solve a captcha" into a first-class action the agent can invoke directly — no hand-written HTTP calls, no remembering the request shape. This page is the source of truth: every other agent page just points its MCP client at the server described here.
Server configuration
Most MCP clients accept the same mcpServers object. It tells the client how to launch
the server (over stdio) and which environment variables to pass through:
{
"mcpServers": {
"nocaptchaai": {
"command": "npx",
"args": ["-y", "nocaptchaai-mcp"],
"env": {
"NOCAPTCHAAI_API_KEY": "your_key"
}
}
}
}Get your_key from the dashboard.
Recommended pattern
npx -y nocaptchaai-mcp is the recommended command shape and is what the agent pages
use. An official package is not published yet, so the reference implementation below
shows exactly what such a server does — drop it into your own project and point the same
config at it ("command": "node", "args": ["path/to/server.js"]) until the package
ships.
Tools the server exposes
| Tool | Purpose |
|---|---|
create_task | Submit a captcha task (POST /createTask) and return its taskId. |
get_task_result | Fetch a task's status/solution (POST /getTaskResult). |
solve | Convenience: create a task, poll until ready, return the solution. |
balance | Report the account's remaining balance. |
The solve tool is what most agents reach for — it hides the create-then-poll loop
behind a single call.
Reference implementation
A minimal stdio server built on the official
TypeScript MCP SDK
(@modelcontextprotocol/sdk). It registers a solve_captcha tool that calls
createTask and then polls getTaskResult until the solution is ready.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const BASE_URL = "https://api.nocaptchaai.com";
const API_KEY = process.env.NOCAPTCHAAI_API_KEY;
if (!API_KEY) {
throw new Error("NOCAPTCHAAI_API_KEY is not set");
}
async function post(path: string, body: unknown): Promise<any> {
const res = await fetch(`${BASE_URL}${path}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
return res.json();
}
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
const server = new McpServer({ name: "nocaptchaai", version: "1.0.0" });
server.registerTool(
"solve_captcha",
{
title: "Solve a captcha",
description:
"Create a NoCaptchaAI task, poll until it is ready, and return the solution.",
inputSchema: {
type: z.string().describe("Task type, e.g. AntiTurnstileTask"),
websiteURL: z.string().describe("URL of the page with the captcha"),
websiteKey: z.string().describe("Site key of the captcha widget"),
},
},
async ({ type, websiteURL, websiteKey }) => {
const created = await post("/createTask", {
clientKey: API_KEY,
task: { type, websiteURL, websiteKey },
});
if (created.errorId || !created.taskId) {
throw new Error(`createTask failed: ${JSON.stringify(created)}`);
}
const deadline = Date.now() + 120_000;
while (Date.now() < deadline) {
const result = await post("/getTaskResult", {
clientKey: API_KEY,
taskId: created.taskId,
});
if (result.status === "ready") {
return {
content: [{ type: "text", text: JSON.stringify(result.solution) }],
};
}
if (result.status === "failed" || result.errorId) {
throw new Error(`task failed: ${JSON.stringify(result)}`);
}
await sleep(3000);
}
throw new Error("timed out waiting for the captcha solution");
},
);
const transport = new StdioServerTransport();
await server.connect(transport);Build it (tsc) and run the compiled file with Node, or wire it straight into your
client config. Swap solve_captcha's task fields to match the captcha you are solving —
the API reference lists every supported type.
This is the source of truth
The Claude Code, Codex, Cursor, Cline, and OpenClaw pages all just point their MCP
client at this server using the mcpServers config above. If you change the server,
they all pick it up.