Systems such as ChatGPT Plugins and Gemini Extensions allows OpenAI and Gemini to connect to external apps and services to retrieve real-time information and perform actions, allowing them to interact directly with Google Workspace (Docs, Drive, Gmail), Google Maps, Google Flights, Google Hotels, and YouTube.
The general technology and industry trends behind systems like Gemini Extensions and ChatGPT Plugins fall under a few distinct terms, depending on whether we are describing the foundational mechanism, the software architecture, or the broader ecosystem.
- Function Calling and Tool Use: At the foundational level, this capability is widely referred to as Function Calling or Tool Use. Instead of relying purely on pre-trained weights, the AI is trained to recognize when it needs external help and generates structured data to execute standard Python functions or external APIs.
- Agentic Tooling and ReAct Architecture: When function calling is paired with autonomous decision-making, it is known as Agentic Tooling. This is heavily driven by architectures like ReAct (Reasoning and Acting). In this framework, the LLM acts as the brain generating internal reasoning traces, while the integrated tools serve as the external action space.
- Extensibility Ecosystems and MCP: At the platform level, these plugin networks are known as Extensibility Ecosystems. To prevent developers from having to write custom integrations for every AI model, the industry is standardizing around technologies like the Model Context Protocol (MCP), an open-source standard that provides a universal way for AI agents to connect securely to external data sources, local systems, and tools.
Augmented Language Models (ALMs)In academic and research contexts, large language models equipped with plugins, search engines, or graph database connections are broadly classified as Augmented Language Models (ALMs) or Tool-Augmented LLMs. This distinguishes them from standard models that are confined to their static training data.
What is an Extensibility Ecosystems Technically
The architectural term for ChatGPT Plugins is Tool Registries or MCP Hubs. At a technical level, these ecosystems serve as catalogs where an AI model dynamically queries and invokes external capabilities.
- Tool Registries: The underlying technical mechanism where third-party APIs, functions, or execution scopes are registered so an agent can pick the right “tool” for a given user intent.
- MCP Servers / Hubs: With the widespread adoption of open connection standards like Anthropic’s Model Context Protocol (MCP), these ecosystems are often referred to as MCP Hubs or MCP Registries. They allow an app or agent to dynamically discover external tool definitions and execute them on demand.
How Standard Protocols like MCP Govern Extensibility Ecosystems?
Standardized open protocols like the Model Context Protocol (MCP) solve a fundamental architectural challenge in agentic AI: how an AI agent safely discovers, understands, and executes third-party tools at runtime without hardcoding integrations or rebuilding prompt templates for every external capability.
Before open protocols, every AI app built a proprietary plugin architecture. MCP decouples the host client (the AI app or IDE) from the external tools, acting as a universal language for tool discovery and execution.
The Dynamic Discovery Workflow
When an agentic system connects to an MCP-based server, dynamic tool discovery operates through a standard client-server request-response lifecycle:

- Discovery & Handshake (
tools/list): Upon startup or user selection, the AI client sends a standardized RPC request (such astools/list) to the connected MCP server or gateway. The server returns a structured array of all available capabilities, complete with exact parameter requirements and JSON schemas. - In-Context Prompt Synthesis: The AI agent converts these JSON schemas into system-level instruction definitions. Because the protocol uses standardized formats (like JSON Schema for arguments), the model knows precisely what inputs are required (e.g., string format, required parameters, default values) without developer intervention.
- Intent Matching & Planning: When a user submits a prompt (e.g., “Export this table to Google Sheets”), the model analyzes the dynamic tool definitions currently loaded in its context window. If a registered tool matches the intent, the model generates a structured JSON payload containing the arguments.
- Invocation & Output Binding (
tools/call): The client receives the model’s structural tool call and sends atools/callRPC message to the target MCP server with the generated arguments. The MCP server executes the underlying code/API call and returns a standardized result payload back to the agent context.
| Architectural Layer | Role in Dynamic Tool Discovery |
|---|---|
| JSON-RPC Transport Layer | Standardized messaging format over standard channels (stdio, SSE, HTTP/WebSockets), allowing local or remote servers to plug into any agent without native code compilation. |
| Semantic Self-Description | Tools provide human-readable descriptions alongside rigid input schemas. The LLM uses these descriptions to decide when and why to invoke a specific tool. |
| Stateless Scope Boundaries | Servers expose atomic primitives - Tools (executable actions), Resources (readable data streams), and Prompts (reusable templates) - allowing servers to enforce fine-grained user permissions. |
MCP Market is NOT “MCP Server/Hub”Although matching syntatically, MCP Market and MCP Server/Hub represent two different layers of the ecosystem:
- MCP Market is a Public Community Directory/Registry. It serves as a human-facing web catalog (like npm, PyPI, or an app store listing) where developers publish, browse, and discover open-source MCP server implementations, installation guides, and documentation. It does not sit inside our active application request lifecycle or execute code for our AI agent.
- MCP Server/Hub is an Active Runtime Gateway / Backend Server. It is the live infrastructure endpoint (such as our backend Node.js server or a hosted container) that directly accepts streamable HTTP/SSE requests, executes the underlying tool logic, handles token authorization, and communicates back and forth with the LLM at runtime via JSON-RPC protocol messages.
Fundamental Components of Enterprise-Grade MCP Server or Hub
From a first-principles engineering perspective, an enterprise-grade MCP Server or Hub breaks down into 5 essential foundational components:
1 - Unified Transport & Protocol Engine (Data Plane)
This component handles low-level network connectivity, protocol parsing, and response framing:
- JSON-RPC Dispatcher: Deserializes incoming
tools/listandtools/callRPC payloads and routes them to the correct execution handler. - Streamable Network Adapters: Exposes stateful, bidirectional streaming transports—such as Server-Sent Events (SSE), WebSockets, or Streamable HTTP - over TLS to support continuous agent execution loops.
2 - Semantic Discovery & Context Trimming Engine
Exposing hundreds of tool schemas at once exhausts the LLM’s context window and skyrockets token costs.
- Vector Tool Index: Stores embeddings of tool descriptions and parameter schemas.
- Dynamic Search & Filtering: When an agent queries the hub, this engine performs semantic similarity matching over
the prompt to retrieve and expose only the top relevant tool schemas during the
tools/listhandshake.
The embeddings are generated from tool metadata documents during an automated indexing pipeline, and the vector search is performed against a centralized Vector Database (Registry).

3 - Protocol Adapter & Translation Layer
When building an AI MCP server with hundreds of tools, we face a major issue: our AI agent speaks only MCP (Model Context Protocol / JSON-RPC), but the real-world software services we want to trigger (like Spotify, Salesforce, or Google Calendar) do not speak MCP—they speak standard REST, GraphQL, or gRPC.
Instead of writing custom backend code (like spotify.ts or salesforce.ts) to bridge every single service by hand,
the Protocol Adapter automates this process.

4 - Identity, Authorization & Token Exchange (Control Plane)
AI agents must execute actions using the specific end-user’s permissions rather than over-privileged system credentials.
- Identity Context Propagation: Intercepts incoming
tools/callrequests and extracts the user’s bearer token (OAuth2/OIDC). - Token Vault Integration: Injects user-specific OAuth refresh/access tokens into downstream requests to ensure zero-trust, role-based access control (RBAC)
5 - Governance, Safety & Telemetry.
In an autonomous environment, this layer prevents malicious agent behavior and system abuse.
- Prompt Injection & Tool Poisoning Guardrails: Inspects incoming inputs and returning execution results for adversarial payload patterns before returning them to the LLM.
- Rate Limits & Circuit Breakers: Enforces strict execution budget caps, execution timeouts, and rate limits to stop runaway recursive agent loops.
- Audit Logging: Centralizes telemetry, tracking token usage, latency, user context, and exact input/output payloads.
General Extensibility Ecosystem Architecture
A standard MCP Server/Hub backed system is ChatGPT Plugins (or ChatGPT Apps):

Authorization - Clicking ”+” (Connect) on iOS
To execute commands on a user’s behalf - like creating calendar events or controlling music - our backend needs their authorized access token.
Authentication Flow (OAuth 2.0 with PKCE) for Single Integration (Google Calendar)

1 - iOS Onboarding
When the user installs the Google Calendar integration in our iOS app:
-
The iOS app triggers a standard OAuth 2.0 PKCE flow (e.g., using
ASWebAuthenticationSessionor Google’s Swift SDK).What is “PKCE”?PKCE (pronounced “pixie”) stands for Proof Key for Code Exchange.
It is an extension to the standard OAuth 2.0 Authorization Code flow designed to prevent authorization code interception attacks. PKCE was originally created for native mobile apps (such as iOS and Android applications) and single-page apps (SPAs) because these client types cannot securely store secret keys.
How PKCE Works
Instead of relying on a static client secret embedded inside a mobile app (which attackers could decompile and steal), PKCE dynamically creates a temporary secret key for every single login request:
- Code Verifier & Challenge Generation: The iOS app creates a high-entropy cryptographically random string called
the
code_verifier. It then creates a hashed version of this string called the code_challenge. - Authorization Request: The app opens an authentication session (such as Google Login) and sends the
code_challengealong with the authorization request. - Authorization Code Received: Once the user logs in and grants permissions, the auth server redirects back to
the app with a temporary
authorization_code. - Token Exchange: The app sends both the
authorization_codeand the original plain-textcode_verifierto our backend or authorization server. - Verification: The server hashes the
code_verifierusing the same algorithm and verifies that it matches the originalcode_challenge. If they match, access and refresh tokens are safely issued.
Why PKCE is Essential here:
- Secure Mobile OAuth: In case of mobile frontend, embedding a static
CLIENT_SECRETinside the Swift binary (iOS for example) is unsafe. PKCE allows the app to securely authenticate users without hardcoding secrets. - Mitigates Malicious Interception: On mobile devices, custom URI schemes or deep links can sometimes be
intercepted by other malicious apps installed on the same device. Even if an attacker steals the
authorization_code, they cannot exchange it for tokens without knowing the secretcode_verifiergenerated inside the app’s memory.
- Code Verifier & Challenge Generation: The iOS app creates a high-entropy cryptographically random string called
the
-
The user logs into Google and grants calendar permissions (
https://www.googleapis.com/auth/calendar). -
The iOS app receives the authorization code/tokens and sends them to backend.
2 - Secure Token Storage in Backend
Backend database securely stores the Refresh Token associated with a user:
- Access tokens expire quickly (typically in 1 hour), but refresh tokens allow our backend to generate valid access tokens silently whenever the user uses a voice command.
- Always encrypt refresh tokens at rest in our database (e.g., using AES-256).
3 - Forwarding Tokens to Third-Party MCP Servers
When a voice command comes in from the hardware, Node.js fetches the user’s fresh OAuth Access Token from your database and passes it down to the MCP server sub-process dynamically.
Here is how we update our mcpClientManager.ts to pass the user’s token per request:
// Updating tool execution to pass user credentials dynamicallyasync fetchToolSchemas(): Promise<MCPToolSchema[]> { const response = await this.client.listTools();
return response.tools.map((tool) => ({ name: tool.name, description: tool.description || "", inputSchema: tool.inputSchema as any, execute: async (args: any, userContext: { userId: string; userToken?: string }) => {
// Inject user's specific OAuth Access Token into the MCP call const result = await this.client.callTool({ name: tool.name, arguments: args, // Pass credentials in metadata/headers if supported by the MCP server, // or ensure the sub-process environment handles multi-tenant auth _meta: { authToken: userContext.userToken } }); return result; } }));}Authentication Flow (OAuth 2.0 with PKCE) for Multiple Integrations
To handle different authorization mechanisms gracefully across third-party MCP tools, we need an Adapter Pattern for Authentication Strategy in our backend.
Every service (Google Calendar, Spotify, Notion, YouTube Music) uses a different credential type:
- OAuth 2.0 PKCE (Google Calendar, Spotify) Requires
refresh_tokenandaccess_tokenrotation. - API Key / Secret (OpenWeather, Notion) Requires a static user-provided string.
- Cookie / Session Token (YouTube Music) Requires raw auth cookies.
Instead of writing custom backend auth logic for each integration, the system can choose to model authentication uniformly across frontend, Database, and MCP Server Wrappers.
1 - Unified Token Data Model in Backend DB
Our backend stores user integrations in a flexible JSON format tied to user ID:
export interface UserIntegration { id: string; userId: string; provider: string; // "google-calendar", "youtube-music", "notion" authType: "oauth2" | "api_key" | "session_cookie";
// Encrypted JSON string holding whatever credentials that provider needs encryptedCredentials: { accessToken?: string; refreshToken?: string; apiKey?: string; expiresAt?: number; rawHeader?: string; };}2 - Provider Auth Strategies
Create a uniform AuthStrategy interface. When a voice command arrives, the backend
- resolves the correct strategy,
- refreshes tokens if necessary, and
- formats the output into headers or parameters that the specific MCP server expects:
export interface AuthStrategy { // Returns clean credentials ready for the MCP server process getValidCredentials(userId: string): Promise<Record<string, string>>;}
// auth/GoogleOAuthStrategy.tsexport class GoogleOAuthStrategy implements AuthStrategy { async getValidCredentials(userId: string): Promise<Record<string, string>> { const integration = await db.findIntegration(userId, "google-calendar");
// Check if access_token is expired; refresh if necessary if (Date.now() >= integration.encryptedCredentials.expiresAt) { const newTokens = await refreshGoogleToken(integration.encryptedCredentials.refreshToken); await db.updateIntegration(integration.id, newTokens); return { authorization: `Bearer ${newTokens.accessToken}` }; }
return { authorization: `Bearer ${integration.encryptedCredentials.accessToken}` }; }}
// auth/ApiKeyStrategy.tsexport class ApiKeyStrategy implements AuthStrategy { async getValidCredentials(userId: string): Promise<Record<string, string>> { const integration = await db.findIntegration(userId, "notion"); return { "x-api-key": integration.encryptedCredentials.apiKey! }; }}3 - Dynamic Injection into MCP Server Sub-processes
Different open-source MCP servers expect auth in different places. The three standard ways third-party MCP servers accept credentials are:
- HTTP Authorization Headers (Standard Remote/SSE MCP)
- Standard Environment Variables (Stdio Sub-processes)
- Execution Meta/Arguments (
tools/callJSON-RPC parameters)
We can map auth credentials dynamically into mcpClientManager:
export class ExternalMCPServerWrapper { private config: MCPServerConfig; private authStrategy: AuthStrategy;
constructor(config: MCPServerConfig, authStrategy: AuthStrategy) { this.config = config; this.authStrategy = authStrategy; }
async executeTool(toolName: string, args: any, userId: string) { // 1. Fetch valid user credentials dynamically (refreshes OAuth if expired) const authHeaders = await this.authStrategy.getValidCredentials(userId);
// 2. Dispatch via stdio/SSE using the formatted credentials return await this.client.callTool({ name: toolName, arguments: { ...args, // Option A: Pass credentials inside _meta if using dynamic runtime auth _meta: { authHeaders } } }); }}4 - iOS App Dynamic Onboarding Flow

If authType === "oauth2": iOS launchesASWebAuthenticationSessionwithauthUrl, catches the OAuth code redirect, and sendsPOST /v1/mcp/google-calendar/callbackto Node.js.If authType === "api_key": iOS displays a simple text input UI (“Enter your Notion API Key”) and sends the string directly to Node.js for encrypted storage.
Why This Design Scales
- Backend handles multi-tenancy & token lifecycle: Users never get token-expiration errors because the backend auto-refreshes tokens before delegating calls to MCP sub-processes.
- Zero code changes to LLM / Prompt logic: The LLM context generator only cares about tool schemas (
name,description,inputSchema). Authentication stays completely hidden behind theAuthStrategylayer.