Overview
ChatGPT can connect to your MCP servers to access custom tools and capabilities. This integration allows ChatGPT to leverage your MCP tools during conversations, extending its functionality beyond built-in capabilities.
MCP server integration with ChatGPT requires a deployed server accessible via HTTPS. You cannot use localhost URLs.
Prerequisites
Deployed MCP Server
Your MCP server must be deployed and accessible via HTTPS:
Manufact Cloud : Automatic HTTPS deployment
Self-hosted : Requires SSL certificate (Let’s Encrypt recommended)
Custom domain : Optional but recommended
ChatGPT Plus or Enterprise
MCP integration requires:
ChatGPT Plus subscription, or
ChatGPT Enterprise account, or
ChatGPT Team account
Server URL
Know your MCP server endpoint URL: https://your-server.run.mcp-use.com/mcp
Connection Methods
Method 1: ChatGPT Custom Actions (Recommended)
Custom Actions allow you to create reusable connections to your MCP server that can be used across multiple ChatGPT sessions.
Get MCP Server Metadata
First, retrieve your server’s tool definitions: curl https://your-server.run.mcp-use.com/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 1
}'
This returns your server’s available tools and their schemas.
Create Custom GPT
Go to ChatGPT
Click your profile icon → My GPTs
Click Create a GPT
In the Configure tab, click Create new action
Configure Action Schema
Create an OpenAPI schema for your MCP tools: openapi : 3.0.0
info :
title : My MCP Server
version : 1.0.0
description : Custom tools from my MCP server
servers :
- url : https://your-server.run.mcp-use.com
paths :
/mcp :
post :
operationId : callMCPTool
summary : Call an MCP tool
requestBody :
required : true
content :
application/json :
schema :
type : object
properties :
jsonrpc :
type : string
default : "2.0"
method :
type : string
enum : [ tools/call ]
params :
type : object
properties :
name :
type : string
description : Tool name to call
arguments :
type : object
description : Tool arguments
id :
type : integer
responses :
'200' :
description : Tool result
Test and Save
Test the action in ChatGPT’s action editor
Save your Custom GPT
Start using your MCP tools in conversations
ChatGPT can call HTTP endpoints directly using its function calling capabilities:
Describe Your Tools
In your ChatGPT conversation, describe your MCP server’s capabilities: I have an MCP server at https://your-server.run.mcp-use.com/mcp
that provides the following tools:
1. get_weather: Gets weather for a location
- Input: { "city": "string" }
2. search_web: Searches the web
- Input: { "query": "string" }
Please use these tools when relevant.
ChatGPT Makes Requests
ChatGPT will format and send MCP-compatible requests: {
"jsonrpc" : "2.0" ,
"method" : "tools/call" ,
"params" : {
"name" : "get_weather" ,
"arguments" : {
"city" : "Tokyo"
}
},
"id" : 1
}
Server Configuration
CORS Configuration
Ensure your MCP server allows requests from ChatGPT:
import { MCPServer } from "mcp-use/server" ;
const server = new MCPServer ({
name: "my-server" ,
version: "1.0.0" ,
cors: {
origin: [
"https://chat.openai.com" ,
"https://chatgpt.com"
],
credentials: true
}
});
Authentication
API Key Authentication
OAuth 2.0
No Authentication
Implement API key validation: import { MCPServer } from "mcp-use/server" ;
const server = new MCPServer ({
name: "my-server" ,
version: "1.0.0" ,
middleware: [
( req , res , next ) => {
const apiKey = req . headers [ "x-api-key" ];
if ( apiKey !== process . env . EXPECTED_API_KEY ) {
return res . status ( 401 ). json ({ error: "Unauthorized" });
}
next ();
}
]
});
In ChatGPT Custom Action, add header: components :
securitySchemes :
ApiKeyAuth :
type : apiKey
in : header
name : X-API-Key
security :
- ApiKeyAuth : []
Use OAuth for user-specific access: import { MCPServer } from "mcp-use/server" ;
const server = new MCPServer ({
name: "my-server" ,
version: "1.0.0" ,
oauth: {
provider: "auth0" ,
clientId: process . env . AUTH0_CLIENT_ID ,
domain: process . env . AUTH0_DOMAIN
}
});
In ChatGPT, configure OAuth: components :
securitySchemes :
OAuth2 :
type : oauth2
flows :
authorizationCode :
authorizationUrl : https://your-domain.auth0.com/authorize
tokenUrl : https://your-domain.auth0.com/oauth/token
scopes :
read : Read access
write : Write access
For public tools (not recommended for production): const server = new MCPServer ({
name: "public-server" ,
version: "1.0.0" ,
// No auth configuration
});
Example Integration
Create MCP Server
import { MCPServer , text } from "mcp-use/server" ;
import { z } from "zod" ;
const server = new MCPServer ({
name: "weather-server" ,
version: "1.0.0"
});
server . tool ({
name: "get_weather" ,
description: "Get current weather for a city" ,
schema: z . object ({
city: z . string (). describe ( "City name" ),
units: z . enum ([ "celsius" , "fahrenheit" ]). optional ()
})
}, async ({ city , units = "celsius" }) => {
const weather = await fetchWeather ( city , units );
return text ( `Weather in ${ city } : ${ weather . temp } °, ${ weather . conditions } ` );
});
await server . listen ( 3000 );
Deploy Server
# Deploy to Manufact Cloud
npx mcp-use deploy
# Note the deployment URL
# Example: https://weather-abc123.run.mcp-use.com/mcp
Create Custom GPT
Configure action in ChatGPT: openapi : 3.0.0
info :
title : Weather Server
version : 1.0.0
servers :
- url : https://weather-abc123.run.mcp-use.com
paths :
/mcp :
post :
operationId : getWeather
summary : Get weather for a city
requestBody :
content :
application/json :
schema :
type : object
properties :
jsonrpc :
type : string
default : "2.0"
method :
type : string
enum : [ tools/call ]
params :
type : object
properties :
name :
type : string
enum : [ get_weather ]
arguments :
type : object
properties :
city :
type : string
units :
type : string
enum : [ celsius , fahrenheit ]
Test in ChatGPT
Start a conversation: User: What's the weather in Tokyo?
ChatGPT: [Calls your MCP tool]
Let me check the weather in Tokyo for you.
[Displays weather information from your server]
Advanced Features
Streaming Responses
Enable streaming for long-running operations:
import { MCPServer , streamText } from "mcp-use/server" ;
server . tool ({
name: "generate_report" ,
description: "Generate a detailed report" ,
schema: z . object ({ topic: z . string () })
}, async function* ({ topic }) {
yield * streamText ( `Generating report on ${ topic } ... \n\n ` );
for ( const section of generateSections ( topic )) {
yield * streamText ( section + " \n " );
await delay ( 100 );
}
});
Error Handling
Provide helpful error messages:
server . tool ({
name: "search_database" ,
description: "Search internal database" ,
schema: z . object ({ query: z . string () })
}, async ({ query }) => {
try {
const results = await database . search ( query );
return text ( `Found ${ results . length } results` );
} catch ( error ) {
if ( error . code === "RATE_LIMIT" ) {
return text ( "Rate limit exceeded. Please try again in a few minutes." );
}
throw error ; // Let MCP handle other errors
}
});
Tool Context
Provide context-aware responses:
server . tool ({
name: "get_user_info" ,
description: "Get information about the current user" ,
schema: z . object ({})
}, async ({}, context ) => {
// Access user information from context
const userId = context . headers [ "x-user-id" ];
const userInfo = await fetchUserInfo ( userId );
return text ( `User: ${ userInfo . name } , Email: ${ userInfo . email } ` );
});
Testing Your Integration
Test with Inspector
# Open inspector
open https://inspector.mcp-use.com/inspector?autoConnect=https://your-server.run.mcp-use.com/mcp
Test tools manually before integrating with ChatGPT.
Test with cURL
# List tools
curl -X POST https://your-server.run.mcp-use.com/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 1
}'
# Call tool
curl -X POST https://your-server.run.mcp-use.com/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {"city": "Tokyo"}
},
"id": 2
}'
Troubleshooting
Problem : ChatGPT cannot access your server due to CORSSolution :const server = new MCPServer ({
cors: {
origin: [
"https://chat.openai.com" ,
"https://chatgpt.com"
],
methods: [ "GET" , "POST" , "OPTIONS" ],
credentials: true
}
});
Problem : API key or OAuth not workingSolution :
Verify API key is correctly set in ChatGPT action headers
Check server logs for authentication errors
Test authentication with cURL first
Ensure OAuth callback URL is whitelisted
Problem : Requests timeoutSolution :
Optimize slow operations
Implement streaming for long tasks
Increase server timeout settings
Check network connectivity
Best Practices
Use descriptive tool names that clearly indicate their purpose
Provide detailed descriptions in tool schemas to help ChatGPT understand when to use them
Implement proper authentication for production deployments
Handle errors gracefully with helpful error messages
Test thoroughly before deploying to production
Monitor usage with logging and analytics
Set rate limits to prevent abuse
Use HTTPS for all production deployments
Rate Limiting
Implement rate limiting to control usage:
import rateLimit from "express-rate-limit" ;
const limiter = rateLimit ({
windowMs: 15 * 60 * 1000 , // 15 minutes
max: 100 , // Limit each IP to 100 requests per windowMs
message: "Too many requests, please try again later."
});
const server = new MCPServer ({
name: "rate-limited-server" ,
middleware: [ limiter ]
});
Usage Analytics
Track tool usage:
server . tool ({
name: "track_usage" ,
description: "Internal tracking tool"
}, async ( args , context ) => {
// Log usage to analytics
await analytics . track ({
event: "tool_called" ,
toolName: context . tool . name ,
userId: context . userId ,
timestamp: new Date ()
});
// Continue with tool logic
});
Next Steps
Integrate with Claude Connect to Claude Desktop
Custom Clients Build custom MCP clients
Authentication Secure your integration
Monitoring Track usage and performance