dataforseo-mcp-server
Version:
A Model Context Protocol (MCP) server for the DataForSEO API, enabling modular and extensible integration of DataForSEO endpoints with support for both HTTP and SSE transports.
86 lines (85 loc) • 4.18 kB
JavaScript
import { z } from 'zod';
import { BaseTool } from '../../../../base.tool.js';
export class GoogleSERPCompetitorsTool extends BaseTool {
client;
constructor(client) {
super(client);
this.client = client;
}
getName() {
return 'dataforseo_labs_google_serp_competitors';
}
getDescription() {
return "This endpoint will provide you with a list of domains ranking for the keywords you specify. You will also get SERP rankings, rating, estimated traffic volume, and visibility values the provided domains gain from the specified keywords.";
}
getParams() {
return {
keywords: z.array(z.string()).describe(`keywords array
required field
the results will be based on the keywords you specify in this array
UTF-8 encoding;
the keywords will be converted to lowercase format;
you can specify the maximum of 200 keywords`),
location_name: z.string().default("United States").describe(`full name of the location
required field
in format "Country"
example:
United Kingdom`),
language_code: z.string().default("en").describe(`language code
required field
example:
en`),
limit: z.number().min(1).max(1000).default(10).optional().describe("Maximum number of keywords to return"),
offset: z.number().min(0).optional().describe(`offset in the results array of returned keywords
optional field
default value: 0
if you specify the 10 value, the first ten keywords in the results array will be omitted and the data will be provided for the successive keywords`),
filters: z.array(z.union([
z.array(z.union([z.string(), z.number(), z.boolean()])).length(3),
z.enum(["and", "or"])
])).max(8).optional().describe(`you can add several filters at once (8 filters maximum)
you should set a logical operator and, or between the conditions
the following operators are supported:
regex, not_regex, <, <=, >, >=, =, <>, in, not_in, match, not_match, ilike, not_ilike, like, not_like
you can use the % operator with like and not_like, as well as ilike and not_ilike to match any string of zero or more characters
merge operator must be a string and connect two other arrays, availible values: or, and.
example:
["ranked_serp_element.serp_item.rank_group","<=",10]
[["ranked_serp_element.serp_item.rank_group","<=",10],"or",["ranked_serp_element.serp_item.type","<>","paid"]]
[["keyword_data.keyword_info.search_volume","<>",0],"and",[["ranked_serp_element.serp_item.type","<>","paid"],"or",["ranked_serp_element.serp_item.is_malicious","=",false]]]`),
order_by: z.array(z.string()).optional().describe(`results sorting rules
optional field
you can use the same values as in the filters array to sort the results
possible sorting types:
asc – results will be sorted in the ascending order
desc – results will be sorted in the descending order
the comma is used as a separator
example:
["avg_position,asc"]
default rule:
["rating,desc"]
note that you can set no more than three sorting rules in a single request
you should use a comma to separate several sorting rules
example:
["avg_position,asc","etv,desc"]`),
include_subdomains: z.boolean().optional().describe("Include keywords from subdomains")
};
}
async handle(params) {
try {
const response = await this.client.makeRequest('/v3/dataforseo_labs/google/serp_competitors/live', 'POST', [{
keywords: params.keywords,
location_name: params.location_name,
language_code: params.language_code,
limit: params.limit,
offset: params.offset,
filters: this.formatFilters(params.filters),
order_by: this.formatOrderBy(params.order_by),
}]);
return this.validateAndFormatResponse(response);
}
catch (error) {
return this.formatErrorResponse(error);
}
}
}