Start trial
PricingContact Us
Log InStart Free Trial

How TinyMCE AI Works: LLM Gateway, Model Routing, and JWT Role Gating

7 min read

How TinyMCE AI Works

Written by

Kim Woodfield

Category

Developer Insights

Integrating AI into a rich text editor is not just a UI problem.

Once you introduce large language models into an application that was traditionally client-side and deterministic, you inherit a new set of architectural concerns: model routing, prompt orchestration, authorization, and provider abstraction. Get those wrong and you end up with an integration that breaks every time a model changes, leaks permissions to the frontend, or bakes provider-specific logic into the editor runtime.

This article explains how TinyMCE AI addresses those problems through its gateway-based architecture, with a focus on model routing, prompt customization, and JWT-based role gating.

The problem with AI in the editor

Most AI-assisted writing still happens outside the editor. A user opens an AI chat window, pastes content into it, prompts the model, copies the result into the editor, then fixes formatting and context issues. This workflow works, but it breaks focus and disconnects the model from the document context.

TinyMCE AI was designed to eliminate the round-trip.

Users can rewrite, summarize, translate, and generate content directly inside the editor with document context and structure passed to the model automatically. But closing that gap introduces a new set of architectural challenges beyond the UI, including model selection, prompt orchestration, authorization, tenant-specific policy enforcement and provider abstraction.

Let’s examine TinyMCE’s approach to those questions in the architecture behind TinyMCE AI, focusing on:

  1. Model routing
  2. Prompt customization
  3. JWT-based role gating

High-level architecture

TinyMCE AI follows a gateway-based architecture. The editor does not communicate directly with OpenAI, Anthropic, Gemini, or any other provider. Instead, requests pass through TinyMCE’s AI service responsible for routing, authorization, and prompt orchestration.

A typical request flow looks like this:

User Action in Editor
   ↓
TinyMCE AI plugin
   ↓
Transport Layer
   ↓
HTTP Request + JWT
   ↓
AI Service
   ↓
Selected Model Provider
   ↓
Streaming Response (SSE)
   ↓
Editor Update

The separation between editor concerns and AI infrastructure concerns is intentional. The editor runtime is responsible for:

  • Selection state
  • UI management
  • Streamed content insertion
  • Undo and redo integration
  • Content safety

The TinyMCE AI service is responsible for capabilities such as:

  • Authentication and authorization
  • Prompt orchestration
  • Model routing
  • Provider abstraction
  • Telemetry and rate limiting

This boundary keeps editor integrations stable even as models, prompts, and providers evolve.

Inside the TinyMCE AI plugin

The TinyMCE AI plugin acts as the orchestration layer inside the editor runtime. Its responsibilities include:

  • Collecting editor context
  • Building normalized requests
  • Managing async request state
  • Streaming responses back into the document

A typical interaction begins when a user selects text and triggers an AI action from the editor UI. Internally, the plugin dispatches an editor command:

editor.execCommand("TinyMCEAIQuickActionImproveWriting");

The plugin gathers:

  • The current selection
  • Document context
  • The requested operation
  • Optional arguments such as target language

It then constructs a normalized payload:

const payload = {
  content: [{ type: "text", content: editor.selection.getContent() }],
};

The plugin intentionally avoids embedding provider-specific logic. There is no OpenAI-specific request formatting, Anthropic token handling, or provider-specific retry logic inside the editor runtime. This keeps client-side requests simple and provider-agnostic. This abstraction matters because editor integrations may live for years, while model providers and routing strategies change constantly.

AI editing inside a rich text editor also introduces synchronization problems that do not exist in standalone chat interfaces. While suggestions stream in, the editor enters a readonly preview state to keep the document stable. Generated HTML still passes through the editor’s schema and normalization pipeline before insertion. If the user rejects the suggestion, the original editor state must be restored cleanly.

The plugin therefore treats AI responses more like editor transactions than simple text replacement operations.

System actions vs. custom actions

TinyMCE AI splits AI actions into two types: system actions and custom actions. It's one of the most important design decisions in the plugin, because that split determines:

  • Who selects the model
  • How permissions are enforced
  • How much flexibility developers have

System actions

System actions are predefined operations such as:

  • Grammar correction
  • Rewriting
  • Tone adjustment
  • Translation

When the user selects a system action, TinyMCE AI plugin dispatches a command:

editor.execCommand("TinyMCEAIQuickActionImproveWriting");

The plugin collects the relevant editor context, constructs a normalized request, and sends it to the TinyMCE AI service.

The AI service then:

  • Selects the prompt
  • Chooses the model
  • Applies tenant-specific restrictions
  • Validates permissions

The editor never needs to know which provider actually handled the request. Switching providers or underlying models does not require changes to the editor integration.

Custom actions

Custom actions are configured in the editor and are best suited to reusable, application-specific workflows.

Example:

tinymceai_quickactions_custom: [
  {
    type: "action",
    id: "summarize",
    title: "Summarize",
    prompt: "Summarize the following in 2-3 sentences",
    model: "gemini-2-5-flash",
  },
];

The plugin collects the user's selected content, adds the custom prompt and requested model, then sends everything to the TinyMCE AI service.

The TinyMCE AI service can still:

  • Reject unauthorized models
  • Override model selection
  • Apply compliance rules
  • Meter usage

The important tradeoff is that custom prompts live in frontend configuration, which means they ship in the client bundle and are inspectable by users. Frontend configuration works well for stable, reusable workflows and application-specific actions.

Model routing

TinyMCE AI routes system requests to models based on the task because different AI tasks have different operational requirements.

Task

Primary Aim

Grammar correction

Low latency

Long-form summarization

Large context window

Tone rewriting

Balanced quality and cost

Translation

Multilingual accuracy

Using a single model for every operation does not produce the best results. A lightweight rewrite operation should not incur the same latency and cost profile as large-document summarization. The AI service may consider factors such as task type, payload size, tenant configuration, permissions, latency targets, and provider availability when determining how to handle a request.

The editor is largely decoupled from model selection. Depending on the feature, the AI service may determine the final model used to handle the request.

That abstraction allows the TinyMCE AI service to:

  • Swap providers
  • Benchmark models
  • Implement failover
  • Optimize cost
  • Apply regional compliance policies

without changing frontend integrations.

Prompt customization

Prompt engineering becomes infrastructure as soon as AI moves into production. Hardcoding prompts directly into components quickly becomes difficult to maintain. TinyMCE AI separates prompts into layers:

System Prompt
   +
Task Prompt
   +
User Content
   +
Editor Context

System prompts define foundational behavior:

You are an editing assistant.
Preserve HTML structure.
Do not invent factual claims.

Task prompts describe the requested operation:

Rewrite the content in a professional tone.

Separating prompt layers makes it easier to:

  • Audit prompt changes
  • Evolve workflows over time
  • Maintain consistent behavior
  • Enforce compliance rules

One way to customize AI behaviour is through editor configuration, particularly for reusable custom actions. This works well for reusable workflows and application-specific actions, while the TinyMCE AI service continues to enforce routing, authorization, and policy constraints.

JWT-based role gating

AI features come with costs that traditional editor features don’t. Every AI request can consume tokens, incur provider costs, count towards rate limits and be subject to compliance or organizational policies.

Because of this, it isn’t enough to control access in the frontend. A determined user could simply bypass the UI and call the API directly. Instead, TinyMCE AI uses JWT-based authorization so the AI service can verify what each user is allowed to do before processing a request.

From the editor’s perspective, integration remains intentionally simple:

tinymceai_token_provider: () => fetch("/api/jwt-token").then((r) => r.json());

The plugin:

  • Caches the token
  • Refreshes it when needed
  • Attaches it to requests automatically

Your application backend is still responsible for generating and signing the JWT, but the plugin handles client-side concerns such as token refresh, expiration checks, and attaching the token to requests.A simplified payload might look like this:

{
  "sub": "user-123",
  "tenant": "acme-corp",
  "auth": {
    "ai": {
      "permissions": [
        "ai:model:gpt-4o",
        "ai:actions:system:*",
        "ai:actions:custom:*"
      ]
    }
  }
}

Those permissions determine:

  • Which models can be requested
  • Which actions are available
  • Which tenant policies apply

Importantly, the JWT is the enforcement boundary, not the UI. Applications may choose to hide unavailable actions for UX reasons, but permissions are always enforced server-side. That distinction matters in multi-tenant systems where different users may share the same editor configuration while operating under completely different AI policies.

Streaming and runtime performance

Traditional editor interactions are nearly instantaneous. AI requests are not. That makes perceived latency especially important inside the editor experience.

TinyMCE AI uses Server-Sent Events (SSE) for streaming responses. SSE were chosen over WebSockets because AI responses are primarily unidirectional streams, making SSE simpler to operate through standard HTTP infrastructure and reverse proxies.

The plugin also manages:

  • Cancellation
  • Loading states
  • Partial responses
  • Streamed HTML insertion
  • Undo and redo integration

Generated content still passes through the editor's schema and normalization pipeline before insertion.

That helps ensure AI-assisted edits behave like standard editor operations rather than bypassing existing document constraints.

Design tradeoffs

Every AI architecture involves tradeoffs.

TinyMCE AI prioritizes extensibility and operational control over direct provider coupling.

System actions provide:

  • Centrally managed prompts
  • AI service-controlled model selection
  • Consistent behavior across clients

Custom actions provide:

  • Dynamic prompts
  • Application-specific workflows
  • Faster experimentation

Similarly, smaller models improve responsiveness and cost efficiency, while larger models generally produce higher-quality output for complex tasks.

Routing exists to balance those tradeoffs dynamically rather than forcing a single model strategy for every operation.

Conclusion

TinyMCE AI starts with a simple goal: allow users to perform AI-assisted editing without leaving the document.

The harder problem is making that experience reliable once deployed into real applications.

Modern AI editor integrations need to handle:

  • Model evolution
  • Async streaming interactions
  • Tenant-specific policies
  • Authorization
  • Observability
  • Operational cost

TinyMCE AI approaches those concerns as infrastructure problems rather than isolated UI features.

The result is an architecture that separates:

  • Editor interaction
  • Routing
  • Prompt orchestration
  • Authorization
  • Provider execution

That separation allows teams to evolve models, prompts, and policies over time without rewriting editor integrations.

Models will continue to evolve quickly. Integration architecture tends to last much longer.

For AI-assisted editing systems, those architectural boundaries are what ultimately determine whether the integration remains maintainable, secure, and adaptable at scale.

If you’re interested in learning more and speaking to other developers working with TinyMCE, head over and join our Developer Community. Learn about new use cases, discuss implementation, get help from peers and Tiny experts, and connect with other developers working with TinyMCE.

TinyMCE AI
byKim Woodfield

Kim Woodfield is a Software Engineer at TinyMCE, where he develops features for the world's most trusted rich text editor. A full-stack engineer with a frontend focus, Kim works primarily with TypeScript, React, TinyMCE, Bun, and CI/CD, building developer-focused tools and editing experiences that are performant, maintainable, and intuitive.

Related Articles

  • Developer Insights

    The Recommended Migration Path from Another Rich Text Editor to TinyMCE

Join 100,000+ developers who get regular tips & updates from the Tiny team.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.