feat: add version checking capability to MCP server

- Add version metadata (__version__, __updated__, __author__)
- Create get_version tool that returns server information
- Include Python version, start time, and configuration details
- Add comprehensive tests for version functionality
- Update existing tests to handle new tool count

Now you can check the server version from Claude by asking:
"Can you get the version of the Gemini MCP server?"

Version: 2.2.0
Updated: 2025-06-08
Author: Fahad Gilani

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Fahad
2025-06-08 21:07:41 +04:00
parent f8d8c8a412
commit 9a3c476056
3 changed files with 126 additions and 1 deletions

View File

@@ -7,6 +7,7 @@ Enhanced for large-scale code analysis with 1M token context window
import asyncio import asyncio
import json import json
import os import os
from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional, Tuple
@@ -17,6 +18,11 @@ from mcp.server.stdio import stdio_server
from mcp.types import TextContent, Tool from mcp.types import TextContent, Tool
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
# Version and metadata
__version__ = "2.2.0"
__updated__ = "2025-06-08"
__author__ = "Fahad Gilani"
# Default to Gemini 2.5 Pro Preview with maximum context # Default to Gemini 2.5 Pro Preview with maximum context
DEFAULT_MODEL = "gemini-2.5-pro-preview-06-05" DEFAULT_MODEL = "gemini-2.5-pro-preview-06-05"
MAX_CONTEXT_TOKENS = 1000000 # 1M tokens MAX_CONTEXT_TOKENS = 1000000 # 1M tokens
@@ -277,6 +283,11 @@ async def handle_list_tools() -> List[Tool]:
description="List available Gemini models", description="List available Gemini models",
inputSchema={"type": "object", "properties": {}}, inputSchema={"type": "object", "properties": {}},
), ),
Tool(
name="get_version",
description="Get the version and metadata of the Gemini MCP Server",
inputSchema={"type": "object", "properties": {}},
),
] ]
@@ -426,6 +437,33 @@ marked with their paths and content boundaries."""
except Exception as e: except Exception as e:
return [TextContent(type="text", text=f"Error listing models: {str(e)}")] return [TextContent(type="text", text=f"Error listing models: {str(e)}")]
elif name == "get_version":
# Return version and metadata information
version_info = {
"version": __version__,
"updated": __updated__,
"author": __author__,
"default_model": DEFAULT_MODEL,
"max_context_tokens": f"{MAX_CONTEXT_TOKENS:,}",
"python_version": f"{os.sys.version_info.major}.{os.sys.version_info.minor}.{os.sys.version_info.micro}",
"server_started": datetime.now().isoformat(),
}
return [TextContent(
type="text",
text=f"""🤖 Gemini MCP Server v{__version__}
Updated: {__updated__}
Author: {__author__}
Configuration:
• Default Model: {DEFAULT_MODEL}
• Max Context: {MAX_CONTEXT_TOKENS:,} tokens
• Python: {version_info['python_version']}
• Started: {version_info['server_started']}
For updates, visit: https://github.com/BeehiveInnovations/gemini-mcp-server"""
)]
else: else:
return [TextContent(type="text", text=f"Unknown tool: {name}")] return [TextContent(type="text", text=f"Unknown tool: {name}")]

View File

@@ -139,12 +139,13 @@ class TestToolHandlers:
async def test_handle_list_tools(self): async def test_handle_list_tools(self):
"""Test listing available tools""" """Test listing available tools"""
tools = await handle_list_tools() tools = await handle_list_tools()
assert len(tools) == 3 assert len(tools) == 4 # Updated to include get_version
tool_names = [tool.name for tool in tools] tool_names = [tool.name for tool in tools]
assert "chat" in tool_names assert "chat" in tool_names
assert "analyze_code" in tool_names assert "analyze_code" in tool_names
assert "list_models" in tool_names assert "list_models" in tool_names
assert "get_version" in tool_names
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_handle_call_tool_unknown(self): async def test_handle_call_tool_unknown(self):

86
tests/test_version.py Normal file
View File

@@ -0,0 +1,86 @@
"""
Test version functionality
"""
import pytest
import json
from pathlib import Path
import sys
# Add parent directory to path for imports
parent_dir = Path(__file__).resolve().parent.parent
if str(parent_dir) not in sys.path:
sys.path.insert(0, str(parent_dir))
from gemini_server import (
__version__,
__updated__,
__author__,
handle_list_tools,
handle_call_tool,
)
class TestVersionFunctionality:
"""Test version-related functionality"""
@pytest.mark.asyncio
async def test_version_constants_exist(self):
"""Test that version constants are defined"""
assert __version__ is not None
assert isinstance(__version__, str)
assert __updated__ is not None
assert isinstance(__updated__, str)
assert __author__ is not None
assert isinstance(__author__, str)
@pytest.mark.asyncio
async def test_version_tool_in_list(self):
"""Test that get_version tool appears in tool list"""
tools = await handle_list_tools()
tool_names = [tool.name for tool in tools]
assert "get_version" in tool_names
# Find the version tool
version_tool = next(t for t in tools if t.name == "get_version")
assert version_tool.description == "Get the version and metadata of the Gemini MCP Server"
@pytest.mark.asyncio
async def test_get_version_tool_execution(self):
"""Test executing the get_version tool"""
result = await handle_call_tool("get_version", {})
assert len(result) == 1
assert result[0].type == "text"
# Check the response contains expected information
response_text = result[0].text
assert __version__ in response_text
assert __updated__ in response_text
assert __author__ in response_text
assert "Gemini MCP Server" in response_text
assert "Default Model:" in response_text
assert "Max Context:" in response_text
assert "Python:" in response_text
assert "Started:" in response_text
assert "github.com/BeehiveInnovations/gemini-mcp-server" in response_text
@pytest.mark.asyncio
async def test_version_format(self):
"""Test that version follows semantic versioning"""
parts = __version__.split(".")
assert len(parts) == 3 # Major.Minor.Patch
for part in parts:
assert part.isdigit() # Each part should be numeric
@pytest.mark.asyncio
async def test_date_format(self):
"""Test that updated date follows expected format"""
# Expected format: YYYY-MM-DD
parts = __updated__.split("-")
assert len(parts) == 3
assert len(parts[0]) == 4 # Year
assert len(parts[1]) == 2 # Month
assert len(parts[2]) == 2 # Day
for part in parts:
assert part.isdigit()