# How the MCP Server Enables External AI Clients to Drive the Instatic CMS

> Discover how the Instatic MCP server securely connects external AI clients to your CMS. Execute operations via capability-filtered tools at the _/instatic/mcp endpoint.

- Repository: [CoreBunch/Instatic](https://github.com/CoreBunch/Instatic)
- Tags: internals
- Published: 2026-07-29

---

**The Instatic MCP server acts as a secure bridge that authenticates external AI agents and executes CMS operations through capability-filtered tools, exposing functionality at the `/_instatic/mcp` endpoint.**

The Model Context Protocol (MCP) implementation in Instatic transforms your content management system into an AI-programmable platform. By exposing a structured tool catalog over HTTP, the MCP server enables external AI clients like Claude, Codex, and custom connectors to read styles, publish sites, and manage content programmatically. This architecture separates authentication, capability gating, and execution into distinct layers defined in the server's AI module.

## MCP Server Entry Point and Routing

All MCP traffic enters through a dedicated HTTP endpoint defined in [`server/router.ts`](https://github.com/CoreBunch/Instatic/blob/main/server/router.ts). The server registers the `/_instatic/mcp` path as the primary entry point for Model Context Protocol requests.

When an external AI client sends a request to this endpoint, the system first validates credentials through the middleware chain. Unauthenticated requests receive an immediate **401 Unauthorized** response before reaching the tool execution layer. This routing structure ensures that only verified connections can access the CMS control plane.

## Authentication Methods for AI Connections

The [`server/ai/mcp/auth.ts`](https://github.com/CoreBunch/Instatic/blob/main/server/ai/mcp/auth.ts) module resolves incoming bearer tokens into validated connection tuples containing `{ connectorId, userId, capabilities }`. Instatic supports two distinct authentication modes, both stored as persistent grants in the `ai_mcp_connectors` table.

### Personal Access Tokens (PAT)

Personal access tokens provide direct API access for local CLI tools and custom integrations. Generated from the administrative UI via the **Create access token** flow, these tokens are returned once as plaintext and stored internally as SHA-256 hashes.

Clients authenticate by including the token in the `Authorization` header.

```ts
import { createMcpAccessToken } from '@core/ai/mcp/connectors/token';

const { accessToken, connection } = await createMcpAccessToken({
  userId,
  label: 'my-cli',
  capabilities: ['ai.tools.write', 'pages.publish'],
  ttlDays: 30,
});

```

### OAuth 2.0 with PKCE

For third-party applications, Instatic implements the OAuth Authorization Code flow with PKCE extension. The flow begins when the client reads the well-known metadata from `/.well-known/oauth-protected-resource`, then registers as a dynamic client at `/_instatic/oauth/register`.

The user authorizes the connection through the admin UI at `/admin/ai/oauth/authorize`. Tokens rotate on each use and are stored hashed in the database, providing enhanced security for public clients.

```ts
import { exchangeCodeForToken } from '@core/ai/mcp/oauth/store';

const token = await exchangeCodeForToken({ code, codeVerifier });

```

## Capability-Based Tool Registry

Once authenticated, requests reach the tool registry defined in [`server/ai/mcp/server.ts`](https://github.com/CoreBunch/Instatic/blob/main/server/ai/mcp/server.ts) and [`server/ai/mcp/registry.ts`](https://github.com/CoreBunch/Instatic/blob/main/server/ai/mcp/registry.ts). The system filters the full tool catalog against the connection's granted capabilities defined in [`src/core/capabilities.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/capabilities.ts).

The `toolAllowedForCapabilities` gate ensures that AI clients can only invoke operations explicitly granted during connection setup. For example, a connection with `ai.tools.read` but without `ai.tools.write` cannot execute mutating operations.

## Tool Execution Models

Instatic distinguishes between two execution modes depending on whether the connection owner's editor workspace is active.

### Headless Tools

Headless commands like `site_read_styles` and `site_publish` execute directly against repository or publisher APIs without requiring an open browser session. These tools bypass the editor state and interact immediately with the underlying data stores.

### Browser-Relay Tools

Mutations that affect draft content route through [`server/ai/mcp/editorBridge.ts`](https://github.com/CoreBunch/Instatic/blob/main/server/ai/mcp/editorBridge.ts), which forwards calls to the live workspace of the connection owner. This ensures that all changes pass through the single source-of-truth draft store.

If the workspace is not currently open, the tool returns a scope-specific error rather than failing silently or creating orphaned states.

## Publishing Workflow and Audit Trails

The `site_publish` tool demonstrates the full capability stack. Before execution, the server verifies that the connection possesses both `ai.tools.write` and `pages.publish` capabilities. Upon validation, the tool triggers the static-site pipeline located in `server/publish/*` and records the connection ID in the audit event, creating a permanent log of AI-initiated deployments.

## Processing MCP Requests

The following example demonstrates how the server resolves an incoming MCP request with authentication:

```ts
import { resolveMcpRequest } from '@core/ai/mcp/server';

const result = await resolveMcpRequest({
  path: '/_instatic/mcp',
  method: 'POST',
  headers: { Authorization: 'Bearer imcp_pat_…' },
  body: { tool: 'site_publish', args: {} },
});

```

## Summary

- The MCP server exposes CMS functionality at `/_instatic/mcp` via [`server/router.ts`](https://github.com/CoreBunch/Instatic/blob/main/server/router.ts), creating a standardized entry point for AI agents.
- **Dual authentication modes** support both long-lived Personal Access Tokens and rotating OAuth 2.0 credentials stored in the `ai_mcp_connectors` table.
- **Capability gating** filters tool access through `toolAllowedForCapabilities`, ensuring least-privilege access for external clients.
- **Two execution models** handle operations either headlessly or through the browser relay in [`editorBridge.ts`](https://github.com/CoreBunch/Instatic/blob/main/editorBridge.ts), maintaining data consistency with the editor workspace.
- All operations are audited, with publishing workflows requiring explicit `pages.publish` capability in addition to tool access.

## Frequently Asked Questions

### What AI clients can connect to the Instatic MCP server?

Any client implementing the Model Context Protocol can connect, including Claude Desktop, OpenAI Codex, Cursor, and custom-built connectors. The server accepts standard JSON-RPC requests over HTTP at the `/_instatic/mcp` endpoint, making it compatible with any MCP-compliant agent.

### How do capabilities restrict what an AI client can do?

Capabilities act as granular permissions defined in `CORE_CAPABILITIES`. When a connection is established, the grant records specific capability strings like `ai.tools.write` or `pages.publish`. The [`server/ai/mcp/server.ts`](https://github.com/CoreBunch/Instatic/blob/main/server/ai/mcp/server.ts) filters the exposed tool catalog based on these grants, preventing unauthorized access to destructive operations even if the bearer token is valid.

### What happens if I try to run a browser-relay tool when the editor is closed?

The system returns a specific error indicating the workspace is unavailable rather than executing the command against stale state. This design prevents data conflicts by ensuring that [`editorBridge.ts`](https://github.com/CoreBunch/Instatic/blob/main/editorBridge.ts) can only forward mutations to an active editing session where the draft store is loaded in memory.

### Can I revoke an AI connection after creation?

Yes. Both Personal Access Tokens and OAuth grants can be revoked through the admin UI or by deleting the record from the `ai_mcp_connectors` table. Revocation takes effect immediately, causing subsequent requests to return 401 errors as handled by [`server/ai/mcp/auth.ts`](https://github.com/CoreBunch/Instatic/blob/main/server/ai/mcp/auth.ts).