Announcing CIMD support for MCP Client registration
Learn more

DataForSEO MCP vs DataForSEO API for AI Agents (2026)

Nishant Choudhary
Tech Evangelist

TL;DR

  • The official DataForSEO MCP server registers roughly 90 tools across ten API modules, and every one of them calls a /live endpoint. The Standard queue (task_post and task_get), pingbacks, postbacks, and full-site OnPage crawls have no MCP surface at all.
  • That is a cost decision, not just a capability gap. DataForSEO prices a SERP at $0.0006 on the Standard queue and $0.002 in Live mode, so an MCP-driven agent pays roughly 3.3 times the Standard rate on every SERP it pulls.
  • Auth does not diverge the way it does for Notion or Slack. The local and Docker MCP paths use DATAFORSEO_USERNAME and DATAFORSEO_PASSWORD; the API uses the same login and password over HTTP Basic. The hosted remote endpoint adds an OAuth option for interactive clients, and that is the only place the two paths differ.
  • DataForSEO credentials carry no scopes and no per-seat permission model. Rate limits, the 30-concurrent-request ceiling, and the prepaid balance are all account-wide, so a shared credential means one tenant's runaway agent throttles and bills every other tenant.
  • Scalekit's DataForSEO MCP connector resolves a per-user connected account on every tool call and logs each call against the identity that authorized it, so the MCP versus API decision does not change your credential infrastructure.

Your agent needs live SERP positions, keyword volumes, and backlink data. DataForSEO ships an official MCP server and a REST API that has been in production for years. Most comparisons in this series turn on auth: the MCP server forces OAuth, the API gives you alternatives. DataForSEO inverts that. Both paths land on the same account-level credential, and the decision turns on delivery method and cost instead. Here is how to pick.

What DataForSEO MCP and DataForSEO API actually are

These are two front doors onto the same data, but they are not two views of the same API surface. The MCP server is a curated subset with a fixed delivery method. The REST API is the whole platform.

DataForSEO MCP

DataForSEO maintains an official, Apache-2.0 MCP server written in TypeScript and announced in May 2025. It runs three ways: locally over stdio via npx dataforseo-mcp-server, as a Docker container, or against the hosted remote endpoint at https://mcp.dataforseo.com/mcp. Setup instructions for each client live on the DataForSEO MCP page, and the implementation is on the official DataForSEO MCP server repository.

The ten modules and the default that surprises people

The server organizes tools into ten modules: AI_OPTIMIZATION, SERP, KEYWORDS_DATA, ONPAGE, DATAFORSEO_LABS, BACKLINKS, BUSINESS_DATA, DOMAIN_ANALYTICS, CONTENT_ANALYSIS, and MERCHANT. The ENABLED_MODULES environment variable narrows that set. If you leave it unset, every module is enabled, which means roughly 90 tool definitions land in your agent's context. DataForSEO's own setup page acknowledges the consequence: Cursor caps active MCP tools at 40, so you are told to disable modules you do not need.

DataForSEO API

The REST API sits at https://api.dataforseo.com/v3/ and authenticates with HTTP Basic using the API login and password from your account's API Access dashboard. Full endpoint documentation and the product surface are available in the DataForSEO API docs.

Two delivery methods, not one

This is the distinction the MCP server erases. Most DataForSEO endpoints exist in two forms. The Live method holds the connection open and returns results in the response. The Standard method uses task_post to queue work, then either tasks_ready plus task_get to collect it, or a pingback_url or postback_url so DataForSEO pushes results to your server on completion. Standard batches up to 100 tasks per POST call and costs a fraction of Live.

Comparing them where it matters for agents

The topic coverage of the MCP server is genuinely broad. Keyword research, backlink profiles, SERP competitors, WHOIS, technology detection, and LLM mention tracking are all there. What is missing is not a topic. It is a delivery method.

What your agent can actually do

Capability
DataForSEO MCP
DataForSEO API
Live organic SERP for Google, Bing, Yahoo
Yes
Yes
Other Google SERP types (Maps, News, Images, Local Finder)
No
Yes
Keyword research via DataForSEO Labs
Yes
Yes
Backlink profiles, anchors, referring domains
Yes
Yes
AI Optimization: LLM mentions, ChatGPT scraper
Yes
Yes
Single-page OnPage checks (instant pages, Lighthouse, content parsing)
Yes
Yes
Full-site OnPage crawl (summary, pages, resources, links)
No
Yes
Standard queue via task_post and task_get
No
Yes
Result delivery via pingback_url or postback_url
No
Yes
Business Data reviews (Google, Trustpilot, Tripadvisor)
No
Yes
Merchant: Amazon products, ASIN, sellers
Yes
Yes
Merchant: Google Shopping
No
Yes

The gap that matters most is priced, not missing

Every endpoint the MCP server calls ends in /live, or is a static reference lookup such as serp_locations. There is no task_post anywhere in the codebase. For an interactive agent answering one question, that is correct behavior. For a nightly rank tracker pulling 5,000 keywords, it is a bill. At DataForSEO's published rates, those 5,000 SERPs cost $10 through Live and $3 through the Standard queue, every night. The MCP server gives your agent no way to choose the cheaper door.

This is the same tradeoff explored in the broader discussion of why MCP can be significantly more expensive than direct API calls — the delivery method shapes the cost structure in ways that compound at scale.

The second gap is architectural

Full-site OnPage auditing is a crawl, not a request. You post a task with a page limit, DataForSEO crawls the site, and you then read the summary, pages, resources, and links endpoints. The MCP server exposes on_page_instant_pages, on_page_content_parsing, and on_page_lighthouse, all of which analyze a single URL synchronously. If your agent's job is "audit this 4,000-page site," the MCP server cannot start the job, and the absence of postback support means it could not learn the job finished either.

The auth path each one puts you on

Here is where DataForSEO breaks the pattern the rest of this series established. For Notion, Slack, and Salesforce, the MCP server forces per-user OAuth and the API offers alternatives. DataForSEO does close to the opposite.

MCP auth: the same static credential, with one exception

The local and Docker paths read DATAFORSEO_USERNAME and DATAFORSEO_PASSWORD from the environment. The hosted remote endpoint accepts a Base64-encoded HTTP Basic header built from that same login and password. The one exception is the connector flow: Claude Desktop and ChatGPT can authorize https://mcp.dataforseo.com/mcp through an OAuth consent step instead of a pasted header. That is the only per-identity handshake DataForSEO offers on either path.

API auth: one credential, no scopes

The REST API accepts HTTP Basic with the same login and password. There is no scope parameter, no read-only variant, and no per-endpoint permission grant. A credential that can read a SERP can also queue an OnPage crawl and spend the account balance. Least privilege is not expressible in the credential itself, which means it has to be enforced one layer up, at the tool surface your agent is allowed to see. This is precisely the challenge described in patterns for credential ownership across agent tool-calling architectures.

Why the usual multi-tenant framing does not apply cleanly

In a Notion agent, per-user OAuth exists because each user has a different workspace with different content. DataForSEO has no user-scoped data. Every credential sees the same global index. The isolation you need is not about who can read what. It is about whose balance gets drawn down, whose rate limit gets consumed, and whose activity shows up in an audit trail when a customer disputes a bill.

What that means in a B2B product

If you are building an SEO product where each agency customer brings their own DataForSEO account, you hold one credential per tenant either way. Neither path stores it, rotates it, or revokes it for you. If instead you run your own single DataForSEO account behind all tenants, every tenant shares one prepaid balance and one set of limits, and you own the attribution problem entirely. Understanding how tool calling auth changes when you move from single-tenant to multi-tenant is essential before you commit to either architecture.

What you own in production

Both paths hand you real operational surface. The split is narrower here than for most connectors, because both ultimately issue the same authenticated HTTP calls to the same endpoints.

On the MCP path

DataForSEO maintains the tool schemas, response trimming, and endpoint mapping. You still own credential storage, module selection per deployment, and context budget. The server ships a --configuration flag that takes a JSON file of supported_fields per tool so you can strip response payloads down to the fields you actually use, which matters because DataForSEO responses are large and verbose by default.

On the API path

You own endpoint selection, request construction, retries, pagination, and the polling or webhook loop for Standard tasks. You also gain the levers the MCP server does not expose: queue selection, task batching, priority, and depth control. For a deterministic pipeline, that control is the reason to be on this path.

Rate limits and concurrency are account-wide

DataForSEO's general limit is 2,000 requests per minute, with a ceiling of 30 simultaneous requests against live endpoints, and it publishes X-RateLimit-Limit and X-RateLimit-Remaining headers on every response. Those 30 concurrent slots belong to the account, not to the caller. A shared credential means tenants contend for the same 30 slots, and a burst from one agent surfaces as latency for everyone else.

Schema drift

MCP tool schemas change when DataForSEO ships a server update, and the tool names are not versioned. The REST API is versioned in the path at /v3/, and endpoint contracts are documented per endpoint. If an unexpected schema change in your rank-tracking pipeline is an incident rather than an inconvenience, the versioned path is the more predictable dependency.

When to use MCP, when to use the API

The split is cleaner for DataForSEO than for most tools in this series, because the delivery-method boundary maps almost exactly onto the interactive versus batch boundary.

Use the DataForSEO MCP server when

  • Your agent is interactive and a human is waiting: an SEO copilot that answers "where does this domain rank for these ten terms right now," where Live latency is the point and Live pricing is acceptable
  • Your workload is research-shaped rather than monitoring-shaped: competitor discovery, keyword ideation, backlink investigation, ad-hoc content analysis
  • You are tracking AI visibility through the AI_OPTIMIZATION module and want LLM mention data without writing a client for it
  • You are prototyping and want working DataForSEO tool schemas before you commit to an integration

Use the DataForSEO API directly when

  • Your agent runs on a schedule: nightly rank tracking, weekly backlink diffs, or any batch where the Standard queue's lower per-SERP cost compounds
  • You need pingback_url or postback_url delivery so a background job does not sit in a polling loop
  • Your agent triggers full-site OnPage crawls, or needs Google Maps, News, Images, or Local Finder SERPs
  • You need Business Data reviews or Google Shopping merchant data, neither of which the MCP server exposes
  • You need per-request control over priority and depth to keep spend predictable at volume

The credential problem that exists on both paths

Both paths hand your agent a DataForSEO credential. Neither hands you a vault, a rotation policy, or an attribution trail. For a metered, prepaid API, that gap has a sharper edge than usual.

The N-credential problem, with a billing dimension

In a multi-tenant SEO product, each customer either brings their own DataForSEO account or shares yours. In the first case you are storing N sets of credentials encrypted at rest, isolated per tenant, and revocable when a customer churns. In the second, one shared credential funds every tenant's usage, and when the balance drains at 2am you have no per-tenant record of who spent it. This is exactly the kind of audit trail gap that surfaces during security reviews and compliance inquiries.

What neither path gives you

Storage outside the agent runtime. Isolation per tenant. Revocation on offboarding. And the one that bites hardest here: attribution. Standard application logs record which of your users triggered a workflow. They do not record which credential executed the downstream DataForSEO call, or which of the 90 available tools it reached for. That correlation is what a cost dispute and a SOC 2 auditor both ask for, and it is far easier to have before you need it. The problem of knowing whether your agent is actually working correctly is inseparable from knowing what it called and why.

Where Scalekit fits

Scalekit's DataForSEO connector stores the credential in an encrypted vault outside your agent runtime, resolves the correct connected account on every tool call, and records each call against the identity that authorized it. The same infrastructure works whether you chose the MCP path or the direct API path. Setup lives in the DataForSEO MCP connector docs, and the connector overview is on the Scalekit DataForSEO connector page.

Building a DataForSEO agent with Scalekit

Scalekit exposes DataForSEO through a single connector, dataforseomcp, which fronts the official MCP server and prefixes every tool name accordingly. The sequence below follows the order that matters: retrieve the authorized tool surface, understand why that surface is correct for this user, then execute.

Prerequisites and the connection name

Create the connection once in the Scalekit dashboard under AgentKit > Connections, then copy the connection name into your code. The string in code must match the dashboard value character for character. A mismatch here is the single most common integration error.

pip install scalekit-sdk-python langchain-openai # .env SCALEKIT_ENV_URL=https://your-env.scalekit.cloud SCALEKIT_CLIENT_ID=skc_... SCALEKIT_CLIENT_SECRET=sks_... OPENAI_API_KEY=sk-...

Authorize the user once

Scalekit creates a connected account per user and tracks its auth state, so subsequent runs check status instead of re-prompting.

import os import scalekit.client scalekit_client = scalekit.client.ScalekitClient( env_url=os.getenv("SCALEKIT_ENV_URL"), client_id=os.getenv("SCALEKIT_CLIENT_ID"), client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), ) actions = scalekit_client.actions # Must match the connection name configured in the Scalekit dashboard. CONNECTION_NAME = "dataforseomcp" IDENTIFIER = "user_123" account = actions.get_or_create_connected_account( connection_name=CONNECTION_NAME, identifier=IDENTIFIER, ) if account.connected_account.status != "ACTIVE": link = actions.get_authorization_link( connection_name=CONNECTION_NAME, identifier=IDENTIFIER, ) print("Authorize DataForSEO:", link.link) input("Press Enter after authorizing...")

Retrieve the authorized tool surface

Before the agent sees anything, decide what it is allowed to see. list_scoped_tools does not explore an unknown catalog. It returns the tools this user's connected account is authorized to call, and the tool_names filter narrows that further to the handful this agent role actually needs.

from scalekit.v1.tools.tools_pb2 import ScopedToolFilter RANK_TRACKER_TOOLS = [ "dataforseomcp_serp_organic_live_advanced", "dataforseomcp_dataforseo_labs_google_ranked_keywords", "dataforseomcp_dataforseo_labs_google_competitors_domain", ] scoped = actions.tools.list_scoped_tools( identifier=IDENTIFIER, filter=ScopedToolFilter( connection_names=[CONNECTION_NAME], tool_names=RANK_TRACKER_TOOLS, ), page_size=100, ) for tool in scoped.tools: print(tool.name, "|", tool.description)

Why that scoping is the whole point

The DataForSEO MCP server with all modules enabled puts roughly 90 tools in context. At a conservative 200 tokens per schema, that is about 18,000 tokens burned before the agent does any work, and DataForSEO schemas run larger than average because of the nested filters and long location_name descriptions. Cutting the surface to three tools removes both the token cost and the decision space the model was never designed to search at that scale. Surface reduction is the lever. Model upgrades help. They are not the lever.

Run the agent loop with LangChain

actions.langchain.get_tools() returns native StructuredTool objects built from that same scoped surface, so the agent code carries no Scalekit-specific logic beyond initialization. For more on how LangChain's tool calling works and where it needs augmentation, see LangChain tool calling: how it works, where it stops, and how Scalekit completes it.

from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage, ToolMessage tools = actions.langchain.get_tools( identifier=IDENTIFIER, connection_names=[CONNECTION_NAME], tool_names=RANK_TRACKER_TOOLS, page_size=100, ) tool_map = {t.name: t for t in tools} llm = ChatOpenAI(model="gpt-4o").bind_tools(tools) messages = [ HumanMessage( "For the domain example.com in the United States, list the top keywords " "it ranks for and name its three closest organic competitors." ) ] while True: response = llm.invoke(messages) messages.append(response) if not response.tool_calls: print(response.content) break for tc in response.tool_calls: result = tool_map[tc["name"]].invoke(tc["args"]) messages.append(ToolMessage(content=str(result), tool_call_id=tc["id"]))

TypeScript with the Claude SDK

The Node.js SDK follows the same discovery-then-execute shape. listScopedTools returns raw JSON Schema you can hand straight to the Anthropic Messages API, and executeTool resolves the connected account server-side so no DataForSEO credential ever enters the agent process.

npm install @scalekit-sdk/node @anthropic-ai/sdk
import { ScalekitClient } from '@scalekit-sdk/node'; import Anthropic from '@anthropic-ai/sdk'; const scalekit = new ScalekitClient( process.env.SCALEKIT_ENV_URL!, process.env.SCALEKIT_CLIENT_ID!, process.env.SCALEKIT_CLIENT_SECRET!, ); const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY! }); // Must match the connection name configured in the Scalekit dashboard. const CONNECTION_NAME = 'dataforseomcp'; const IDENTIFIER = 'user_123'; const { tools } = await scalekit.tools.listScopedTools(IDENTIFIER, { filter: { connectionNames: [CONNECTION_NAME], toolNames: [ 'dataforseomcp_serp_organic_live_advanced', 'dataforseomcp_backlinks_summary', ], }, pageSize: 100, }); const claudeTools = tools.map((t) => ({ name: t.name, description: t.description, input_schema: t.inputSchema as Anthropic.Tool.InputSchema, })); const messages: Anthropic.MessageParam[] = [ { role: 'user', content: 'Who ranks in the top 10 for "agent authentication" in the United States, ' + 'and what does the backlink profile of the number one result look like?', }, ]; while (true) { const response = await anthropic.messages.create({ model: 'claude-sonnet-4-6', max_tokens: 2048, messages, tools: claudeTools, }); messages.push({ role: 'assistant', content: response.content }); if (response.stop_reason !== 'tool_use') { for (const block of response.content) { if (block.type === 'text') console.log(block.text); } break; } const toolResults: Anthropic.ToolResultBlockParam[] = []; for (const block of response.content) { if (block.type !== 'tool_use') continue; const result = await scalekit.actions.executeTool({ toolName: block.name, toolInput: block.input as Record, identifier: IDENTIFIER, }); toolResults.push({ type: 'tool_result', tool_use_id: block.id, content: JSON.stringify(result.data), }); } messages.push({ role: 'user', content: toolResults }); }

Virtual MCP servers for multi-tool, multi-tenant agents

A real SEO agent rarely stops at DataForSEO. It writes findings to Notion, posts a digest to Slack, and files work in Linear. Handing it three full MCP servers means three full tool catalogs. Virtual MCP servers let you declare exactly which tools from which connections the agent can see, once per agent role, and then mint a per-user endpoint at runtime.

from scalekit.actions.types import McpConfigConnectionToolMapping config = actions.mcp.create_config( name="seo-reporting-agent", description="Reads DataForSEO rankings and writes a summary to Notion.", connection_tool_mappings=[ McpConfigConnectionToolMapping( connection_name="dataforseomcp", tools=[ "dataforseomcp_serp_organic_live_advanced", "dataforseomcp_dataforseo_labs_google_ranked_keywords", ], ), McpConfigConnectionToolMapping( connection_name="notion", tools=["notion_create_page"], ), ], ) # Runtime: one call per user, idempotent. instance = actions.mcp.ensure_instance( config_name="seo-reporting-agent", user_identifier=IDENTIFIER, ) auth_state = actions.mcp.get_instance_auth_state( instance_id=instance.instance.id, include_auth_links=True, ) for conn in auth_state.connections: if conn.connected_account_status != "ACTIVE": print(f"{conn.connection_name} needs authorization: {conn.authentication_link}") print("MCP endpoint for this user:", instance.instance.url)

One definition, per-user identity

The server definition is created once per agent role. The endpoint is static. The identity is not: each run resolves to that user's connected accounts, so no DataForSEO credential is shared between tenants and no per-user server configuration exists to drift. There is no MCP server to deploy, host, or maintain.

Tool call logs and downstream attribution

Because every call routes through Scalekit, each execution is logged against the connected account that authorized it, with the tool name and the response. For a metered API like DataForSEO, that log is the difference between "someone spent $400 on Live SERPs last night" and "this tenant's rank tracker called dataforseomcp_serp_organic_live_advanced 200,000 times." Logs are exportable to your SIEM, with failures separated by source.

Which one to build against

If your DataForSEO agent is interactive and a person is waiting for the answer, use the MCP server. Live delivery is what that workload needs, the tool schemas are maintained by DataForSEO, and you are operational in an afternoon. Scope the modules deliberately, because the default enables all ten.

If your agent runs on a schedule, crawls whole sites, or pulls thousands of SERPs a night, use the API directly. The Standard queue and postback delivery are not conveniences at that volume; they are the difference between a $3 job and a $10 one, run 365 times a year.

Most production SEO agents end up running both, and the credential problem is identical either way. That is the part that needs production-grade infrastructure. The broader question of which auth patterns apply to production tool-calling agents is worth reviewing before you finalize your architecture.

Talk to other DataForSEO agent builders

Building rank trackers, AI visibility monitors, or multi-tenant SEO agents on DataForSEO? Join the Scalekit Slack community to compare notes with other agent builders, or talk to an engineer if you want help scoping the auth architecture before you write it.

Browse the Scalekit DataForSEO connector and its tool list in the docs.

No items found.
Agent
Auth Quickstart
On this page
Share this article
Agent
Auth Quickstart

Acquire enterprise customers with
zero upfront cost.

Every feature unlocked. No hidden fees.