****** Latest Updates *******
Date: 2026-08-03
- Added region-aware Anaplan authentication for Basic, OAuth2, and certificate flows.
- Credentials now use region-prefixed
.envvariables; unprefixed credential variables are ignored. - Added root
config.yamlwith regional nicknames, endpoint URLs, active flags, and credential variable mappings. - Added region-aware API, OAuth, Integration API, and Playwright instance routing.
- Updated remote HTTP authentication to require the selected region's OAuth client ID.
- Updated
.env.examplewith the new region-prefixed credential and runtime configuration format. - Added and updated tests for regional authentication, instance routing, HTTP validation, and Playwright configuration.
- Full verification passes: 223 tests, typecheck, and build.
This document should be read alongside Anaplan's current modeling guidance:
- Your modeling experience: https://help.anaplan.com/your-modeling-experience-ee72bb4a-463f-44f7-bfb1-09892a951472
- Model building recommendations: https://help.anaplan.com/model-building-recommendations-6d742812-f1c7-4296-a504-651b1c8086f3
- Planual: https://support.anaplan.com/planual-5731dc37-317a-49fa-a5ff-7fc3926972de
Apply these principles when using the MCP tools against live models:
- Start with the business case, not the API endpoint. Identify the planning process, decision points, facts, lists, time ranges, versions, and users before changing structures or data.
- Follow DISCO module separation: Data, Input, System, Calculation, and Output modules should have clear responsibilities. Do not mix imports, assumptions, business logic, and reporting line items in one module unless the model owner has intentionally designed it that way.
- Respect the Central Library. Lists, subsets, line item subsets, time, versions, users, roles, and naming conventions are shared model architecture, not disposable integration artefacts.
- Prefer narrow dimensionality. Use only the dimensions required for a calculation or input. Use subsets, line-item applies-to, and time ranges to reduce cell count and improve performance.
- Keep formulas simple, reusable, and auditable. Break complex logic into intermediate line items, use system modules for mappings and attributes, and avoid hard-coded item references where a lookup or mapping module is more maintainable.
- Preserve model-builder intent. Before writing cells, adding list items, running imports, or changing calendar/version settings, inspect modules, line items, dimensions, saved views, actions, and task history so the operation follows the existing model design.
- Use saved views and purpose-built import/export actions for integrations. Do not treat ad hoc grid reads/writes as a substitute for governed integration processes when a model already exposes actions or processes.
- Validate before and after every write. Check source file mapping, dimensional coordinates, access permissions, model state, task result, rejected rows, and downstream output modules.
- Protect ALM and production controls. Treat structural changes, list changes, current period, fiscal year, switchover, delete actions, and model open/close as governed operations that may affect production users.
- Document assumptions. Record the model, workspace, module/view/action used, dimensional filters, version/time context, and any Planual trade-offs made during automation.
Setup guide: platform-aware install walkthrough for Windows, macOS, and Linux with OAuth2 / Certificate / Basic Auth options.
A Model Context Protocol (MCP) server that connects AI assistants to Anaplan's Integration API v2. Gives LLMs like Claude direct access to browse workspaces, manage data, run imports/exports, and administer models through 70 structured tools, using your existing Anaplan credentials and permissions.
Built in TypeScript. Supports both stdio (local) and Streamable HTTP (remote) transports. Works with Claude Desktop, Claude Code, claude.ai, and any MCP-compatible client. Includes a built-in orchestration guide that teaches the AI assistant the correct tool sequences for every workflow.
Note: This server was developed using Hermes Agent. Claude Code has not been tested as a development environment for this project.
Anaplan's Integration API is powerful but requires technical expertise to use directly. Most teams rely on a handful of model builders to navigate complex models, extract data, and run imports - creating bottlenecks when others need access to the same information.
This server wraps the API in 76 structured tools (including 3 with Playwright UI automation fallback) that AI assistants like Claude can call on your behalf. Explore models, pull data, run actions, and onboard new team members - all by asking in plain English instead of writing API calls or waiting for someone who knows the model.
For business users: Stop waiting for someone to pull data or explain how a model works. Ask Claude to show you the numbers, walk you through module structure, or run your regular imports.
For model builders and consultants: Analyze model structure, trace formula dependencies, review line item configurations, and identify performance issues - all through conversation instead of clicking through hundreds of modules manually.
For IT and platform teams: Standard API access using your existing authentication and permissions. No new credentials, no elevated access. Open source for auditability. Anaplan data is processed by your AI assistant - locally or through your provider's environment depending on your setup.
Model Documentation:
- "Show me the structure of the Supply Planning model"
- "List all line items and their formulas in the Revenue module"
- "What dimensions does the Margin line item use?"
Data Review:
- "Pull the current pricing data for all products"
- "Show me which list items were recently added"
- "Read the forecast numbers for Q3 and summarize"
Impact Analysis:
- "What modules use the Product list as a dimension?"
- "Show all line items that reference Cost Per Unit"
- "Which views include the Region dimension?"
Automation:
- "Run the monthly demand import and show me the result"
- "Export sales actuals and save to Downloads"
- "Add these 50 new products to the master list"
Onboarding:
- "Walk me through the modules in this model"
- "How is this model structured? What are the key lists?"
- "What changed in this model since last quarter?"
This server was developed using the Hermes Agent - an AI agent framework from Anthropic that powers tools like Claude Code. The development workflow involved orchestrating multiple AI agents to implement, test, and document the Anaplan MCP integration.
Note: While development was done using Hermes Agent, this repository is intended for general use with any MCP-compatible client. The Hermes Agent toolset enables automated multi-step workflows that accelerate development, but the resulting MCP server itself is platform-agnostic and works with Claude Desktop, Claude Code, claude.ai, and other MCP clients.
- Browse workspaces, models, modules, lists, and views
- Read cell data and list items
- Write cell values and manage list items (add, update, delete)
- Run imports, exports, processes, and delete actions
- Upload and download files
- Manage models (open, close, delete, set periods and fiscal year)
- Change model mode, create lists, and create modules via Playwright UI automation (when API returns 405)
- Query users, versions, and task history
The Anaplan API does not support:
- Defining formulas through API
- Building model structure from scratch
- Configuring model calendar programmatically
For structural creation (lists, modules, line items) blocked by the API on some tenants, enable Playwright UI automation (ANAPLAN_PLAYWRIGHT_ENABLED=true). See the Playwright UI Automation section below and docs/guides/anaplan-playwright-structural-crud.md.
- Node.js 18+ - download here
- An Anaplan account with API access (any auth method - basic, certificate, or OAuth)
- An MCP-compatible client - Claude Desktop (recommended), Claude Code, or any other MCP client
git clone https://github.com/tinstep/hermes-anaplan-mcp.git
cd hermes-anaplan-mcp
npm install
npm run buildTwo ways to connect: build a Claude Desktop extension (.mcpb file, single-click install, settings editable in Claude's UI) or edit the JSON config by hand. The extension is recommended unless you need remote HTTP mode or want to run from source without packaging.
npm run build:extensionThis compiles the server, stages a production-only copy (no dev dependencies, no docs/tests), and packs it into anaplan-mcp.mcpb in the repo root. Requires the prerequisites above; npx will fetch the @anthropic-ai/mcpb packaging tool on first run.
Then in Claude Desktop: Settings → Extensions → Install from file... and pick anaplan-mcp.mcpb. Claude renders a settings form for every field defined in manifest.json's user_config (instance, OAuth client ID, username/password, certificate paths, and the Playwright toggles) — fill in whichever auth method you're using and leave the rest blank. Nothing needs manual JSON editing, and secrets like the password field are masked.
If you later enable the Playwright fallback, install its browser binary inside the installed extension folder (Claude shows the path under the extension's details):
cd <extension folder>
npm install playwright && npx playwright install chromiumRe-run npm run build:extension and reinstall whenever you pull new code — the bundle isn't auto-updated from source.
Step 1: Open the config file
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
C:\Users\<YourUsername>\AppData\Roaming\Claude\claude_desktop_config.json
If the file doesn't exist yet, create it with {} as the contents.
Tip (Windows): You can type
%APPDATA%\Claudein the File Explorer address bar to jump straight to the folder.
Step 2: Add the Anaplan server
Replace <path> with the absolute path to your cloned repo (e.g. /Users/you/anaplan-mcp on macOS/Linux or C:/Users/you/anaplan-mcp on Windows - always use forward slashes).
Choose one auth method only. For most users, use OAuth2 so Claude can show a sign-in link in chat. Do not set OAuth, certificate, and basic env vars together.
Also choose which Anaplan instance (tenant region) to connect to via ANAPLAN_INSTANCE. This controls auth, API, OAuth, and Playwright UI routing. Supported values today: us1 (default) and au1. See Anaplan instances below for details and for connecting to instances not built in.
Recommended: OAuth2 (device grant)
{
"mcpServers": {
"anaplan": {
"command": "node",
"args": ["<path>/dist/index.js"],
"env": {
"ANAPLAN_CLIENT_ID": "your-client-id",
"ANAPLAN_INSTANCE": "us1"
}
}
}
}On first use, Claude shows a link in chat, approve it in Anaplan, then retry your request. OAuth tokens are kept in memory only. If the MCP process restarts, or an OAuth session is idle for more than 60 minutes, you'll be prompted to authorize again unless you provide ANAPLAN_REFRESH_TOKEN yourself.
OAuth support is device grant only. ANAPLAN_CLIENT_SECRET, ANAPLAN_OAUTH_AUTHORIZATION_CODE, and ANAPLAN_OAUTH_REDIRECT_URI are ignored by the server.
If you do not want OAuth, use one of these alternatives instead:
Certificate auth
"env": {
"ANAPLAN_CERTIFICATE_PATH": "/path/to/cert.pem",
"ANAPLAN_PRIVATE_KEY_PATH": "/path/to/key.pem"
}ANAPLAN_CERTIFICATE_ENCODED_DATA_FORMAT can be added optionally; defaults to v2. Set v1 only for legacy tenants.
Basic auth
"env": {
"ANAPLAN_USERNAME": "user@company.com",
"ANAPLAN_PASSWORD": "your-password"
}Use this only if you want email/password auth instead of OAuth or certificate auth. If your Anaplan account uses SSO, basic auth may not work unless your tenant allows exception users.
If your config file already has content, add mcpServers inside the existing top-level object - don't create a second {} block.
Step 3: Restart Claude Desktop
Quit Claude Desktop completely (right-click the system tray icon and quit - don't just close the window) and reopen it. You should see the Anaplan tools available (look for the hammer icon in the chat input area).
Troubleshooting:
- "Unexpected non-whitespace" error - Your JSON is invalid. Make sure there's only one
{}object in the file and no trailing commas. Paste your config into jsonlint.com to check. - Server disconnected - Run
node C:/path/to/hermes-anaplan-mcp/dist/index.jsin a terminal to see the actual error. Common causes: wrong path inargs, missingnpm run build, or Node.js not installed. - 401 Unauthorized when using tools - Your Anaplan credentials are wrong, or your account uses SSO (in which case basic auth won't work - use certificate or OAuth2 instead).
- OAuth refresh failed / reauthorization required - The MCP server is up and reached Anaplan, but the saved OAuth session is no longer valid. Re-authorize in your MCP client, then retry the tool.
Note: Claude Code was not used as a development environment for this project. If you encounter issues, try using Claude Desktop first for comparison.
Copy .mcp.json.example to .mcp.json and fill in your credentials. The file is gitignored by default - never commit credentials to version control.
cp .mcp.json.example .mcp.jsonAlternatively, use the CLI:
claude mcp add anaplan -- node /absolute/path/to/hermes-anaplan-mcp/dist/index.jsAny MCP-compatible client that supports stdio transport can connect. The server expects to be launched as a subprocess with stdin/stdout for communication. Pass Anaplan credentials via environment variables.
The server also supports Streamable HTTP transport for remote MCP connections from claude.ai, ChatGPT, and other browser-based AI assistants. Deploy the Docker image to a supported cloud or self-hosted platform and connect via the remote MCP integration settings.
Remote HTTP mode is designed for per-session Anaplan OAuth, not a single shared Anaplan user. Set the region-prefixed client ID in the Hermes .env file (for example AU1A_ANAPLAN_CLIENT_ID) so each remote session can authorize against Anaplan with its own identity. If you want an extra outer gate in front of the endpoint, you can also set ANAPLAN_MCP_HTTP_AUTH_TOKEN and have your client or reverse proxy send it as Authorization: Bearer <token>.
See the Remote Deployment Guide for full setup instructions, platform recommendations, and troubleshooting.
Anaplan tenants live on different instances (regions). Set ANAPLAN_REGION once to select the endpoints used by OAuth, certificate and basic auth, transactional/bulk API calls, and the optional Playwright UI fallback. ANAPLAN_INSTANCE remains a backwards-compatible override.
| Region / nickname | Auth base URL | API base URL | OAuth/UI base URL |
|---|---|---|---|
us1a / usa |
https://auth.anaplan.com |
https://api.anaplan.com |
https://us1a.app.anaplan.com |
au1a / aws (default) |
https://au1a.app2.anaplan.com |
https://api.au1a.app2.anaplan.com |
https://au1a.app2.anaplan.com |
If neither selector is set, the server uses default_region from config.yaml. Authentication and API endpoints must come from the same region; regional tokens are not interchangeable with the global API.
For an instance that isn't built in, set ANAPLAN_INSTANCE to any identifier and provide endpoint overrides:
"env": {
"ANAPLAN_INSTANCE": "eu1",
"ANAPLAN_INSTANCE_AUTH_BASE_URL": "https://auth.anaplan.com",
"ANAPLAN_INSTANCE_API_BASE_URL": "https://api.anaplan.com",
"ANAPLAN_INSTANCE_OAUTH_BASE_URL": "https://eu1a.app.anaplan.com",
"ANAPLAN_INSTANCE_UI_BASE_URL": "https://eu1a.app.anaplan.com"
}ANAPLAN_INSTANCE_UI_BASE_URL is optional for custom instances and defaults to ANAPLAN_INSTANCE_OAUTH_BASE_URL. For catalogued regions, API and browser fallback operations resolve from the same config.yaml entry.
Region selection is supplied through environment variables. Regional endpoint metadata and human-maintained activation flags are loaded at runtime from the root config.yaml; secrets remain in Hermes .env files.
| Method | Env Vars | Description |
|---|---|---|
| OAuth2 (device grant) | <REGION>_ANAPLAN_CLIENT_ID, <REGION>_ANAPLAN_REFRESH_TOKEN (optional) |
Highest priority. Device authorization flow. Claude shows you the URL and code in chat; authorize in browser then retry. Tokens stay in memory only, so restart or >60 minutes of idle time requires another device login unless you set the region-prefixed refresh token |
| Certificate | <REGION>_ANAPLAN_CERTIFICATE_PATH, <REGION>_ANAPLAN_PRIVATE_KEY_PATH, <REGION>_ANAPLAN_CERTIFICATE_ENCODED_DATA_FORMAT (optional) |
Second priority. PEM certificate + private key, authenticates via CACertificate flow. Data format defaults to v2 |
| Basic | <REGION>_ANAPLAN_USERNAME, <REGION>_ANAPLAN_PASSWORD |
Lowest priority. Email + password, sends base64 credentials to the regional auth endpoint |
Set ANAPLAN_REGION or ANAPLAN_PLAYWRIGHT_REGION to select the region. For example, AU1A_ANAPLAN_USERNAME and AU1A_ANAPLAN_PASSWORD are selected for au1a. Credentials are loaded from Hermes .env files only; unprefixed credential variables are ignored. If multiple authentication methods are configured for the selected region, the server picks the highest-priority method automatically.
The root config.yaml is the runtime source of truth for regional endpoints, nicknames, the default region, and credential env-file paths. It contains no credential values.
Each region defines:
active: whether the region is currently enabled for this installationnickname: human-friendly region nameapi_access_url: Anaplan API base URLplaywright_access_url: user-facing Anaplan URL for browser automationintegration_url: Integration API hosttoken_url: Basic authentication token endpointoauth_token_url: OAuth token endpoint when availablecredentials.env_file: source.envfile for credentialscredentials.username_env_var: username variable namecredentials.password_env_var: password variable name
The current active regions are au1a (aws) and us1a (usa). All other catalogued regions are inactive. Review entries marked REVIEW before enabling those regions.
Example:
default_region: au1a
default_env_file: /home/cam/.hermes/.env
regions:
au1a:
active: true
nickname: aws
api_access_url: https://api.au1a.app2.anaplan.com/2/0
playwright_access_url: https://au1a.app2.anaplan.com
integration_url: https://api.au1a.app2.anaplan.com
token_url: https://au1a.app2.anaplan.com/token/authenticate
credentials:
env_file: /home/cam/.hermes/.env
username_env_var: AU1A_ANAPLAN_USERNAME
password_env_var: AU1A_ANAPLAN_PASSWORDThese apply only to npm run start:http / remote MCP deployments:
| Variable | Description |
|---|---|
<REGION>_ANAPLAN_CLIENT_ID |
Required for remote HTTP mode. Each HTTP session uses the selected region's OAuth client to authenticate the end user with Anaplan |
ANAPLAN_MCP_HTTP_AUTH_TOKEN |
Optional extra edge protection. When set, callers must also send it as Authorization: Bearer <token>. MCP_HTTP_AUTH_TOKEN is accepted as an alias |
ANAPLAN_MCP_HTTP_BODY_LIMIT |
Optional JSON body limit for remote HTTP requests. Defaults to 100mb to support large run_import and upload_file payloads. MCP_HTTP_BODY_LIMIT is accepted as an alias |
- Hermes: Put region-prefixed Anaplan credentials in
~/.hermes/.envor the active profile's.env; keep only non-secret runtime flags in MCP configuration - Regional catalog: Edit the root
config.yamlto change region metadata, activation status, or environment-variable names - Other MCP clients: Use their server-specific
"env"block if required, but never commit credentials
Security note: Never commit credentials to version control. Env files and MCP config files are gitignored by default in this repo.
This server has full access to whatever your Anaplan credentials allow. The 76 tools cover read, write, action, admin, and UI automation operations:
- Read-only tools (safe to use freely):
show_*tools,read_cells,get_list_items,download_file,get_action_status - Write tools (modify data):
write_cells,add_list_items,update_list_items,delete_list_items,create_list,create_module,add_lineitem,delete_list,delete_module - Action tools (trigger Anaplan processes):
run_import,run_export,run_process,run_delete - Admin tools (model management):
close_model,open_model,bulk_delete_models,set_currentperiod,set_fiscalyear - UI automation tools (Playwright browser fallback):
set_modelmode,create_list(UI path),create_module(UI path)
Claude Desktop prompts you before each tool call. You'll see the tool name and parameters, and can approve or deny. This gives you a chance to review before any action runs. You can also use the "Allow for this chat" option for tools you trust.
- Start with read-only. Ask Claude to explore your workspaces and models before running any write operations. Get comfortable with the tool output first.
- Prefer the Anaplan REST API. Use the standard API/MCP tools for authentication, workspace/model discovery, module/list/line-item reads, cell reads/writes, imports, exports, and any operation with a supported API endpoint. Do not use Playwright or browser control for login or read-only queries.
- Use browser automation only as a last resort. Use Playwright/browser control only when the required API endpoint does not exist or Anaplan rejects a supported structural API operation (for example, tenant-restricted creation of modules, lists, or line items). Do not switch to the browser merely because an API call needs pagination, retries, or parameter discovery.
- Test in a dev workspace. If you have a non-production Anaplan workspace, use that while getting familiar with the tools.
- Use least-privilege credentials. If your Anaplan admin can create a service account with limited workspace access, use that instead of your personal admin account.
- Review before confirming write operations. When Claude proposes to run an import, write cells, or delete items, read the parameters carefully before approving.
- Exports and imports are asynchronous. The server polls until they complete (up to 5 minutes). You can cancel a running task with
cancel_taskif needed.
| Tool | Description |
|---|---|
show_workspaces |
List all accessible workspacesGET /workspaces |
show_workspacedetails |
Get workspace details (size and active status)GET /workspaces/{workspaceId} |
show_models |
List models in a workspace. Optional state filter: UNLOCKED, PRODUCTION, ARCHIVED, LOCKED, MAINTENANCE, PRODUCTION_MAINTENANCEGET /workspaces/{workspaceId}/models |
show_allmodels |
List all models across all workspaces. Optional state filter: UNLOCKED, PRODUCTION, ARCHIVED, LOCKED, MAINTENANCE, PRODUCTION_MAINTENANCEGET /models |
show_modeldetails |
Get model details including state and workspaceGET /models/{modelId} |
show_modelstatus |
Check model status (legacy endpoint, often returns 405)POST /workspaces/{workspaceId}/models/{modelId}/status |
show_modules |
List modules in a modelGET /workspaces/{workspaceId}/models/{modelId}/modules |
show_moduledetails |
Get module details by filtering module listGET /workspaces/{workspaceId}/models/{modelId}/modules |
show_lineitems |
List line items in a module (includeAll supported)GET /models/{modelId}/modules/{moduleId}/lineItems |
show_alllineitems |
List all line items in a model (includeAll supported)GET /models/{modelId}/lineItems |
show_lineitem_dimensions |
List dimensions for a line itemGET /models/{modelId}/lineItems/{lineItemId}/dimensions |
show_lineitem_dimensions_items |
List dimension items for a line item/dimension pairGET /models/{modelId}/lineItems/{lineItemId}/dimensions/{dimensionId}/items |
show_savedviews |
List saved and default views in a moduleGET /workspaces/{workspaceId}/models/{modelId}/modules/{moduleId}/views |
show_allviews |
List all views in a model (cross-module)GET /models/{modelId}/views |
show_viewdetails |
Get view axis metadata (rows, columns, pages)GET /models/{modelId}/views/{viewId} |
show_lists |
List lists (dimensions) in a modelGET /workspaces/{workspaceId}/models/{modelId}/lists |
get_list_items |
Get items from a listGET /workspaces/{workspaceId}/models/{modelId}/lists/{listId}/items |
show_listmetadata |
Get list metadata including parent/properties/countGET /workspaces/{workspaceId}/models/{modelId}/lists/{listId} |
show_dimensionitems |
List all items in a model-level dimensionGET /models/{modelId}/dimensions/{dimensionId}/items |
show_viewdimensionitems |
List selected dimension items for a viewGET /models/{modelId}/views/{viewId}/dimensions/{dimensionId}/items |
lookup_dimensionitems |
Resolve dimension items by names/codesPOST /workspaces/{workspaceId}/models/{modelId}/dimensions/{dimensionId}/items |
show_imports |
List import actions in a modelGET /workspaces/{workspaceId}/models/{modelId}/imports |
show_importdetails |
Get import metadataGET /workspaces/{workspaceId}/models/{modelId}/imports/{importId} |
show_exports |
List export actions in a modelGET /workspaces/{workspaceId}/models/{modelId}/exports |
show_exportdetails |
Get export metadataGET /workspaces/{workspaceId}/models/{modelId}/exports/{exportId} |
show_processes |
List process actions in a modelGET /workspaces/{workspaceId}/models/{modelId}/processes |
show_processdetails |
Get process metadataGET /workspaces/{workspaceId}/models/{modelId}/processes/{processId} |
show_files |
List files in a modelGET /workspaces/{workspaceId}/models/{modelId}/files |
show_actions |
List model actions (including deletes)GET /workspaces/{workspaceId}/models/{modelId}/actions |
show_actiondetails |
Get action metadataGET /workspaces/{workspaceId}/models/{modelId}/actions/{actionId} |
show_currentperiod |
Get current periodGET /workspaces/{workspaceId}/models/{modelId}/currentPeriod |
show_modelcalendar |
Get fiscal year/calendar settingsGET /workspaces/{workspaceId}/models/{modelId}/modelCalendar |
show_versions |
List version metadataGET /models/{modelId}/versions |
show_currentuser |
Get current authenticated userGET /users/me |
show_users |
List users in tenant scopeGET /users |
show_userdetails |
Get user details by IDGET /users/{userId} |
show_tasks |
List task history for imports/exports/processes/actionsGET /workspaces/{workspaceId}/models/{modelId}/{actionType}/{actionId}/tasks |
| Tool | Description |
|---|---|
run_export |
Run export task, download output, optionally save locally with saveToDownloads and fileNamePOST .../exports/{exportId}/tasks |
run_import |
Upload file chunks, run import, and poll task completionPOST .../imports/{importId}/tasks |
run_process |
Run process task and poll completionPOST .../processes/{processId}/tasks |
run_delete |
Run delete action taskPOST .../actions/{deleteActionId}/tasks |
upload_file |
Initialize chunked upload, upload chunks, and complete file uploadPOST .../files/{fileId} |
download_file |
Download file by reading all chunk payloads. Text returns inline; binary files should use saveToDownloadsGET .../files/{fileId}/chunks |
delete_file |
Delete model file (irreversible)DELETE .../files/{fileId} |
get_action_status |
Get status for import/export/process/action taskGET .../{actionType}/{actionId}/tasks/{taskId} |
close_model |
Close (archive) a modelPOST .../models/{modelId}/close |
open_model |
Open (wake up) a closed modelPOST .../models/{modelId}/open |
bulk_delete_models |
Delete multiple closed modelsPOST /workspaces/{workspaceId}/bulkDeleteModels |
set_currentperiod |
Set current periodPUT .../models/{modelId}/currentPeriod |
set_fiscalyear |
Update model fiscal yearPUT .../models/{modelId}/modelCalendar/fiscalYear |
set_versionswitchover |
Set version switchover datePUT /models/{modelId}/versions/{versionId}/switchover |
download_importdump |
Download failed import dump chunks (CSV)GET .../imports/{importId}/tasks/{taskId}/dump/chunks |
download_processdump |
Download failed process dump chunks (CSV)GET .../processes/{processId}/tasks/{taskId}/dumps/{objectId}/chunks |
cancel_task |
Cancel running import/export/process/action taskDELETE .../{actionType}/{actionId}/tasks/{taskId} |
create_view_readrequest |
Create large-volume view read requestPOST .../views/{viewId}/readRequests |
get_view_readrequest |
Get large-volume view read request statusGET .../views/{viewId}/readRequests/{requestId} |
get_view_readrequest_page |
Download a CSV page from view read requestGET .../views/{viewId}/readRequests/{requestId}/pages/{pageNo} |
delete_view_readrequest |
Delete large-volume view read requestDELETE .../views/{viewId}/readRequests/{requestId} |
preview_list |
Preview up to 1000 records from a large list (CSV) before a full large read requestGET .../lists/{listId}/readRequests/preview |
create_list_readrequest |
Create large-volume list read requestPOST .../lists/{listId}/readRequests |
get_list_readrequest |
Get large-volume list read request statusGET .../lists/{listId}/readRequests/{requestId} |
get_list_readrequest_page |
Download a CSV page from list read requestGET .../lists/{listId}/readRequests/{requestId}/pages/{pageNo} |
delete_list_readrequest |
Delete large-volume list read requestDELETE .../lists/{listId}/readRequests/{requestId} |
reset_list_index |
Reset list item index numberingPOST /models/{modelId}/lists/{listId}/resetIndex |
download_optimizer_log |
Download Optimizer solver log for a completed actionGET .../optimizeActions/{actionId}/tasks/{correlationId}/solutionLogs |
| Tool | Description |
|---|---|
read_cells |
Read cell data from a module viewGET /models/{modelId}/views/{viewId}/data?format=v1 |
write_cells |
Write values to specific module cellsPOST /models/{modelId}/modules/{moduleId}/data |
add_list_items |
Add new items to a listPOST .../lists/{listId}/items?action=add |
update_list_items |
Update existing list itemsPUT .../lists/{listId}/items |
delete_list_items |
Delete list itemsPOST .../lists/{listId}/items?action=delete |
add_lineitem |
Add one or more line items to a modulePOST /workspaces/{workspaceId}/models/{modelId}/modules/{moduleId}/lineItems |
delete_module |
Delete a module from a model (requires force=true)DELETE /workspaces/{workspaceId}/models/{modelId}/modules/{moduleId} |
delete_list |
Delete a list from a model (requires force=true)DELETE /workspaces/{workspaceId}/models/{modelId}/lists/{listId} |
Some Anaplan operations are blocked by the Transactional API v2.0 on certain tenants (returns HTTP 405). When Playwright UI automation is enabled, these tools automatically fall back to browser-based interaction with the Anaplan web interface.
| Tool | Description |
|---|---|
set_modelmode |
Change model mode via Anaplan UI (UNLOCKED, LOCKED, ARCHIVED, PRODUCTION, PRODUCTION_MAINTENANCE). Falls back to Playwright browser automation when the API returns 405 UI flow: Home → Model Management → select model → Change Mode → pick mode → OK |
create_list |
Create a new list via Anaplan UI. Falls back to Playwright when the API returns 405 UI flow: Open model → Settings → Lists → Add List → fill name → Save |
create_module |
Create a new module via Anaplan UI. Falls back to Playwright when the API returns 405 UI flow: Open model → Settings → Modules → Add Module → fill name → Save |
Playwright is an optional dependency and is installed by a normal npm install. Deployments that omit optional dependencies, including the .mcpb extension bundle, still boot normally; Playwright is only required when this feature is enabled.
Prerequisites:
npm install playwright && npx playwright install chromium && npx playwright install-deps chromiumEnvironment variables:
| Variable | Required | Description |
|---|---|---|
ANAPLAN_PLAYWRIGHT_ENABLED |
Yes | Set to true to enable Playwright fallback. Default: false |
ANAPLAN_INSTANCE |
No | Selects API, OAuth, and Playwright UI routing. Default: us1; built-in alternative: au1 |
ANAPLAN_PLAYWRIGHT_HEADLESS |
No | Set to false for interactive MFA entry. Default: true |
ANAPLAN_USERNAME |
Yes | Anaplan email (shared with API auth) |
ANAPLAN_PASSWORD |
Yes | Anaplan password (shared with API auth) |
Enabling it in Claude Desktop: add the variables above to the same env block used for auth, in your claude_desktop_config.json:
{
"mcpServers": {
"anaplan": {
"command": "node",
"args": ["<path>/dist/index.js"],
"env": {
"ANAPLAN_CLIENT_ID": "your-client-id",
"ANAPLAN_INSTANCE": "us1",
"ANAPLAN_PLAYWRIGHT_ENABLED": "true",
"ANAPLAN_USERNAME": "user@company.com",
"ANAPLAN_PASSWORD": "your-password"
}
}
}
}Leave ANAPLAN_PLAYWRIGHT_ENABLED unset (or "false") to keep the 3 fallback tools purely advisory — they'll still register, but return a guidance message instead of driving a browser, and Playwright itself never needs to be installed.
Architecture:
- Lazy browser lifecycle — Chromium launches on first use, authenticates, and stays alive for subsequent calls. After 5 minutes of idle time the browser closes gracefully.
- API-first with automatic fallback — tools attempt the REST API first; on HTTP 405 they invoke the Playwright UI automation. When Playwright is disabled, a guidance message tells the user to perform the action manually in the Anaplan UI.
- MFA support — if MFA is required and running headless, the tool throws a clear error. Set
ANAPLAN_PLAYWRIGHT_HEADLESS=falsefor interactive MFA entry. - Not installed vs. disabled — if
ANAPLAN_PLAYWRIGHT_ENABLED=truebut theplaywrightpackage isn't installed, the server still starts; only the fallback call itself fails, with an error telling you to runnpm install playwright.
Important notes:
- The Anaplan SPA renders model content inside an iframe named
"App shell content". Playwright automation usesframeLocatorfor model-level operations. - The models list page may use closed Shadow DOM or custom rendering that is invisible to Playwright DOM access. The automation includes screenshot-based fallbacks for these cases.
- All Playwright errors capture screenshots to
/tmp/anaplan-ui-debug/<action>-<timestamp>.pngfor diagnosis. - Patch
src/*.tsonly —npm run buildoverwritesdist/from source.
The server exposes a built-in MCP resource (anaplan://orchestration-guide) that AI assistants read automatically. This guide teaches the correct tool sequences for every workflow category:
- Navigation -- workspace -> model -> module -> line items/views
- Reading data -- discover modules, find views, read cells (with fallback to large volume reads for >1M cells)
- Writing data -- resolve line item dimensions and item IDs before calling write_cells
- Bulk imports -- inspect import definition, upload data to source file, run import, check status, download error dump if failed
- Bulk exports -- single-step run_export handles the full lifecycle
- Processes -- run chained actions, monitor with get_action_status
- Large volume reads -- create request, poll until complete, download pages, clean up
- List & structural mutations -- create/delete lists and modules, add line items, then add/update/delete list items
Every tool description also includes prerequisite hints ("Use show_imports first to find importId") and parameter descriptions explain where each value comes from ("from show_lineitems or show_alllineitems"). Key workflow tools append "Next steps" guidance to their responses.
src/
auth/ # Authentication providers (basic, certificate, oauth) + token manager
api/ # HTTP client with retry logic + 17 domain-specific API wrappers
ui/ # Playwright browser automation (AnaplanUI class) — lazy lifecycle, API-1st fallback
tools/ # MCP tool registrations (exploration, bulk, transactional, playwright) + response hints
resources/ # MCP resource content (orchestration guide)
server.ts # Wires auth > client > APIs > UI > MCP server + registers resources
index.ts # Entry point (stdio transport)
http.ts # Entry point (Streamable HTTP transport)
docs/
api/ # Anaplan API reference docs (Integration, ALM, SCIM, CloudWorks, Audit)
architecture/ # Runtime diagrams (request flow, trust boundary, subsystem map)
guides/ # Tool selection and workflow guides
examples/ # Example output - FY26 Sales Forecast deck generated via MCP
manifest.json # Claude Desktop extension (.mcpb) manifest — server config + user-editable settings
scripts/build-extension.sh # Packs manifest.json + dist/ into anaplan-mcp.mcpb (npm run build:extension)
Four layers:
- Auth layer - pluggable providers behind a common
AuthProviderinterface. TheAuthManagerselects the right provider from env vars and handles token lifecycle. - API layer -
AnaplanClienthandles all HTTP communication with the Anaplan API. 17 domain wrappers provide typed methods for each endpoint. Auto-paginates list endpoints using Anaplan'smeta.pagingmetadata. - UI layer -
AnaplanUI(Playwright) handles operations the Transactional API v2.0 blocks with HTTP 405. Lazy browser lifecycle: launches Chromium on first use, authenticates, stays alive for 5 minutes idle, then shuts down. Tools call the API first and fall back to Playwright on 405. - Tools layer - registers MCP tools on the server with zod schemas for input validation. Each tool delegates to the appropriate API wrapper (or UI fallback) and formats results. Key tools include next-step hints to guide multi-tool workflows.
For detailed runtime diagrams (request flow, trust boundary, subsystem map) see docs/architecture/overview.md.
The skills/ folder holds Claude Code project-level skills - reusable instruction sets that the AI assistant loads automatically during your session.
A template is provided at skills/example.md. Copy it, rename it, and fill in your instructions. Claude Code will pick it up as a skill available in this project.
Skills are gitignored by default (personal workflows vary), with only the example tracked. Add your own without worrying about committing them.
Unofficial personal project - not affiliated with, endorsed by, or supported by Anaplan. Uses the official Anaplan Integration API v2 - no undocumented endpoints. Users are responsible for compliance with Anaplan's Terms of Service. No warranty provided; use at your own risk.
GPL-3.0-only - see LICENSE file for details. Covers the code in this repository only. Anaplan's API and service are subject to Anaplan's Terms of Service and Acceptable Use Policy.