appsmith-mcp

appsmith-mcp

MCP server for interacting with a self-hosted Appsmith instance via its REST API, enabling read/update/create of pages, queries, JS objects, widgets, datasources, and applications with lazy session management and destructive-operation gating.

Category
访问服务器

README

appsmith-mcp

MCP server for a self-hosted Appsmith instance, over Appsmith's own REST API — the same API the editor uses.

Built because no reliable Appsmith MCP server exists: there is nothing published on npm or PyPI, nothing in the appsmithorg GitHub org, and the listings that surface in search results are auto-generated stubs with no implementation behind them.

How it authenticates

Appsmith uses Spring Security form login behind CSRF protection:

  1. A GET /api/v1/users/me seeds an XSRF-TOKEN cookie.
  2. POST /api/v1/login sends username/password form-encoded, echoing that token in the X-XSRF-TOKEN header.
  3. The response sets a SESSION cookie used for every later call.

The client logs in lazily on first use and re-logs in once automatically on a 401, so an expired session heals itself instead of failing a tool call.

Setup

npm install
cp .env.example .env         # then put your Appsmith password in .env
npm run check                # read-only checks against the live instance
npm run check -- --scratch   # also covers writes, via a throwaway app it deletes

npm run check prints a PASS/FAIL row per endpoint — run it whenever an Appsmith upgrade might have moved routes. --scratch creates an mcp-smoke-* application, exercises create-page / publish / delete against it, and removes it again.

Registration

Registered at user scope, so it is available in every project rather than one:

claude mcp add appsmith --scope user -- \
  node --env-file-if-exists=<abs-path>/.env <abs-path>/src/index.js

That writes to ~/.claude.json. Paths must be absolute — a user-scope server is launched from whatever directory the session happens to be in.

Credentials are read from .env via Node's --env-file-if-exists, so no secret lives in the MCP config. Because .env pins one instance, retarget it by changing APPSMITH_URL.

To scope it back to a single project, claude mcp remove appsmith --scope user and put the same command in that project's .mcp.json.

Tools

Read

Tool Endpoint
appsmith_whoami GET /api/v1/users/me
appsmith_list_workspaces GET /api/v1/workspaces/home
appsmith_list_applications GET /api/v1/applications/home
appsmith_list_pages GET /api/v1/pages/application/{id}
appsmith_get_page GET /api/v1/pages/{id}
appsmith_list_queries GET /api/v1/actions
appsmith_list_js_objects GET /api/v1/collections/actions
appsmith_list_datasources GET /api/v1/datasources
appsmith_get_datasource_structure GET /api/v1/datasources/{id}/structure
appsmith_list_plugins GET /api/v1/plugins
appsmith_search_entities GET /api/v1/search-entities
appsmith_export_application GET /api/v1/applications/export/{id}

Edit — changing an existing app's logic

Tool Endpoint
appsmith_update_query PUT /api/v1/actions/{id}
appsmith_create_query POST /api/v1/actions
appsmith_update_js_object PATCH /api/v1/collections/actions/{id} + PUT .../body
appsmith_create_js_object POST /api/v1/collections/actions
appsmith_delete_query DELETE /api/v1/actions/{id} — gated
appsmith_delete_js_object DELETE /api/v1/collections/actions/{id} — gated
appsmith_get_widget GET /api/v1/pages/{id} (one widget)
appsmith_update_widget PUT /api/v1/layouts/{layoutId}/pages/{pageId}
appsmith_clone_widget PUT /api/v1/layouts/{layoutId}/pages/{pageId}
appsmith_generate_crud_page POST /api/v1/pages/crud-page

Write — structure and lifecycle

Tool Endpoint
appsmith_create_workspace POST /api/v1/workspaces
appsmith_create_application POST /api/v1/applications
appsmith_create_page POST /api/v1/pages
appsmith_execute_query POST /api/v1/actions/execute
appsmith_publish_application POST /api/v1/applications/publish/{id}
appsmith_clone_application POST /api/v1/applications/clone/{id}
appsmith_delete_application DELETE /api/v1/applications/{id} — gated
appsmith_api_request any route; non-GET gated

Editing is deliberately typed rather than left to appsmith_api_request: the raw tool is gated behind ALLOW_DESTRUCTIVE and cannot be safely auto-approved, since it can reach any endpoint. The typed tools each do one thing, so they can be allow-listed individually.

appsmith_update_query sends only the fields you pass — the server merges the rest, so the datasource and untouched settings survive. It deliberately does not rename: renaming needs a refactor pass that rewrites bindings across the app, and a plain PUT would leave every reference broken.

Adding widgets

There is deliberately no "create widget from scratch" tool. Appsmith's widget defaults live in its frontend, not its API — /api/v1/widgets, /widget-config and /configs all 404 — and a real widget carries 24–65 properties depending on type. A hand-written defaults catalogue would replicate frontend logic, drift on every Appsmith upgrade, and fail silently when it did. The two supported routes instead:

  • appsmith_clone_widget copies a widget that Appsmith itself created, so the defaults are always correct and there is nothing to maintain. Every descendant gets a fresh widgetId and a free name (Canvas1Canvas2, internointerno1); names only need to be unique per page. The copy is placed below its siblings so it cannot land on another widget. Bindings inside the copy are not rewritten — one that referenced the source by name still points at the original, so the response returns renamedInsideCopy for the caller to fix.
  • appsmith_generate_crud_page calls Appsmith's own generator for a whole screen.

Bindings

appsmith_update_widget maintains dynamicBindingPathList for you. Appsmith only evaluates {{ }} on properties listed there and the server does not infer it: a binding written without registration is stored verbatim and rendered as a literal string — which, for a boolean like isDisabled, is always truthy. Setting a binding adds the path; setting a literal removes it. A widget's other properties are preserved, since the whole layout is read, patched and written back.

Safety

  • appsmith_delete_application and non-GET appsmith_api_request calls refuse to run unless APPSMITH_MCP_ALLOW_DESTRUCTIVE=true.
  • appsmith_execute_query runs against the real datasource — a write query writes. It is not gated, since running queries is the point, so check what a query does before running it.
  • Large payloads (page DSLs, exports) are truncated at APPSMITH_MCP_MAX_CHARS. appsmith_get_page returns a widget outline by default; pass full=true for the raw layout. appsmith_export_application takes an outputPath to write to disk instead of returning inline.

Instance quirks found while building this

Two behaviours differ from what the CE controllers suggest, both handled in the code:

  • GET /applications/home documents workspaceId as optional, but this instance rejects the call without it. appsmith_list_applications fans out across every workspace when no id is given.
  • POST /pages rejects an empty layouts array, and layouts: [{}] silently creates a page whose DSL is null — blank and unusable in the editor. The root CANVAS_WIDGET canvas must be sent explicitly; see src/defaults.js.

Maintenance

Routes were taken from the Appsmith backend controllers, not guessed:

  • controllers/ce/ApplicationControllerCE.java
  • controllers/ce/PageControllerCE.java
  • controllers/ce/ActionControllerCE.java
  • controllers/ce/DatasourceControllerCE.java
  • controllers/ce/WorkspaceControllerCE.java
  • constants/ce/UrlCE.java

Appsmith's API is not a documented public contract, so a major upgrade can move a route. npm run check is the fast way to find out.

License

MIT — see LICENSE.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选