Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@udaykakade25
Copy link
Collaborator

Description

Adds the MCP Server for Calendly.
Tools: get_user_info, get_event_details, list_events, list_event_types, list_availability_schedules, and list_event_invitees.

Related issue

None

Type of change

  • New MCP feature (non-breaking change which adds functionality)

How has this been tested?

(Add screenshots or recordings here if applicable.)
Tested using Claude in VSCode Terminal and verified on Calendly Web.

Checklist

  • I have performed a self-review of my own code
  • My changes generate no new warnings

@udaykakade25
Copy link
Collaborator Author

Screenshots: https://drive.google.com/drive/folders/1wq_ujAoJT4LDobLP_B0NoGed1vBgYIdS?usp=sharing
(All Tools are working as expected)

@@ -0,0 +1,2 @@
CALENDLY_ACCESS_TOKEN=YOUR_CALENDLY_ACCESS_TOKEN_HERE
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@udaykakade25 Bro Where are you Using this???

@Mayank-MSJ-Singh
Copy link
Collaborator

Mayank-MSJ-Singh commented Aug 10, 2025

Screenshot From 2025-08-11 01-20-26

Logs -

Screenshot From 2025-08-11 01-26-31 Screenshot From 2025-08-11 01-26-36

my .env file -
image

@Mayank-MSJ-Singh
Copy link
Collaborator

Mayank-MSJ-Singh commented Aug 10, 2025

@udaykakade25 Bro, it might work when it gets the x-auth-token from the header, but for testing, it’s not really working. Also, your base.py looks a bit different from the others.
I’d suggest you check out Zihao’s code and follow that style. If all the code looks similar, it’ll be way easier for new people to get it and for us when we come back to it later.

Comment on lines +22 to +112
class CalendlyClient:
"""Client for Calendly API using Bearer Authentication."""

@staticmethod
async def make_request(
method: str,
endpoint: str,
json_data: Optional[Dict[str, Any]] = None,
params: Optional[Dict[str, Any]] = None,
expect_empty_response: bool = False
) -> Dict[str, Any]:
"""Make an HTTP request to Calendly API."""
access_token = get_auth_token()

if not access_token:
raise RuntimeError("No access token provided. Please set the x-auth-token header.")

headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}

url = f"{CALENDLY_API_BASE}{endpoint}"

async with httpx.AsyncClient() as client:
try:
if method.upper() == "GET":
response = await client.get(url, headers=headers, params=params)
elif method.upper() == "POST":
response = await client.post(url, headers=headers, json=json_data)
elif method.upper() == "PUT":
response = await client.put(url, headers=headers, json=json_data)
elif method.upper() == "PATCH":
response = await client.patch(url, headers=headers, json=json_data)
elif method.upper() == "DELETE":
response = await client.delete(url, headers=headers)
else:
raise ValueError(f"Unsupported HTTP method: {method}")

response.raise_for_status()

# Handle empty responses
if expect_empty_response or response.status_code == 204 or not response.content:
return {"success": True}

try:
json_response = response.json()
# Handle null/undefined responses
if json_response is None:
return {"data": None, "message": "API returned null response"}
return json_response
except ValueError as e:
# Handle cases where response content exists but isn't valid JSON
logger.error(f"Failed to parse JSON response: {e}")
logger.error(f"Response content: {response.content}")
return {"error": "Invalid JSON response", "content": response.text}

except httpx.HTTPStatusError as e:
logger.error(f"Calendly API request failed: {e.response.status_code} {e.response.reason_phrase} for {method} {url}")
error_details = e.response.reason_phrase
try:
error_body = e.response.json()
error_details = f"{e.response.reason_phrase} - {error_body}"
except Exception:
pass
raise RuntimeError(f"Calendly API Error ({e.response.status_code}): {error_details}") from e
except Exception as e:
logger.error(f"An unexpected error occurred during Calendly API request: {e}")
raise RuntimeError(f"Unexpected error during API call to {method} {url}") from e

async def make_calendly_request(
method: str,
endpoint: str,
json_data: Optional[Dict] = None,
params: Optional[Dict] = None,
expect_empty_response: bool = False
) -> Any:
"""
Makes an HTTP request to the Calendly API.

Args:
method: HTTP method (GET, POST, etc.)
endpoint: API endpoint (should start with /)
json_data: JSON payload for POST/PUT requests
params: Query parameters
expect_empty_response: Whether to expect an empty response (for some operations)

Returns:
Response data as dict, or None for empty responses
"""
return await CalendlyClient.make_request(method, endpoint, json_data, params, expect_empty_response) No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep the code simple and use httpx in a consistent, straightforward way across all tools. What do you think?

@zihaolin96 zihaolin96 merged commit ea511a8 into Klavis-AI:main Oct 14, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants