A REST Profile for the Model Context Protocol — Draft Proposal
Version: 0.1.0 | Status: Draft Proposal
Abstract
The Model Context Protocol (MCP) defines how AI models connect to external services. MCP currently supports two transports: stdio for local servers, and Streamable HTTP for remote servers using JSON-RPC over HTTP. This document proposes a third transport option: a REST profile that allows any service with an existing REST API to become MCP-compatible by publishing an OpenAPI specification at a well-known URL.
The REST profile does not replace the existing MCP transports. It is designed for the common case — remote services that authenticate with OAuth and expose request-response endpoints — where the full JSON-RPC transport is unnecessary overhead. Services that need bidirectional communication, server-initiated requests, or stateful sessions should continue to use the Streamable HTTP transport.
1. Motivation
MCP’s architecture is inherently modular. Capabilities are negotiated at initialization, and servers only implement what they need. But the transport layer currently requires every server to speak JSON-RPC, even when the server’s functionality maps directly to standard REST endpoints.
Hundreds of thousands of services already have REST APIs, OpenAPI specifications, and OAuth 2.0 support. For these services, the gap between “has an API” and “supports MCP” is a full JSON-RPC implementation, a new deployment, and a new codebase to maintain. A REST profile closes that gap: the same service becomes MCP-compatible by adding a single YAML file at a well-known URL.
This isn’t a theoretical problem. The MCP meme has spread far faster than MCP server implementations. Every AI platform supports MCP. Every developer knows the term. Yet the number of services that have actually shipped MCP servers remains small. A REST profile would unlock the long tail of services that will never build a dedicated JSON-RPC server but would happily expose their existing API.
2. Relationship to the MCP Specification
This profile maps MCP’s existing concepts onto REST and OpenAPI equivalents. The semantics are identical — only the wire format changes.
| MCP Concept | REST Profile Equivalent |
|---|---|
| Transport (JSON-RPC over HTTP) | Standard HTTP (REST calls) |
| tools/list discovery | OpenAPI spec at /.well-known/mcp.yaml |
| Tool name + inputSchema | operationId + OpenAPI parameter/request schemas |
| Tool result | HTTP response body |
| OAuth 2.0 + PKCE | Identical — same auth model |
| Dynamic Client Registration | Identical — same RFC 7591 support |
| Capability negotiation | Implicit in the OpenAPI document |
Features that require bidirectional communication are outside the scope of this profile:
- Sampling — Server-initiated LLM completion requests (requires server→client messages)
- Prompts — User-controlled prompt templates (requires a discovery protocol beyond static files)
- Resource subscriptions — Real-time change notifications (requires server push)
Services that need these features should use the Streamable HTTP transport. The REST profile covers the common case: AI clients discovering and invoking tools on remote services with user-scoped authentication.
3. Conformance
The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" in this document are to be interpreted as described in RFC 2119.
A service conforms to the MCP REST profile if it satisfies all requirements in Sections 4 through 7.
4. Discovery
4.1 Manifest Location
A conformant service MUST publish an OpenAPI 3.x specification at the following well-known URI:
GET /.well-known/mcp.yaml
The response MUST have a Content-Type of application/yaml or application/json (if the service prefers to publish as mcp.json).
This follows the same well-known URI pattern that MCP already uses for OAuth discovery (/.well-known/oauth-authorization-server).
4.2 Manifest Content
The manifest MUST be a valid OpenAPI 3.1.0 (or later) document.
The manifest MAY be the service’s complete OpenAPI specification, or it MAY be a curated subset containing only the endpoints intended for AI model consumption.
4.3 Metadata
The info object MUST include:
title— The human-readable name of the service.version— The version of the API.description— A plain-language description of the service and its capabilities. This description SHOULD be written with AI model consumers in mind.
The info object MAY include an x-mcp extension containing additional metadata:
info:
title: Notion
version: 1.0.0
description: Access and manage pages, databases, and content in Notion workspaces.
x-mcp:
logo: https://notion.so/logo.png
categories:
- productivity
- knowledge-management
5. Tool Definitions
5.1 Mapping to MCP Tools
In the standard MCP protocol, tools are defined as {name, description, inputSchema} objects and discovered via the tools/list JSON-RPC method. In the REST profile, tools map to OpenAPI path operations:
| MCP Tool Field | OpenAPI Equivalent |
|---|---|
| name | operationId |
| description | description field on the operation |
| inputSchema | Combined parameters + requestBody schema |
Each path operation in the manifest represents one MCP tool. AI clients read the manifest to build their tool list, exactly as they would call tools/list in the standard protocol.
5.2 Required Fields
Every tool endpoint MUST include:
operationId— A unique, short, descriptive identifier (e.g., search-tasks, create-page).summary— A one-line description of what the tool does.description— A detailed explanation of the tool’s behaviour, including when to use it, what it returns, and any important constraints.
5.3 Writing Descriptions for AI Consumers
This is the key difference between a standard OpenAPI spec and an MCP-compatible one. Tool descriptions are the primary mechanism by which an AI model decides whether and how to use a tool.
Descriptions SHOULD:
- State what the tool does in concrete terms.
- Specify what the tool returns.
- Clarify when to use this tool versus other available tools.
- Note any side effects (e.g., "This will send an email to the specified recipient.").
Descriptions SHOULD NOT:
- Reference UI elements or user-facing features the AI cannot interact with.
- Assume familiarity with the service’s internal concepts without explanation.
5.4 Parameter and Response Schemas
Request parameters and bodies MUST be described using JSON Schema as defined by OpenAPI 3.1.0. Each property SHOULD include a description field.
Response bodies SHOULD be described with JSON Schema. This allows AI models to understand the shape of returned data and use it in subsequent reasoning or tool calls.
6. Authentication
6.1 OAuth 2.0
The REST profile uses the same authentication model as MCP’s Streamable HTTP transport: OAuth 2.0 with PKCE.
A conformant service MUST support OAuth 2.0 Authorization Code flow with PKCE (Proof Key for Code Exchange). OAuth configuration MUST be declared in the securitySchemes section of the OpenAPI manifest:
components:
securitySchemes:
oauth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://api.example.com/oauth/authorize
tokenUrl: https://api.example.com/oauth/token
scopes:
read: Read access to user content
write: Create and modify content
A global security requirement MUST be declared at the top level of the manifest:
security:
- oauth2:
- read
6.2 User-Scoped Access
All API calls made by an AI model on behalf of a user MUST use that user’s OAuth access token. The service MUST enforce its existing permission model against the authenticated user. An AI model MUST NOT have access to any data or actions beyond what the authenticated user is authorised to access.
This is identical to MCP’s existing security principle that servers must not gain ambient authority beyond what the user explicitly grants.
6.3 Token Handling
AI host applications are responsible for initiating the OAuth flow, obtaining user consent, storing and refreshing access tokens, and including the access token in the Authorization header of all requests:
Authorization: Bearer {access_token}
6.4 Client Registration
Traditional OAuth assumes a developer manually registers their application with a service and obtains a client_id in advance. AI clients connecting to arbitrary services cannot do this — they may encounter a service for the first time at runtime. MCP already addresses this challenge.
A conformant service MUST support at least one of the following client registration mechanisms:
- Client Metadata Documents (preferred) — The AI platform publishes a stable document at a well-known URL (e.g., https://anthropic.com/.well-known/oauth-client.json) describing its client identity, redirect URIs, and capabilities. The service fetches this document and uses it as the client record.
- Dynamic Client Registration (RFC 7591) — The service’s authorization server accepts registration requests from unknown clients at runtime. This is already recommended by the MCP specification.
- Pre-registered client IDs (fallback) — The service publishes documentation where AI platform developers can manually register and obtain a client_id.
7. HTTP Conventions
7.1 Error Responses
Error responses MUST use appropriate HTTP status codes and SHOULD return a JSON body with a human-readable message field:
{
"error": "not_found",
"message": "No page found with the given ID. It may have been deleted or you may not have access."
}
The message field SHOULD be written in plain language suitable for interpretation by an AI model.
7.2 Pagination
Endpoints that return collections SHOULD support cursor-based pagination using the following convention:
- Request parameter:
cursor(string, optional) andlimit(integer, optional). - Response field:
next_cursor(string or null). A null value indicates no further results.
7.3 Rate Limiting
Services SHOULD return 429 Too Many Requests with a Retry-After header when rate limits are exceeded. AI host applications MUST respect the Retry-After value before retrying.
7.4 Streaming (Optional)
Endpoints that return long-running or incremental results MAY use Server-Sent Events (SSE). This is indicated by the response content type text/event-stream in the OpenAPI manifest. This aligns with MCP’s existing use of SSE in the Streamable HTTP transport.
Streaming is OPTIONAL. Most tool endpoints will use standard request-response.
8. Example Manifest
A complete manifest for a hypothetical task management service:
openapi: 3.1.0
info:
title: Acme Tasks
version: 2.0.0
description: |
Manage tasks and projects in Acme Tasks.
Supports creating, searching, updating, and completing tasks
within the authenticated user's workspace.
x-mcp:
logo: https://acmetasks.com/logo.png
categories:
- project-management
servers:
- url: https://api.acmetasks.com
paths:
/v1/tasks/search:
post:
operationId: search-tasks
summary: Search for tasks in the user's workspace.
description: |
Returns tasks matching the query string. Searches task titles,
descriptions, and comments. Results are ordered by relevance.
Only returns tasks visible to the authenticated user.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
query:
type: string
description: Free-text search query.
status:
type: string
enum: [open, in_progress, done]
description: Filter by task status. Omit to include all statuses.
limit:
type: integer
default: 20
description: Maximum number of results.
cursor:
type: string
description: Pagination cursor from a previous response.
required:
- query
responses:
'200':
description: A list of matching tasks.
content:
application/json:
schema:
type: object
properties:
results:
type: array
items:
$ref: '#/components/schemas/Task'
next_cursor:
type: string
nullable: true
/v1/tasks:
post:
operationId: create-task
summary: Create a new task.
description: |
Creates a task in the specified project. The task will be
assigned to the authenticated user by default unless an
assignee_id is provided.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
project_id:
type: string
description: The project to create the task in.
title:
type: string
description: The task title.
description:
type: string
description: Detailed task description. Supports Markdown.
assignee_id:
type: string
description: User ID to assign the task to. Defaults to the authenticated user.
due_date:
type: string
format: date
description: Due date in YYYY-MM-DD format.
required:
- project_id
- title
responses:
'201':
description: The created task.
/v1/tasks/{task_id}/complete:
post:
operationId: complete-task
summary: Mark a task as done.
description: |
Sets the task's status to done and records the completion
timestamp. This action cannot be undone via this endpoint;
use update-task to reopen a task if needed.
parameters:
- name: task_id
in: path
required: true
schema:
type: string
responses:
'200':
description: The completed task.
components:
schemas:
Task:
type: object
properties:
id: { type: string }
title: { type: string }
description: { type: string }
status:
type: string
enum: [open, in_progress, done]
assignee_id: { type: string }
project_id: { type: string }
due_date:
type: string
format: date
nullable: true
completed_at:
type: string
format: date-time
nullable: true
created_at:
type: string
format: date-time
securitySchemes:
oauth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://acmetasks.com/oauth/authorize
tokenUrl: https://acmetasks.com/oauth/token
scopes:
read: Read tasks and projects
write: Create and modify tasks
security:
- oauth2:
- read
- write
9. Adoption Path
If your service already has a REST API with an OpenAPI specification and OAuth 2.0 support, conforming to this profile requires minimal additional work:
| Requirement | You likely already have | What to add |
|---|---|---|
| REST API | Yes | Nothing |
| OpenAPI spec | Probably | Publish at /.well-known/mcp.yaml |
| OAuth 2.0 + PKCE | Probably | Add PKCE if not already supported |
| AI-optimised descriptions | No | Rewrite operationId, summary, and description fields for AI consumers |
That’s the gap. MCP compatibility goes from "build a new JSON-RPC server" to "add a well-known URL and improve your descriptions."
10. What This Profile Does Not Cover
The following MCP features require bidirectional communication and are outside the scope of this profile. Services that need them should use the Streamable HTTP transport:
- Sampling — Server-initiated LLM completion requests. The server asks the client’s LLM for help while processing a request. Requires server→client messaging.
- Prompts — User-controlled prompt templates that servers expose as slash commands. Requires a dynamic discovery protocol.
- Resource subscriptions — Clients subscribe to change notifications on specific resources. Requires server push.
- Server-initiated notifications — The server pushes updates to the client without being asked. Requires a persistent connection.
The REST profile is deliberately limited in scope. It covers the overwhelmingly common case — AI clients discovering and calling tools on remote services with user-scoped authentication — and defers everything else to MCP’s existing transports. This is a feature, not a limitation: the simplicity is what makes it possible for hundreds of thousands of existing REST APIs to participate in the MCP ecosystem without building anything new.
References
- Model Context Protocol Specification (2025-03-26)
- OpenAPI Specification 3.1.0
- RFC 6749 — The OAuth 2.0 Authorization Framework
- RFC 7636 — Proof Key for Code Exchange (PKCE)
- RFC 7591 — OAuth 2.0 Dynamic Client Registration Protocol
- RFC 2119 — Key Words for Use in RFCs
- Server-Sent Events — HTML Living Standard
- RFC 8615 — Well-Known URIs