Tools reference
Every tool SerpPal's MCP server offers AI assistants, with each parameter, its limits and what it returns: articles, keyword analysis, media and publishing.
These are the tools an AI assistant gets when it connects to SerpPal. You don't call them yourself: you ask in plain words and the assistant picks the tools. This page helps you know what is possible and read what the assistant did.
All tools act as you, with your role in each project. Ids are the long codes SerpPal gives projects, articles, sites, posts and files (the assistant gets them from the list tools). Times are ISO 8601, for example 2026-11-06T09:00:00+06:00.
| Tool | What it does | Changes anything? |
|---|---|---|
list_projects | Lists your projects | No |
list_articles | Lists and searches articles | No |
get_article | Reads one article with its SEO guide | No |
update_article | Saves new content, title or meta description | Yes |
analyze_keyword | Starts a new article for a keyword | Yes, uses one analysis |
list_sites | Lists a project's connected sites | No |
list_media | Lists your images and videos | No |
add_media_from_url | Copies an image or video into your library | Yes, uses storage |
publish_article | Publishes or schedules an article | Yes |
list_posts | Lists posts | No |
get_post | Reads one post | No |
reschedule_post | Changes when a post goes out | Yes |
cancel_post | Cancels a post | Yes |
retry_post | Tries a failed post again | Yes |
Articles
list_projects
Lists the projects you can open (your own and ones shared with you).
No parameters.
Returns for each project: id, name, domain, your role (owner, editor or viewer), the number of articles, a count of articles by state, the average content score (avgScore) and lastActivity.
list_articles
Lists articles, most recently changed first.
| Parameter | Type | Required | Description |
|---|---|---|---|
project_id | string | No | Only articles in this project. Without it, articles from all your projects. |
search | string | No | Text to find in the keyword or the title. Up to 150 characters. |
status | string | No | todo (not finished or published yet) or published. |
limit | integer | No | Articles per page, 1 to 50. Default 20. |
page | integer | No | Page number, from 1. |
Returns articles (each with id, projectId, projectName, keyword, title, score, words, state, analysisStatus, targetUrl, updatedAt), plus page, pages and total.
get_article
Reads one article: its title, meta description, keyword, country and language, content score, word count, content, H2 and H3 headings, live URL, the posts made from it, and an SEO guide.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The article id. |
format | string | No | html (default; use it before editing) or text (easier to read, with headings marked by #). |
include_seo_guide | boolean | No | Include the SEO guide. Default true. |
The SEO guide (seoGuide) has: the target score and competitors' best and median scores, the target word count, the score's parts, up to 30 terms to add (with how often they are used now and the range to aim for), up to 10 overused terms, terms to use in headings, up to 12 missing topics, up to 10 questions to answer, and up to 8 tips. It is empty while the keyword analysis is still running.
Other useful fields: analysisStatus (queued, running, done or error), analysisError, editorUrl (a link to open the article in SerpPal) and role.
update_article
Saves changes to an article. Fields you leave out stay as they are. Needs edit access to the project.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The article id. |
title | string | No | The SEO title. Up to 300 characters. |
meta | string | No | The meta description. Up to 500 characters; about 150 to 160 works best. |
content_html | string | No | The whole article body as HTML (h2 and h3 headings, p, ul, ol, table, a, img, strong, em). Replaces the current content. The whole request must stay under 1 MB. |
At least one of title, meta or content_html is needed ("Nothing to change: give title, meta and/or content_html").
The content score and word count are recalculated with the same scorer as the editor. The version before the change is saved in the article's history with the note "Before an edit from an AI assistant", so you can restore it (see Versions and autosave).
Returns the new score and previousScore, words and previousWords, savedAt and editorUrl.
analyze_keyword
Starts a new article for a keyword in a project. SerpPal reads the top Google results and builds the brief and score, just like Analyze a keyword. Uses one analysis from your monthly plan. Needs edit access to the project.
| Parameter | Type | Required | Description |
|---|---|---|---|
project_id | string | Yes | The project to add the article to. |
keyword | string | Yes | The keyword, up to 150 characters. |
location | integer | No | The country as a Google Ads location code, for example 2840 United States, 2826 United Kingdom, 2050 Bangladesh. Default: the project's country. |
language | string | No | A language code such as en, de or pt-BR. Default: the project's language. |
Returns articleId and analysisStatus: "queued". The analysis takes about a minute; the assistant then calls get_article until analysisStatus is done. If your plan's analyses are used up, it gets the same message as in the app. See Countries and languages.
Media
list_media
Lists the images and videos in your media library, newest first, 24 per page.
| Parameter | Type | Required | Description |
|---|---|---|---|
kind | string | No | image or video. |
page | integer | No | Page number, from 1. |
Returns media (each with id, kind, mime, name, size in bytes, alt, the file's public url and createdAt), page numbers, and storage (used and limit in bytes; -1 means no limit).
add_media_from_url
Downloads an image or video from a public address into your media library. It counts toward your plan's storage.
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The public https address of the file. Up to 2,000 characters. |
alt | string | No | Alt text describing the image. Up to 300 characters. |
Accepts JPG, PNG, WebP, GIF and AVIF images up to 15 MB, and MP4, WebM and MOV videos up to 250 MB. For YouTube or Vimeo, don't download: pass the link to publish_article as video_url.
Returns the new media (use its id in publish_article) and storage.
Publishing
list_sites
Lists the sites connected to a project, with the ids to use in publish_article. Passwords, keys and tokens are never included: secret fields only show true when they are set.
| Parameter | Type | Required | Description |
|---|---|---|---|
project_id | string | Yes | The project id. |
Returns sites, each with id, name, platform (wordpress, shopify, ghost, webflow or webhook), label, its non-secret settings, lastChecked and the last error.
publish_article
Publishes an article to a connected site now, or schedules it. It follows the same rules as the Publish dialog (see Publish and schedule): the article is sent as it is when the post goes out, the first H1 is removed, and publishing the same article to the same site again updates that post. Needs edit access to the project. Assistants are told to ask you before calling it.
| Parameter | Type | Required | Description |
|---|---|---|---|
article_id | string | Yes | The article id. |
site_id | string | Yes | The site id from list_sites. The site must be connected to the article's project. |
when | string | No | When to publish: an ISO 8601 time with a time zone, for example 2026-11-06T09:00:00+06:00 or 2026-11-06T03:00:00Z. Leave it out, or use now, to publish now. Within the next two years. |
as_draft | boolean | No | true sends it as a draft instead of a live post. Default false. |
title | string | No | Post title, up to 300 characters. Default: the article title. |
slug | string | No | URL slug, up to 200 characters. Default: made by the site. |
excerpt | string | No | Up to 1,000 characters. Default: the article's meta description. |
tags | array of strings | No | Up to 20 tag names, 80 characters each. |
categories | array of strings | No | Up to 20 category names, 80 characters each. |
featured_image_id | string | No | The media id of an image for the featured image. |
featured_image_alt | string | No | Alt text for the featured image, up to 300 characters. |
media | array | No | Up to 40 images or videos to place in the post (see below). |
Each item in media:
| Field | Type | Required | Description |
|---|---|---|---|
position | string | Yes | top, end or after_heading. |
media_id | string | One of these two | A media id from list_media or add_media_from_url. |
video_url | string | One of these two | A YouTube, Vimeo or video file link to embed. |
heading | string | With after_heading | The text of the H2 or H3 heading to place it after. Case doesn't matter, and part of the heading is enough if only one heading contains it. |
alt | string | No | Alt text (or a title for videos), up to 300 characters. |
caption | string | No | Caption, up to 500 characters. |
When publishing now, the tool waits up to 10 seconds for the result. It returns the post and a note: "Published.", "Publishing failed: ...", that the site didn't answer and it will be retried, that it is still in progress (check with get_post), or "Scheduled for ...".
Errors you may see: "is not a full ISO 8601 time with a timezone", "give either media_id or video_url", "after_heading needs the heading text in "heading"", "this article has no H2 or H3 headings", and "no heading matches ..." followed by the list of the article's headings.
list_posts
Lists posts, upcoming first, 20 per page.
| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | No | scheduled, publishing, published, failed or canceled. |
project_id | string | No | Only posts in this project. |
article_id | string | No | Only posts of this article. |
page | integer | No | Page number, from 1. |
Returns posts, page numbers, total, and counts by status.
get_post
Reads one post.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The post id. |
A post has: status, publishAs (publish or draft), publishAt (when it is due), publishedAt, the live url, any error, the number of attempts, the articleId, projectId and siteId, the site and article, and the options chosen (title, slug, excerpt, tags, categories, featured image and media).
reschedule_post
Changes when a scheduled, failed or canceled post goes out. It is scheduled again.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The post id. |
when | string | Yes | The new time (ISO 8601 with a time zone), or now to publish right away. |
A published post can't be rescheduled: "This post is already published. To update it on the site, call publish_article again for the same article and site."
cancel_post
Cancels a scheduled or failed post so it doesn't go out. Nothing is removed from the site.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The post id. |
retry_post
Tries a failed or canceled post again, right now, and waits up to 10 seconds for the result.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The post id. |
Errors
- A tool that can't find something answers with its message and "Check the id, or that this account can open it." The id is wrong, or your account can't open that project.
- A tool you aren't allowed to use in a project (for example
update_articleas a viewer) answers with the access error. - Wrong arguments are refused before anything runs, for example "Invalid arguments for publish_article: arguments.when must be a string".
- An unexpected problem answers "Something went wrong on SerpPal's side. Please try again."
Limits on calls and request size are in Security and limits.