deploy2 / echo_server.py
Abdelkarim Bengrine
fix: oauth
532ff49
from mcp.server.fastmcp import FastMCP
from fastmcp import Client
from fastmcp.client.auth import OAuth
import os
from typing import Optional, Dict, Any
mcp = FastMCP(name='EchoServer', stateless_http=True)
# Twitter OAuth configuration
TWITTER_CLIENT_ID = os.getenv('TWITTER_CLIENT_ID')
TWITTER_CLIENT_SECRET = os.getenv('TWITTER_CLIENT_SECRET')
TWITTER_REDIRECT_URI = os.getenv(
'TWITTER_REDIRECT_URI', 'http://localhost:8080/callback'
)
# Global Twitter client instance
twitter_client: Optional[Client] = None
async def get_twitter_client() -> Client:
"""Get authenticated Twitter client using OAuth"""
global twitter_client
if twitter_client is None:
# Configure OAuth for Twitter
oauth = OAuth(
mcp_url='https://api.twitter.com/2', # Twitter API v2 endpoint
scopes=['tweet.read', 'tweet.write', 'users.read'],
client_name='FastMCP Twitter Client',
additional_client_metadata={
'client_id': TWITTER_CLIENT_ID,
'client_secret': TWITTER_CLIENT_SECRET,
'redirect_uri': TWITTER_REDIRECT_URI
}
)
twitter_client = Client('https://api.twitter.com/2', auth=oauth)
await twitter_client.__aenter__()
return twitter_client
@mcp.tool(description='A simple echo tool')
def echo(message: str) -> str:
return f'Echo: {message}'
@mcp.tool(description='Authenticate with Twitter using OAuth 2.1')
async def authenticate_twitter() -> Dict[str, Any]:
"""Authenticate with Twitter and return authentication status"""
try:
client = await get_twitter_client()
# Test the connection by making a simple API call
response = await client.request('GET', '/users/me')
return {
'status': 'success',
'message': 'Successfully authenticated with Twitter',
'user_data': (
response.json() if hasattr(response, 'json') else str(response)
)
}
except Exception as e:
return {
'status': 'error',
'message': f'Failed to authenticate with Twitter: {str(e)}',
'error': str(e)
}
@mcp.tool(description='Post a tweet using Twitter API v2')
async def post_tweet(text: str) -> Dict[str, Any]:
"""Post a tweet to Twitter"""
try:
client = await get_twitter_client()
# Twitter API v2 endpoint for posting tweets
tweet_data = {
'text': text
}
response = await client.request('POST', '/tweets', json=tweet_data)
return {
'status': 'success',
'message': 'Tweet posted successfully',
'tweet_id': (
response.json().get('data', {}).get('id')
if hasattr(response, 'json') else None
),
'response': (
response.json() if hasattr(response, 'json') else str(response)
)
}
except Exception as e:
return {
'status': 'error',
'message': f'Failed to post tweet: {str(e)}',
'error': str(e)
}
@mcp.tool(description="Get user's Twitter profile information")
async def get_twitter_profile() -> Dict[str, Any]:
"""Get the authenticated user's Twitter profile"""
try:
client = await get_twitter_client()
# Get user profile information
response = await client.request(
'GET', '/users/me?user.fields=id,name,username,public_metrics'
)
return {
'status': 'success',
'message': 'Profile retrieved successfully',
'profile': (
response.json() if hasattr(response, 'json') else str(response)
)
}
except Exception as e:
return {
'status': 'error',
'message': f'Failed to get profile: {str(e)}',
'error': str(e)
}
@mcp.tool(description='Search for tweets using Twitter API v2')
async def search_tweets(query: str, max_results: int = 10) -> Dict[str, Any]:
"""Search for tweets on Twitter"""
try:
client = await get_twitter_client()
# Twitter API v2 search endpoint
params = {
'query': query,
'max_results': min(max_results, 100), # Twitter API limit
'tweet.fields': 'created_at,author_id,public_metrics'
}
response = await client.request(
'GET', '/tweets/search/recent', params=params
)
return {
'status': 'success',
'message': f'Found tweets for query: {query}',
'tweets': (
response.json() if hasattr(response, 'json') else str(response)
)
}
except Exception as e:
return {
'status': 'error',
'message': f'Failed to search tweets: {str(e)}',
'error': str(e)
}
# Example usage functions
async def example_twitter_oauth_usage():
"""Example of how to use Twitter OAuth with FastMCP"""
# Method 1: Using default OAuth settings
async with Client('https://api.twitter.com/2', auth='oauth') as client:
await client.ping()
# Method 2: Using OAuth helper with custom configuration
oauth = OAuth(
mcp_url='https://api.twitter.com/2',
scopes=['tweet.read', 'tweet.write', 'users.read'],
client_name='FastMCP Twitter Client'
)
async with Client('https://api.twitter.com/2', auth=oauth) as client:
await client.ping()