#!/usr/bin/env python3
"""
Interactive MCP Test Client for Clockify MCP Server
Tests the MCP server by communicating via the stdio protocol
"""
import asyncio
import json
import os
import sys
from mcp import ClientSession
from mcp.client.stdio import stdio_client, StdioServerParameters
async def test_mcp_server():
"""Test the Clockify MCP server interactively"""
print("=" * 60)
print("Clockify MCP Server Interactive Test")
print("=" * 60)
# Server parameters - run the clockify MCP server
# Explicitly pass through environment variables
env = os.environ.copy()
server_params = StdioServerParameters(
command="python",
args=["-m", "clockify_mcp.server"],
env=env, # Explicitly pass environment
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
# Initialize the session
print("\n1. Initializing MCP session...")
await session.initialize()
print(" Session initialized successfully!")
# List available tools
print("\n2. Listing available tools...")
tools_result = await session.list_tools()
print(f" Found {len(tools_result.tools)} tools:")
for tool in tools_result.tools:
print(f" - {tool.name}: {tool.description[:60]}...")
# Test: Find user time entries for current user
print("\n3. Testing 'find_user_time_entries' tool...")
try:
result = await session.call_tool(
"find_user_time_entries", {"user_name": "khanson"}
)
print(" Result:")
for content in result.content:
if hasattr(content, "text"):
print(f" {content.text[:500]}...")
except Exception as e:
print(f" Error: {e}")
# Test: Get user weekly summary
print("\n4. Testing 'get_user_weekly_summary' tool...")
try:
result = await session.call_tool(
"get_user_weekly_summary", {"user_name": "khanson", "weeks": 2}
)
print(" Result:")
for content in result.content:
if hasattr(content, "text"):
print(f" {content.text}")
except Exception as e:
print(f" Error: {e}")
# Test: Get user weekly summary
print("\n4. Testing 'get_user_weekly_summary' tool...")
try:
result = await session.call_tool(
"get_user_weekly_summary",
{"user_name": "keith", "weeks": 2}, # Adjust user name
)
print(" Result:")
for content in result.content:
if hasattr(content, "text"):
print(f" {content.text}")
except Exception as e:
print(f" Error: {e}")
# Test: Find undertime users
print("\n5. Testing 'find_undertime_users' tool...")
try:
result = await session.call_tool(
"find_undertime_users", {"hours_threshold": 20}
)
print(" Result:")
for content in result.content:
if hasattr(content, "text"):
print(f" {content.text[:500]}...")
except Exception as e:
print(f" Error: {e}")
# Test: Search time entries
print("\n6. Testing 'search_time_entries' tool...")
try:
result = await session.call_tool(
"search_time_entries",
{"search_phrase": "meeting"}, # Common search term
)
print(" Result:")
for content in result.content:
if hasattr(content, "text"):
print(f" {content.text[:500]}...")
except Exception as e:
print(f" Error: {e}")
print("\n" + "=" * 60)
print("MCP Server tests completed!")
print("=" * 60)
async def interactive_mode():
"""Run interactive mode where user can test tools manually"""
print("=" * 60)
print("Clockify MCP Server - Interactive Mode")
print("=" * 60)
env = os.environ.copy()
server_params = StdioServerParameters(
command="python", args=["-m", "clockify_mcp.server"], env=env
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# List tools
tools_result = await session.list_tools()
tools = {tool.name: tool for tool in tools_result.tools}
print("\nAvailable tools:")
for i, name in enumerate(tools.keys(), 1):
print(f" {i}. {name}")
while True:
print("\n" + "-" * 40)
tool_name = input("Enter tool name (or 'quit' to exit): ").strip()
if tool_name.lower() == "quit":
break
if tool_name not in tools:
print(f"Unknown tool: {tool_name}")
continue
tool = tools[tool_name]
print(f"\nTool: {tool.name}")
print(f"Description: {tool.description}")
print(f"Schema: {json.dumps(tool.inputSchema, indent=2)}")
# Get arguments
args_input = input(
"\nEnter arguments as JSON (or empty for {}): "
).strip()
try:
args = json.loads(args_input) if args_input else {}
except json.JSONDecodeError as e:
print(f"Invalid JSON: {e}")
continue
# Call the tool
try:
print("\nCalling tool...")
result = await session.call_tool(tool_name, args)
print("\nResult:")
for content in result.content:
if hasattr(content, "text"):
print(content.text)
except Exception as e:
print(f"Error: {e}")
print("\nGoodbye!")
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "--interactive":
asyncio.run(interactive_mode())
else:
asyncio.run(test_mcp_server())