Mintlify Admin MCP lets AI agents create and edit documentation, restructure navigation, modify site configuration and SEO settings, manage branches, and open pull requests directly in Mintlify.
ChatGPT is OpenAI's assistant. It can add custom MCP servers as plugins, which lets it call your tools from a conversation.
This guide connects Mintlify Admin MCP to ChatGPT through MewCP, so ChatGPT can use Mintlify Admin MCP's 33 tools, like read, search and list_nodes, without your Mintlify Admin MCP credentials ever reaching the app.
Mintlify Admin MCP signs in through managed OAuth. MewCP stores the token encrypted, refreshes it before it expires and injects it only at call time. Your agent never holds it, so it can never leak it.
More apps
Manage repositories, pull requests, issues, branches and development workflows on GitHub. Automate software delivery and collaborate across engineering projects.
Connect to external APIs, webhooks and internet services through standard HTTP requests. Build integrations with virtually any platform that exposes a web-based interface.
Work with pages, databases, blocks and collaborative knowledge stored in Notion. Create, update and organize content while building workflows around structured information and documentation.
Give AI coding agents access to a curated library of real-world website designs, screenshots, design systems, and reusable UI components. Search visual references, find similar designs, analyze layouts, extract colors and typography, compare websites, and retrieve copy-ready JSX components for building better interfaces
Other clients
Mintlify Admin MCP works the same way in every client below. Pick yours for its own guide.
Free to start.
Scope access to the exact Mintlify Admin MCP tools and accounts you allow, work and personal side by side. Anything outside that scope is refused at call time, even when the model asks for it.
Each call is logged: what ran, on which account, and whether it worked. Failures come back structured, so the agent knows whether to retry instead of guessing.
Every app sits behind one secure MCP URL, and there is no server for you to deploy or keep running. Add an integration in the dashboard and it is live on the next call, with no config to change and no new credentials to wire up. Tools load only when a task needs them, so your agent stays fast and focused however many apps you connect.
In ChatGPT, open Plugins and choose Add custom MCP.
Name it "mewcp" and paste the server URL.
Click Connect. A sign-in window opens; sign in to MewCP and approve access. No API key needed.
Start a new chat and ask: "List the tools you can use from MewCP." You should see your connected apps.
Read the full MDX content of a single page on the current branch. Reflects in-session edits made via edit_page/write_page, not just the published version. `path` is the page href (e.g. "/quickstart" or "guides/setup"), with or without a leading slash or trailing .mdx, or the page id from an editor URL (".../~/<pageId>"). To read a private page, pass its `private-page-<uuid>` node id (from `list_nodes` with `visibility: "private"`); this requires a user-principal token and needs no checkout, but on an org-wide connection you must pass `subdomain` to pick the deployment. Returns `{ content, filePath }` on success, or `{ error: "read_failed", reason }` on failure (`reason` carries the human-readable diagnostic such as "No valid pageId found for page" or a hocuspocus connection error).
Find lines matching a substring or regex across every page on the current branch. Returns { matches, truncated } where each match is { path, lineNumber, line }, sorted by path. Reflects in-session edits: pages edited in this session are scanned even before indexing catches up. `query` is treated as a literal fixed string by default; pass `regex: true` for regex syntax. `caseSensitive` defaults to false. `limit` caps results (default 100, max 500). The response is bounded to 30KB — `truncated: true` indicates results were dropped and you should refine the query.
List navigation nodes with optional filters over the current branch nav tree. `parentId: null` returns root-level nodes; a string returns direct children of that node; omit for no filter. `recursive: true` extends the parent filter to all descendants of `parentId` — pair with `parentId: null` (or omit) to dump the entire tree in a single call. `type` accepts a single type or array (e.g. "group"). `language`, `version`, and `tab` are scope filters: a node passes only if its ancestor chain (including itself) contains a matching division node — filtering by a value not present in the tree returns empty. `limit` defaults to 500 (max 500). `cursor` is an opaque pagination token returned as `nextCursor`, stable across inserts. Returns { nodes, nextCursor } where nextCursor is null when exhausted. Pass `visibility: "private"` to instead list the private pages/folders the authorizing user can access (returns the full flat tree of `private-page-<uuid>` / `private-folder-<uuid>` nodes with their `role` and `workspaceSection` of "personal", "teamspace", or "shared"); this requires a user-principal token (not a client/M2M token), needs no checkout, and ignores the other filters — on an org-wide connection pass `subdomain` to pick the deployment.
Get current session state including branch name, edited files, and nav diff
Returns the list of changes between current session and main. Each entry lists `authors`, the members whose unpublished edits it contains, and `byYou`, whether it includes your own edits. An entry with no authors came from a sync or another system process.
String-replace edit on a page Y.Doc body. `path` is the page href or markdown file path (e.g. "/quickstart" or "guides/setup.mdx"), with or without a leading slash or trailing .mdx — the same forms `read` accepts, including markdown files that exist in the repo but are not listed in docs.json navigation. Use this for MDX content edits only — do NOT use it to change frontmatter fields (`title`, `sidebarTitle`, `description`, `icon`, `tag`, `canonical`, `og:*`, `keywords`, `noindex`, `hidden`, etc.); those round-trip through structured node metadata and must be set via `update_node` with `data.type='page'`. For the site-level `description` in `docs.json`, use `update_config`. Edits are broadcast live to connected collaborators: while a person has the page open, plain inline-text edits inside a single paragraph stream character-by-character (typing effect); otherwise they apply instantly, and structural edits always apply atomically. The returned `mode` reports which path ran (`inline-stream`, `inline` or `rebuild`). To edit a private page, pass its `private-page-<uuid>` node id as `path` (from `list_nodes` with `visibility: "private"`); this requires a user-principal token with an editor+ grant on that page, needs no checkout, and on an org-wide connection you must pass `subdomain` to pick the deployment.
Full overwrite of a page Y.Doc content. `path` accepts the same forms as `read` and `edit_page`: the page href or markdown file path, with or without a leading slash or trailing .mdx, including markdown files not listed in docs.json navigation. To overwrite a private page, pass its `private-page-<uuid>` node id (from `list_nodes` with `visibility: "private"`); this requires a user-principal token with an editor+ grant on that page, needs no checkout, and on an org-wide connection you must pass `subdomain` to pick the deployment. Creating a new private page is done via create_node, not write_page.
Insert a node into the navigation tree under `parentId` (null = root). `order` is clamped into siblings and defaults to append. `data` is discriminated by `type`: `page` seeds a Y.Doc from `{ path, content }` (MDX is validated), while `group`, `tab`, `anchor`, `version`, `language`, and `product` take their own name-shaped fields. Parent/child compatibility is enforced against an allowed-children table (e.g. groups cannot contain tabs; pages have no children). Pass `visibility: "private"` to create a real private page (`data.type: "page"`) or private folder (`data.type: "group"`) in Workspace — NOT a public page with `public:false` frontmatter. Private creation requires a user-principal token, ignores branch, needs no checkout, and places the node at the private root (`parentId: null`) or under a `private-folder-<uuid>` parent; the caller becomes its manager. Root placement defaults to Personal; pass `workspaceSection: "teamspace"` with `visibility: "private"` and `parentId: null` for Teamspace. Children inherit their parent section; omit `workspaceSection` for children. Creation under Shared with me is not supported. On an org-wide connection you must pass `subdomain` to pick the deployment. Returns the new `private-page-<uuid>`/`private-folder-<uuid>` node. Pages (public and private) also return `editorUrl` opening the new page in the dashboard; surface it to the user.
Update a navigation node's properties in place by nodeId — no repositioning. `data` is a discriminated union on `type` carrying partial, type-specific fields that are merged into existing `node.data`. For `type:'page'`, this is the correct tool for editing the page's frontmatter (`title`, `sidebarTitle`, `description`, `icon`, `tag`, `canonical`, `og:title`, `og:url`, `keywords`, `noindex`, `hidden`, `deprecated`, etc.) — the merged fields are serialized back into the MDX `---` block on save; do not use `edit_page` for these. `data.type` must match the stored node type. Immutable fields (`href`/`pageId` on pages, internal flags) are rejected — use `move_node` to rename a page path. Page updates emit an `update` pending action with source `metadata`; structural node updates emit an `update-navigation` action. Emits `editor_nav_updated`. Examples: set a page's frontmatter description (`{type:'page', description:'…'}`), rename a group (`{type:'group', group:'New Name'}`), change a tab icon, set a version as default. Private nodes update immediately without checkout; pass subdomain on org-wide connections. With an editor or manager grant, private pages support title, sidebarTitle, icon, iconType, and tag; private folders support group, icon, and tag.
Remove a node and its subtree from the navigation tree by `nodeId`. For pages in the removed set, the hocuspocus room, document S3 blob, and baseline (Redis + S3) are cleaned up. To add a redirect for a removed page, use `update_config` with `add_redirect`. To delete a private page or folder, pass its `private-page-<uuid>` or `private-folder-<uuid>` node id as `nodeId` (from `list_nodes` with `visibility: "private"`); this removes the node and its subtree from the per-user private tree and garbage-collects their page media, requires a user-principal token with a manager grant on that node, needs no checkout, and on an org-wide connection you must pass `subdomain` to pick the deployment. Returns `{ deletedNodeIds }`.
Reposition a node in the navigation tree by nodeId. `parentId: null` moves to root; omit to keep the current parent. `order` is 0-based among the new siblings; omit to append. At least one of `parentId` or `order` is required. Parent/child compatibility is enforced against the allowed-children table. Cross-boundary moves (across version, tab, language, or product ancestors) are allowed; the response flags them via `crossedBoundary`.
Add a local image file to the docs on the current session branch. Pass `contentType` and the exact `size` in bytes: the result is `{ uploadId, uploadUrl, method, headers }`; PUT the file bytes to `uploadUrl` with exactly those headers (for example `curl -X PUT --upload-file ./shot.png -H 'Content-Type: image/png' '<uploadUrl>'`), then call `finalize_image_upload`. This replaces the image at `path` if one already exists. Reference the returned `src` in MDX (``, via `edit_page`/`write_page`) or in docs.json `logo`/`favicon` (via `update_config`). The file's bytes must match the extension. Only `purpose: 'logo'` accepts SVG. The image is published with the session by `save`. For a Personal, Teamspace or Shared page, pass its `privatePage` id (`private-page-<uuid>`) to both tools: the image is saved to that page only and needs no checkout or `save`.
Save an image you uploaded to the `uploadUrl` from `upload_image` into the docs. Pass the `uploadId` and the destination `path` (and `purpose: 'logo'` for an SVG logo). The uploaded bytes are checked against the extension. Returns `{ src, path, mimeType }`. This replaces the image at `path` if one already exists. Pass the same `privatePage` as `upload_image` for a private page.
Update any top-level `docs.json` field except `navigation` (use the navigation tree tools for that). This is the ONLY way to change the site-level `description` (the SEO/social description for the whole docs site) — do not use `edit_page` (which targets page body) or `update_node` (which targets a single page's frontmatter description). `op` selects the operation: `set` ({ docsConfig }) shallow-merges any partial `docs.json` (e.g. `{ theme, name, description, colors, logo, favicon, api, appearance, background, navbar, footer, fonts, search, contextual, banner, interaction, errors, seo, styling, integrations, metadata, ... }` — see https://www.mintlify.com/docs.json); `add_redirect` ({ redirect: { source, destination, permanent? } }) appends to `redirects` (rejects on duplicate source); `remove_redirect` ({ source }) removes by source (rejects if missing). `set` rejects `navigation` and `$schema` keys. Set a top-level key to `null` in `docsConfig` to unset (remove) it entirely. The merged config is validated against the @mintlify/validation schema — any violation rejects the call with no partial writes. Returns `{ diff }` of only the changed fields: array-valued fields (e.g. `redirects`, `navbar.links`) report `{ added, removed }`, nested objects recurse under `{ changed }`, and scalar leaves report `{ before, after }`.
List all git branches available for a deployment before or after checkout. Pass `subdomain` to target a deployment; it defaults to the active session and is required before checkout on this org-wide connection. Optionally filter with `query` to only return matching branch names. Returns `{ branches, total, deployBranch }`.
Select a deployment and open its editor session in one call. This is an org-wide connection, so `subdomain` is required to choose which deployment to open. Subsequent editor tools act on the active session. Required before editor branch tools; deployment management tools (settings, analytics, workflows, members, auth) take their own `subdomain` and do not require checkout. Calling checkout on another subdomain switches the active session without losing the others; re-checking-out an already-open deployment just re-activates it. Pass `branch` to work on a specific branch — if it already exists in git, the session attaches to it as-is; if not, it is created from `from` (defaults to the deploy branch). Pass the deploy branch to edit it directly, as in the dashboard editor: edits appear live to anyone editing it, `save` publishes only your own changes as a commit, and `discard_session` reverts only your own changes; if the deploy branch requires pull requests, a session branch is created off it instead. Omit `branch` to auto-generate a fresh `admin-mcp/<slug>-<sha>` branch from `from` (uses `slug` when provided, otherwise the session id); if that branch already exists (e.g. a retried task) the session resumes it. Returns `{ branchName, sessionId, baseBranch, baseSha, created, note?, editorUrl, toolkit }`. `toolkit` groups the tools you should load next (`explore`, `editContent`, `editNavigation`, `editConfig`, `ship`) so you can call them without further discovery. Surface `editorUrl` to the user so they can follow along in the dashboard editor as the agent works; it opens the branch's default page, so once pages are created or edited prefer the page-level `editorUrl` returned by `create_node` and `save`.
Flush branch to git. With mode="auto" (default) opens a PR if none exists, otherwise commits to the existing PR branch; it only auto-merges when this deployment's agent review setting is push-to-main. With mode="pr" opens a PR if none exists, otherwise commits to the existing PR branch, and never auto-merges. With mode="commit" commits directly to the branch without opening a PR. Returns `editorUrl` opening the first created or edited page in the editor; surface it alongside `prUrl` for review. On the deploy branch, save ignores `mode` and commits only your own unpublished changes straight to it, like Publish in the dashboard editor.
End the session without creating a PR. On a session branch, deletes the branch if nothing was saved. On the deploy branch, reverts only your own unpublished changes and leaves everyone else's.
Get the ClickHouse schema, event taxonomy, traffic classification rules, and SQL conventions for query_analytics. Call this once before writing analytics SQL. Returns { schema } or { ok: false, error } when analytics querying is not enabled for the deployment.
Run one read-only ClickHouse SELECT against the deployment's documentation analytics (page views, agent vs human traffic, search, assistant, feedback). Rows are scoped to the deployment automatically; never filter by subdomain. `sql` is a single SELECT; `limit` caps rows when the SQL has no LIMIT (default 500, max 10000). Returns { ok: true, columns, rows, rowCount, truncated, elapsedMs } or { ok: false, error: { code, message } }; on an error, fix the SQL from the message and retry. Call get_analytics_schema first.
List the deployments this connection is authorized for, returning each `{ subdomain, name }`. On an org-wide connection this is every main (non-preview) deployment in your organization; on a connection scoped to specific deployments it returns only those. Use this to discover which subdomain to `checkout` before editing. Hidden when the connection is pinned to a single deployment.
Read a prebuilt dashboard analytics report for a deployment: traffic KPIs, page views, popular pages, referrals, agent traffic, user flows, CTA clicks, feedback, assistant chats and deflection, search quality, MCP search, and billing-period usage. Pick the report with `request.report`; its other fields are that report’s filters (dates are ISO strings). Large row sets are paginated: each result returns at most `maxRows` rows per list, and `nextRowOffset` when more remain. For custom SQL use query_analytics.
Read a deployment’s Workflows (scheduled and event-triggered agents) and their runs. `list` returns every workflow; `get` one by `workflowSchemaId`; `list_runs` and `list_run_groups` page through run history (most recent first, filtered by status); `get_run` returns one run with its PR, summary and timeline; `get_run_cost` its credits. Requires the Workflows entitlement.
List what workflows can connect to: `list_repos` pages through repositories connected via the org’s GitHub and GitLab installations, `list_pull_requests` lists a repo’s pull requests (most recently updated first), and `list_integrations` lists third-party integrations with their connection status and the `integrationId` to put in a workflow’s `tools.integrations`.
Read a deployment’s dashboard settings in one call: `deployment` (name, base path, custom domains, noindex, AI chat, search, add-ons, privacy, custom scripts, auth type, plan), `git_sources`, `custom_hostnames` (SSL and DNS validation), `source_checks`, plus opt-in `slack` and `snippets`. A section that fails (missing scope or entitlement) comes back as `{ error }` without failing the rest. Pass `subdomains` to compare several deployments.
Change a deployment’s custom domains. Applies immediately to the live site. `add` attaches a domain, `create_hostname` provisions its Cloudflare hostname and SSL, `retrigger_validation` re-checks a pending hostname, `remove` detaches a domain and `delete_hostname` deletes a hostname by id. Returns `state` with the deployment’s `customDomains` and each hostname’s validation status and DNS records.
Change the git repositories a deployment builds from. Applies immediately. `add` appends a source, `update` replaces the source at `index`, `remove` drops it, `reorder` takes the new order as existing indices, and `set_base` makes one source the base. Returns `state.git_sources` after the change.
Change one dashboard setting on a deployment. Applies immediately to the live site, with no branch or PR. Settings: `noindex`, `base_path`, `name`, `disable_ai_chat`, `editor_publishing`, `search_settings`, `search_filters`, `universal_search`, `feedback_add_on`, `audio_add_on`, `related_pages_add_on`, `source_checks`, `privacy`, `custom_scripts` (replaces the list), `auto_route_to_language`. docs.json settings go through update_config instead. Returns `state.deployment` (or `state.source_checks`) after the change.
Manage organization members and private-page sharing. Member actions apply org-wide: `list_members`, `remove_member`, `update_member_roles` (replaces roles), `update_member_git_username`. Sharing actions take a `private-page-<uuid>` / `private-folder-<uuid>` `nodeId` from list_nodes with visibility "private": `list_grants`, `set_grant`, `remove_grant`, `move_to_teamspace`, and `move_to_site` (checkout the destination branch first, then save). Writes require a user-authorized token and return the updated grant, roles, or moved pages.
Create, change, or run a deployment’s Workflows. Applies immediately. `create` and `create_scheduled` (one-time run at `nextRunAt`) take the workflow definition, `update` replaces it by `workflowSchemaId`, `set_enabled` toggles it, `delete` soft-deletes it, and `trigger` starts a run now with an optional scope. Returns the workflow, or `state` with the workflow or started run. Use get_workflows to inspect runs and list_repos_and_prs for repo and integration ids. Requires the Workflows entitlement.
Change who can read a deployment. Applies immediately to the live site. Deployment auth (`update_auth`, `delete_auth`, `add_password`, `delete_password`, `delete_jwt_key_pair`) gates the whole site; end-user auth (`update_user_auth`, `delete_user_auth`) personalizes content per reader; `toggle_auth` switches which one is active. `update_auth` and `update_user_auth` take their config under `request.input`. Requires a user-authorized token. Returns `state.deployment` with `authType` and `userAuthType` after the change.
Merge (`merge`, squash) or close (`close`) a Mintlify-generated pull request by `repo` and `prNumber`. Only when the user explicitly asks.
Change whether agent edits push directly to the deploy branch (`push_to_main`) or open a pull request (`create_pull_request`). Applies immediately. Only when the user explicitly asks. Returns `state.deployment`.