Last updated:

Afina MCP Server#

The Afina MCP server connects an AI agent to the local Afina HTTP API through the standard Model Context Protocol. The agent gets not a "chat with hints", but a set of real tools: reading accounts and scripts, launching browsers, checking proxies, working with RPA modules, task groups, logs, cookies, and migration from other antidetect browsers.

  • Transport: stdio
  • Package: npx -y afina-mcp
  • Afina API: http://localhost:50778 or http://127.0.0.1:50778
  • Authentication: the AFINA_API_KEY environment variable
  • Live check: afina-mcp returns Tools: 92, resources: 5

How Afina MCP works#

Afina MCP Server is a stdio server for AI clients that translates MCP calls into HTTP requests to the local Afina API. When Afina is running, the desktop app starts a local HTTP server on port 50778; if the port is busy, Afina tries the next ports in the range.

Afina MCP Server

The AI client does not access the Afina database directly and does not edit profile files manually. It calls an MCP tool, afina-mcp validates the arguments, sends an HTTP request to Afina with x-api-key, receives the response, and returns it to the agent in MCP format.

afina-mcp is a separate npm package. It does not store Afina session state and lives only as long as the MCP client keeps it running.

Prerequisites#

Before connecting, check your local environment.

WhatHow to checkWhy it is needed
Afina is runningthe app is open locallyStarts the HTTP API
Afina API keySettings → General → API keyPassed as AFINA_API_KEY
Node.js 18+node --versionRuns npx
npxnpx --versionDownloads afina-mcp
Claude Codeclaude --versionMCP client for the connection

Without a valid AFINA_API_KEY, most Afina /api/* endpoints will return 401 Unauthorized or close the connection. The MCP server also will not start correctly without this variable.

Connecting through CLI#

Afina MCP connects to any AI agent in the same way: the client starts npx -y afina-mcp as a local process with the stdio transport and gets access to all 92 Afina tools through the AFINA_API_KEY variable. The only difference between clients is where the config is stored.

Claude Code

For the current project (recommended):

powershell

For all projects of the current user:

powershell

Check the connection:

powershell
text

Codex CLI and other CLI clients

CLI clients without a built-in mcp add command connect MCP through a config file. For Codex CLI, this is ~/.codex/config.yaml:

yaml

For Gemini CLI, use ~/.gemini/settings.json or .gemini/settings.json in the project (the JSON format is shown in the next section).

Connecting through an agent#

Do not want to enter commands manually? Copy the prompt below, replace [INSERT_KEY] with your API key, and send it to the agent - it will complete all steps by itself.

text

If you use --scope project, add .mcp.json to .gitignore. This file stores AFINA_API_KEY, so it must not be committed to the repository. Similarly, exclude any config file that contains the key from git.

After connecting, restart the client. MCP tools are loaded when a new session starts - the server may be added correctly, but the tools will not appear until restart.

Configuring config files#

If the MCP client expects a JSON config, use the standard stdio format. It is the same for all clients that support the MCP specification.

json
ClientConfig path
Claude Desktop (Windows)%APPDATA%\Claude\claude_desktop_config.json
Claude Desktop (macOS)~/Library/Application Support/Claude/claude_desktop_config.json
Cursor.cursor/mcp.json in the project root or ~/.cursor/mcp.json globally
Windsurf~/.codeium/windsurf/mcp_config.json
Gemini CLI.gemini/settings.json in the project or ~/.gemini/settings.json globally
ClineMCP settings in the VS Code extension GUI
Continue.continue/config.json in the project

The "type": "stdio" field can be optional - some clients detect the transport automatically when command is set. If the client does not recognize the config, check the documentation for the specific version.

Config files that contain AFINA_API_KEY should be excluded from version control. For team workflows, store the key in a secrets manager or CI/CD environment variables.

How the agent calls tools#

When you write "show me the list of accounts" to the agent, Claude Code does not run shell commands directly. It sends a JSON-RPC call to stdin of the afina-mcp process.

json

afina-mcp turns this into an HTTP request to local Afina, adds x-api-key, receives a JSON response, and returns it to the agent.

For direct diagnostics without restarting Claude Code, you can run tools/list manually.

powershell

The live tools/list response confirms 92 tools and 5 resources. If your local list differs, your current afina-mcp has priority over this page.

Available tools#

Below are the tool groups confirmed by the live tools/list. Tool and parameter names remain in English because they are part of the executable API.

Accounts and profiles#

ToolRequired parametersWhat it does
list_accounts-Returns accounts with groupId, tagId, isRunning filters
resolve_accountqueryResolves a UUID, name, numberId, or DB id into a full account
get_accountaccountIdReads one account by UUID
create_account-Creates a persistent profile with fingerprint, proxy, tags, groups, settings
create_one_time_profile-Creates a disposable profile, launches the browser, and deletes it after stop
update_account-PATCH update for an account by id or accountId
delete_accountaccountIdSoft-deletes an account
hard_delete_account-Permanently deletes by id, ids, accountId, or accountIds

If the user asks for a "temporary", "single-use", "disposable", or "one-time" profile, the agent must call create_one_time_profile, not create_account. Regular create_account creates a persistent account.

Browser session and page#

ToolRequired parametersWhat it does
start_browserprofileIdLaunches the browser and returns wsEndpoint
stop_browserprofileIdCloses the browser through CDP
eval_in_browserprofileId, codeRuns JavaScript in the current tab
find_clickableprofileId, textFinds a clickable element by text
find_inputprofileId, queryFinds an input field
get_current_urlprofileIdReturns the active tab URL
get_page_textprofileIdReads page text, supports selector and maxChars
take_screenshotprofileIdTakes a screenshot of the current tab

This group gives the agent a "one-off AI session" mode: launch an account, open the required page, read text, take a screenshot, find a button or field, and close the browser without writing an RPA script.

Cookies#

ToolRequired parametersWhat it does
set_cookiesaccountId, cookiesQueues cookies for import into an account
export_cookies-Exports cookies by id, ids, accountId, or accountIds

set_cookies is useful for moving authorized sessions. If the account is not running, cookies will be applied on the next browser start.

RPA scripts#

ToolRequired parametersWhat it does
list_scripts-Returns the list of scripts
get_scriptidReads the full structure of one script
create_scriptname, settingsCreates an RPA script
update_scriptidUpdates a script
run_scriptprofileId, scriptIdRuns a script on one profile; optionally closeBrowserAfter
get_run_logsuuidReads logs from a direct run
stop_running_scriptuuidStops a running script

The script structure uses settings.elements[], settings.connections[], exactly one start:true, and settings.startElement. Before generating a complex script, the agent should read the afina://docs/rpa-blocks resource and the afina://docs/script-schema schema.

executeModule modules#

ToolRequired parametersWhat it does
list_modules-Returns the list of JS modules
get_module-Reads a module by id or hash
create_modulenameCreates a module and its file directory
update_moduleidUpdates the module row in the DB
resign_moduleidRecomputes the Ed25519 module signature
delete_module-Soft-deletes a module
hard_delete_module-Deletes the module row and directory

After editing module files, resign_module is always required. Without a fresh signature, the executor may return modules.error.signature_invalid.

Task groups, tasks, and running across multiple accounts#

ToolRequired parametersWhat it does
list_task_groups-Returns task groups
get_task_groupidReads a task group
get_task_group_tasksgroupIdReads tasks for a specific group
create_task_group-Creates a group with schedule, timeout, and parallelism
update_task_groupidUpdates a task group
start_task_groupidActivates the group scheduler
restart_task_groupidMoves completed tasks back to waiting
stop_task_groupidStops a group
delete_task_groupidSoft-deletes a group
hard_delete_task_group-Permanently deletes a group
add_tasks_to_groupgroupId, scriptId, accountIdsAdds tasks to a group
run_script_on_accountsscriptId, accountIdsCreates or reuses a group and runs a script as a composite operation
list_tasks-Filters tasks by status, groupId, accountId, scriptId, limit
get_active_tasks-Shows active tasks
get_task_logstaskUuidReads task logs
update_taskidUpdates status, executeAt, additionalData, sort, tag, description
delete_tasks-Deletes tasks
stop_tasks-Stops tasks, optionally with closeBrowser

Key orchestration fields: schedule, timeFrom, timeTo, scheduleTime, startHour, endHour, isRepeatable, repeatCount, timeout, activeSession, waitForOtherTaskCompletion.

Proxies, email, databases, and variables#

ToolRequired parametersWhat it does
check_proxies-Checks account proxies by accountIds, groupId, or tagId
check_all_proxies-Checks all saved proxies
add_proxyhost, portAdds a proxy after validation
list_emails-Returns IMAP credentials without passwords
toggle_emailemail, isActiveEnables or disables IMAP monitoring
list_databases-Returns database connections
get_databaseidReads one connection
create_databasenameCreates a SQLite/Postgres/MySQL/MSSQL/MongoDB/Redis connection
update_databaseidUpdates a connection
delete_database-Soft-deletes a database
hard_delete_database-Deletes the row and file if filePath exists
list_global_vars-Returns global variables
create_global_varname, valueCreates a variable
update_global_varidUpdates a variable
delete_global_var-Deletes variables
list_keys-Returns the key catalog
delete_keys-Deletes key names from the catalog
get_account_vars-Reads account variables by account reference
set_account_varkey, valueWrites a plain or encrypted variable
delete_account_varkeyDeletes an account variable

For accounts, the agent should usually call resolve_account first when the user names an account by name, number, or short text reference. resolve_account returns both fields: UUID accountId and numeric id. UUID works for most tools (start_browser, get_account, export_cookies, and others). Exception: run_script_on_accounts, add_tasks_to_group, and check_proxies accept numeric id, not UUID - use the id field from the resolve_account response for these three tools.

Migration from other antidetect browsers#

ToolRequired parametersWhat it does
set_vendor_credentialsvendor, tokenStores a Vision, AdsPower, or Dolphin token
list_vendor_credentials-Shows which vendor credentials are configured
delete_vendor_credentialsvendorDeletes vendor credentials
vision_list_folders-Lists Vision folders
vision_list_profilesfolderIdLists Vision profiles
vision_get_profilefolderId, profileIdFull Vision profile
vision_list_proxiesfolderIdVision proxies
vision_export_cookiesfolderId, profileIdVision cookies
vision_import_profilesfolderId, profileIdsBulk-imports Vision profiles into Afina
adspower_list_groups-AdsPower groups
adspower_list_profiles-AdsPower profiles
adspower_get_profileuserIdFull AdsPower profile
adspower_export_cookiesuserIdAdsPower cookies
adspower_import_profilesuserIdsBulk-imports AdsPower profiles
dolphin_whoami-Dolphin token check
dolphin_list_profiles-Lists Dolphin profiles
dolphin_get_profileprofileIdFull Dolphin profile
dolphin_export_cookiesprofileIdDolphin cookies
dolphin_import_profilesprofileIdsBulk-imports Dolphin profiles

Import supports dryRun, withCookies, tagNames, accountGroupNames, and vendor-specific throttling for cookie export.

CDP tools#

ToolRequired parametersWhat it does
cdp_inspect_browserportReads /json/version from any Chromium with CDP
cdp_export_cookiesport or wsEndpointExports cookies through CDP
migrate_via_cdpport or wsEndpointCreates an Afina account and moves cookies from a running Chromium

The CDP approach is needed when the source does not have a public API for cookie export or when you need to quickly move the current authorized session.

Built-in resources#

Afina MCP also exposes resources. These are not tools for actions, but reference documents the agent should read before complex operations.

URIWhen to read
afina://docs/rpa-blocksBefore generating or editing an RPA script
afina://docs/script-schemaBefore create_script or update_script
afina://docs/tools-cheatsheetWhen it is unclear which MCP tool matches the request
afina://docs/import-mappingBefore importing from Vision, AdsPower, Dolphin, MoreLogin, Octo, Linken Sphere
afina://docs/new-vendor-templateWhen you need to add import from a new vendor

For scripts and migrations, resources are part of the workflow. A correct agent first reads the reference document and only then calls the write-tool.

Practical scenarios#

Check all proxies before starting activity#

text

The agent calls check_all_proxies, groups results by result.status, shows slow proxies separately, and does not proceed to a destructive action without confirmation.

Launch a browser and read a page without an RPA script#

text

Typical flow: resolve_accountstart_browser → navigation through eval_in_browser or CDP → get_page_texttake_screenshotstop_browser.

Run a script on a group of accounts#

text

The agent should first find the script through list_scripts, resolve accounts through resolve_account or list_accounts, and then use run_script_on_accounts with activeSession: 10, schedule: true, timeFrom: "09:00", timeTo: "15:00", and timeout.

Investigate execution errors#

text

The agent uses list_task_groups, get_task_group, get_task_group_tasks, and get_task_logs. If the cause is in the script, it reads get_script; if the cause is in proxies, it calls check_proxies for the specific accounts.

Update a JS module after an API change#

text

Minimum correct flow: list_modulesget_module → edit the module through the available write path → update_module if needed → resign_module. Without resign_module, the module may fail signature validation.

Import profiles from Dolphin#

text

Correct flow: set_vendor_credentials if the token is not stored yet → dolphin_list_profilesdolphin_import_profiles with dryRun: true → confirmation → dolphin_import_profiles without dryRun.

Move a session from any Chromium through CDP#

text

The agent uses cdp_inspect_browser, then migrate_via_cdp or the cdp_export_cookiescreate_accountset_cookies chain.

Security and limitations#

  • The agent should not see encrypted password values or secret variables; it works with names, metadata, and allowed API responses.
  • delete_account is a soft-delete, while hard_delete_account permanently deletes profile rows and files.
  • delete_module, delete_task_group, and delete_database are soft-delete operations; hard_delete_* variants physically delete data.
  • create_one_time_profile automatically hard-deletes the profile after the browser stops.
  • For destructive actions, it is better to ask the agent to first show the list of target objects and wait for confirmation.
  • .mcp.json, claude_desktop_config.json, and .cursor/mcp.json can contain AFINA_API_KEY; do not publish these files.

Do not send the agent "delete everything", "clear all profiles", or "hard delete without confirmation" as the first request. First ask for a dry-run list: which accountId, ids, modules, or groups will be affected.

Troubleshooting#

ProblemLikely causeWhat to do
AFINA_API_KEY env is requiredThe env variable was not providedAdd -e AFINA_API_KEY=... or env in the JSON config
401 UnauthorizedInvalid API keyCopy the key from Afina again
afina does not appear in toolsClaude Code has not been restartedClose the session and open a new one
npx: command not foundNode.js or npm is not installedInstall Node.js 18+
MCP is connected, but Afina tools failAfina is not running or the port is differentStart Afina and check AFINA_URL
Browser does not startInvalid profileId or the account is already in a problematic stateUse resolve_account, then start_browser with UUID
Module does not run after editingresign was not executedCall resign_module
Vendor import does not workMissing credentials or an incorrect baseUrlCheck list_vendor_credentials and set_vendor_credentials

Minimal checklist#

text

After this, the agent can work with Afina as a controlled system: read state, launch browsers, create tasks, analyze logs, edit scripts, and move sessions without manual copying between interfaces.

Related glossary