twitter_refresh_token
Refresh Twitter OAuth2 access tokens using a refresh token and client credentials to maintain API access for Twitter operations without local credential setup.
Instructions
Refresh the access token using the refresh token and client credentials
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| twitter_access_token | No | Twitter OAuth2 access token (optional if expired) | |
| twitter_client_id | Yes | Twitter OAuth2 client ID for token refresh | |
| twitter_client_secret | No | Twitter OAuth2 client secret (required only for confidential clients) | |
| twitter_refresh_token | Yes | Twitter OAuth2 refresh token |
Implementation Reference
- Handler logic in the @server.call_tool() function that processes the twitter_refresh_token tool call, extracts arguments, initializes TwitterClient, and invokes the refresh_token method.
if name == "twitter_refresh_token": # For refresh token, we need refresh token, client ID and secret refresh_token = arguments.get("twitter_refresh_token") client_id = arguments.get("twitter_client_id") client_secret = arguments.get("twitter_client_secret") # Optional for public clients access_token = arguments.get("twitter_access_token") # Optional for refresh if not refresh_token: raise ValueError("twitter_refresh_token is required for token refresh") if not client_id: raise ValueError("twitter_client_id is required for token refresh") # Initialize Twitter client for token refresh twitter = TwitterClient( access_token=access_token, refresh_token=refresh_token, client_id=client_id, client_secret=client_secret ) # Call the refresh_token method results = twitter.refresh_token(client_id=client_id, client_secret=client_secret) return [types.TextContent(type="text", text=results)] - Input schema definition for the twitter_refresh_token tool, specifying properties and required fields.
inputSchema={ "type": "object", "properties": { "twitter_access_token": {"type": "string", "description": "Twitter OAuth2 access token (optional if expired)"}, "twitter_refresh_token": {"type": "string", "description": "Twitter OAuth2 refresh token"}, "twitter_client_id": {"type": "string", "description": "Twitter OAuth2 client ID for token refresh"}, "twitter_client_secret": {"type": "string", "description": "Twitter OAuth2 client secret (required only for confidential clients)"} }, "required": ["twitter_refresh_token", "twitter_client_id"] }, - src/mcp_server_twitter_noauth/server.py:520-533 (registration)Registration of the twitter_refresh_token tool in the @server.list_tools() handler, including name, description, and schema.
types.Tool( name="twitter_refresh_token", description="Refresh the access token using the refresh token and client credentials", inputSchema={ "type": "object", "properties": { "twitter_access_token": {"type": "string", "description": "Twitter OAuth2 access token (optional if expired)"}, "twitter_refresh_token": {"type": "string", "description": "Twitter OAuth2 refresh token"}, "twitter_client_id": {"type": "string", "description": "Twitter OAuth2 client ID for token refresh"}, "twitter_client_secret": {"type": "string", "description": "Twitter OAuth2 client secret (required only for confidential clients)"} }, "required": ["twitter_refresh_token", "twitter_client_id"] }, ), - Core implementation of token refresh logic in TwitterClient class, performing the OAuth2 refresh token request to Twitter API.
def refresh_token(self, client_id: str, client_secret: str = None) -> str: """Refresh the access token using the refresh token Args: client_id: Twitter OAuth2 client ID client_secret: Twitter OAuth2 client secret (only required for confidential clients) """ if not self._refresh_token: # Changed to use the renamed attribute return json.dumps({ "error": "No refresh token provided", "status": "error" }) try: # Set up the request to refresh the token url = self.oauth_url headers = { "Content-Type": "application/x-www-form-urlencoded" } # For confidential clients, add Authorization header if client_id and client_secret: # Create basic auth header for confidential clients auth_string = f"{client_id}:{client_secret}" encoded_auth = base64.b64encode(auth_string.encode()).decode() headers["Authorization"] = f"Basic {encoded_auth}" # Prepare request data based on Twitter's OAuth2 implementation data = { "grant_type": "refresh_token", "refresh_token": self._refresh_token, # Changed to use the renamed attribute } # Client ID is required in the body for public clients if not client_secret: data["client_id"] = client_id response = requests.post(url, headers=headers, data=data) response.raise_for_status() token_data = response.json() logger.debug(f"Token refresh response: {token_data}") # Update access token for API calls self.access_token = token_data.get("access_token") # Update refresh token if a new one is provided new_refresh_token = token_data.get("refresh_token") if new_refresh_token: self._refresh_token = new_refresh_token # Changed to use the renamed attribute # Calculate expiration time if provided expires_in = token_data.get("expires_in") expires_at = None if expires_in: expires_at = datetime.now() + timedelta(seconds=expires_in) # Return the new access token and its expiration return json.dumps({ "access_token": self.access_token, "expires_at": expires_at.isoformat() if expires_at else None, "expires_in": expires_in, "refresh_token": token_data.get("refresh_token", self._refresh_token), # Changed to use the renamed attribute "scope": token_data.get("scope", ""), "status": "success" }) except requests.exceptions.RequestException as e: logger.error(f"Token refresh error: {str(e)}") return json.dumps({ "error": "Token refresh failed. Please provide valid client ID and client secret.", "details": str(e), "status": "error" }) except Exception as e: logger.error(f"Exception: {str(e)}") return json.dumps({ "error": str(e), "status": "error" })