Skip to main content
Glama

Smithsonian Open Access MCP Server

by molanojustin
setup.ps116.5 kB
# Smithsonian MCP Server Setup Script (PowerShell) # This script automates the setup process for Claude Desktop and VS Code integration on Windows param( [string]$ApiKey = "", [switch]$SkipTests = $false, [switch]$Verbose = $false ) # Error handling $ErrorActionPreference = "Stop" # Colors for output function Write-Success { param([string]$Message) Write-Host "✓ $Message" -ForegroundColor Green } function Write-Warning { param([string]$Message) Write-Host "⚠ $Message" -ForegroundColor Yellow } function Write-Error { param([string]$Message) Write-Host "✗ $Message" -ForegroundColor Red } function Write-Info { param([string]$Message) Write-Host "ℹ $Message" -ForegroundColor Blue } Write-Host "Smithsonian MCP Server Setup" -ForegroundColor Blue Write-Host "==================================" -ForegroundColor Blue Write-Host "" # Check if Python is installed function Test-Python { Write-Info "Checking Python installation..." $pythonCommands = @("python", "python3", "py") $pythonCmd = $null foreach ($cmd in $pythonCommands) { try { $version = & $cmd --version 2>$null if ($version -match "Python (\d+\.\d+\.\d+)") { $pythonCmd = $cmd Write-Success "Found Python $($matches[1]) using command '$cmd'" break } } catch { # Command not found, try next } } if (-not $pythonCmd) { Write-Error "Python not found. Please install Python 3.10 or later from python.org" exit 1 } return $pythonCmd } # Create virtual environment function New-VirtualEnvironment { param([string]$PythonCmd) Write-Info "Creating virtual environment..." if (-not (Test-Path "venv")) { & $PythonCmd -m venv venv Write-Success "Virtual environment created" } else { Write-Warning "Virtual environment already exists" } # Activate virtual environment $activateScript = ".\venv\Scripts\Activate.ps1" if (Test-Path $activateScript) { & $activateScript Write-Success "Virtual environment activated" } else { Write-Error "Failed to find virtual environment activation script" exit 1 } } # Install dependencies function Install-Dependencies { Write-Info "Installing Python dependencies..." python -m pip install --upgrade pip python -m pip install -r requirements.txt Write-Success "Dependencies installed" } # Get API key from user function Get-ApiKey { param([string]$ProvidedKey) if ($ProvidedKey) { return $ProvidedKey } Write-Host "" Write-Info "API Key Setup" Write-Host "You need an API key from api.data.gov to access Smithsonian data." Write-Host "If you don't have one yet:" Write-Host "1. Visit: https://api.data.gov/signup/" Write-Host "2. Sign up for free (no special permissions needed)" Write-Host "3. Copy your API key" Write-Host "" $key = Read-Host "Enter your API key (or press Enter to set it later)" if ($key) { "SMITHSONIAN_API_KEY=$key" | Out-File -FilePath ".env" -Encoding UTF8 Write-Success "API key saved to .env file" return $key } else { Write-Warning "API key not set. You'll need to configure it manually later." return $null } } # Validate API key function Test-ApiKey { param([string]$ApiKey) if (-not $ApiKey -or $ApiKey -eq "your_api_key_here") { return $false } Write-Info "Validating API key..." try { $result = python -c " import sys import asyncio import httpx import os os.environ['SMITHSONIAN_API_KEY'] = '$ApiKey' sys.path.insert(0, '.') async def test_api_key(): try: headers = {'X-Api-Key': '$ApiKey'} async with httpx.AsyncClient(headers=headers, timeout=10.0) as client: response = await client.get('https://api.si.edu/openaccess/api/v1.0/search?q=test&rows=1') if response.status_code == 200: data = response.json() if isinstance(data, dict) and 'response' in data and 'rows' in data['response']: print('API key is valid') return True else: print('API key is valid') return True else: print(f'API returned status {response.status_code}') return False except Exception as e: print(f'API key validation failed: {e}') return False try: result = asyncio.run(test_api_key()) if result: sys.exit(0) else: sys.exit(1) except Exception as e: print(f'API key validation failed: {e}') sys.exit(1) " 2>$null if ($LASTEXITCODE -eq 0) { return $true } } catch { # Validation failed } return $false } # Get API key from user with validation function Get-ApiKey { param([string]$ProvidedKey) if ($ProvidedKey) { if (Test-ApiKey -ApiKey $ProvidedKey) { return $ProvidedKey } else { Write-Warning "Provided API key is invalid." } } Write-Host "" Write-Info "API Key Setup" Write-Host "You need an API key from api.data.gov to access Smithsonian data." Write-Host "If you don't have one yet:" Write-Host "1. Visit: https://api.data.gov/signup/" Write-Host "2. Sign up for free (no special permissions needed)" Write-Host "3. Copy your API key" Write-Host "" while ($true) { $key = Read-Host "Enter your API key (or press Enter to skip)" if (-not $key) { Write-Warning "Skipping API key setup. You'll need to configure it later." return $null } if (Test-ApiKey -ApiKey $key) { "SMITHSONIAN_API_KEY=$key" | Out-File -FilePath ".env" -Encoding UTF8 Write-Success "API key validated and saved to .env file" return $key } else { Write-Error "Invalid API key. Please try again or press Enter to skip." } } } # Setup Windows service function Set-WindowsService { Write-Info "Setting up Windows service..." $serviceName = "SmithsonianMCP" $projectDir = Get-Location $pythonPath = ".\venv\Scripts\python.exe" # Check if running as administrator $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($currentUser) $isAdmin = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Warning "Windows service installation requires administrator privileges." Write-Info "To install as a service, run this script as Administrator." return } try { # Create service using New-Service $serviceExists = Get-Service -Name $serviceName -ErrorAction SilentlyContinue if ($serviceExists) { Write-Warning "Service $serviceName already exists. Updating..." Stop-Service -Name $serviceName -Force Remove-Service -Name $serviceName } New-Service -Name $serviceName -DisplayName "Smithsonian MCP Server" -BinaryPathName "`"$pythonPath`" -m smithsonian_mcp.server" -StartupType Automatic -WorkingDirectory $projectDir Write-Success "Windows service '$serviceName' installed successfully" Write-Info "Start the service with: Start-Service $serviceName" Write-Info "Stop the service with: Stop-Service $serviceName" } catch { Write-Error "Failed to install Windows service: $($_.Exception.Message)" Write-Info "You can run the server manually with: python -m smithsonian_mcp.server" } } # Setup Claude Desktop configuration function Set-ClaudeDesktop { param([string]$ApiKey) Write-Info "Setting up Claude Desktop integration..." $claudeConfigDir = "$env:APPDATA\Claude" $claudeConfigFile = "$claudeConfigDir\claude_desktop_config.json" $projectDir = Get-Location $pythonPath = ".\venv\Scripts\python.exe" Write-Info "Claude config path: $claudeConfigFile" # Create Claude config directory if it doesn't exist if (-not (Test-Path $claudeConfigDir)) { New-Item -ItemType Directory -Path $claudeConfigDir -Force | Out-Null } # Backup existing config if (Test-Path $claudeConfigFile) { $backupFile = "$claudeConfigFile.backup.$(Get-Date -Format 'yyyyMMdd_HHmmss')" Copy-Item $claudeConfigFile $backupFile Write-Info "Backed up existing Claude Desktop config." } # Create configuration with absolute paths $config = @{ mcpServers = @{ smithsonian_open_access = @{ command = $pythonPath args = @("-m", "smithsonian_mcp.server") env = @{ SMITHSONIAN_API_KEY = $ApiKey LOG_LEVEL = "INFO" } } } } $configJson = $config | ConvertTo-Json -Depth 4 $configJson | Out-File -FilePath $claudeConfigFile -Encoding UTF8 Write-Success "Claude Desktop configuration updated" Write-Warning "You need to restart Claude Desktop for changes to take effect" } # Check if mcpo is available function Test-McpoAvailable { try { $mcpoVersion = mcpo --version 2>$null if ($LASTEXITCODE -eq 0) { return $true } } catch { # mcpo not found directly } try { $uvxTest = uvx mcpo --help 2>$null if ($LASTEXITCODE -eq 0) { return $true } } catch { # uvx mcpo not available } return $false } # Setup mcpo configuration function Set-McpoConfig { param([string]$ApiKey) Write-Info "Setting up mcpo configuration..." if (-not (Test-Path "mcpo-config.example.json")) { Write-Warning "mcpo-config.example.json not found. Skipping mcpo setup." return $false } # Create mcpo config from example $configFile = "mcpo-config.json" Copy-Item "mcpo-config.example.json" $configFile # Get absolute paths $projectDir = Get-Location $pythonPath = ".\venv\Scripts\python.exe" $fullPythonPath = Join-Path $projectDir $pythonPath # Replace paths and API key in config $configContent = Get-Content $configFile -Raw $configContent = $configContent -replace "/path/to/your/project/.venv/bin/python", $fullPythonPath $configContent = $configContent -replace "/path/to/your/project", $projectDir if ($ApiKey) { $configContent = $configContent -replace "your_api_key_here", $ApiKey } $configContent | Out-File -FilePath $configFile -Encoding UTF8 Write-Success "mcpo configuration created at: $configFile" Write-Info "Python path set to: $fullPythonPath" Write-Info "Project path set to: $projectDir" Write-Info "You can start mcpo with: mcpo --config $configFile --port 8000" return $true } # Test the installation function Test-Installation { param([string]$ApiKey, [bool]$SkipTests) if ($SkipTests) { Write-Warning "Skipping installation tests" return } Write-Info "Testing installation..." try { python examples/test-api-connection.py 2>$null Write-Success "API connectivity test passed" } catch { Write-Warning "API connectivity test failed - check your API key" } Write-Success "Installation test complete" } # Run health check function Invoke-HealthCheck { Write-Info "Running health check..." # Test API connection try { python examples/test-api-connection.py Write-Success "✓ API connection test passed" } catch { Write-Error "✗ API connection test failed" return $false } # Test MCP server startup (brief test) try { $process = Start-Process -FilePath "python" -ArgumentList "-m", "smithsonian_mcp.server", "--test" -PassThru -WindowStyle Hidden Start-Sleep -Seconds 5 if (-not $process.HasExited) { Stop-Process -Id $process.Id -Force Write-Success "✓ MCP server startup test passed" } else { Write-Warning "⚠ MCP server startup test inconclusive (this may be normal)" } } catch { Write-Warning "⚠ MCP server startup test inconclusive (this may be normal)" } Write-Success "Health check completed." return $true } # Main installation function function Start-Installation { try { Write-Host "Starting automated setup..." -ForegroundColor Blue Write-Host "" # Check if we're in the right directory if (-not (Test-Path "requirements.txt")) { Write-Error "requirements.txt not found. Please run this script from the project root directory." exit 1 } $pythonCmd = Test-Python New-VirtualEnvironment -PythonCmd $pythonCmd Install-Dependencies # Setup .env file if (-not (Test-Path ".env")) { if (Test-Path ".env.example") { Copy-Item ".env.example" ".env" Write-Info "Created .env from .env.example" } else { "SMITHSONIAN_API_KEY=your_api_key_here" | Out-File -FilePath ".env" -Encoding UTF8 } } # Check for existing API key $existingKey = $null if (Test-Path ".env") { $envContent = Get-Content ".env" $keyLine = $envContent | Where-Object { $_ -match "^SMITHSONIAN_API_KEY=" } if ($keyLine) { $existingKey = $keyLine -replace "^SMITHSONIAN_API_KEY=", "" } } if ($existingKey -and $existingKey -ne "your_api_key_here" -and (Test-ApiKey -ApiKey $existingKey)) { $apiKey = $existingKey Write-Success "Using existing valid API key from .env file." } else { $apiKey = Get-ApiKey -ProvidedKey $ApiKey } # Check for mcpo and offer setup if (Test-McpoAvailable) { Write-Success "mcpo detected on your system." $setupMcpo = Read-Host "Do you want to create an mcpo configuration file? (y/N)" if ($setupMcpo -match '^[Yy]') { Set-McpoConfig -ApiKey $apiKey } } else { Write-Info "mcpo not found. For multi-MCP orchestration, install with: pip install mcpo" } # Setup Windows service $setupService = Read-Host "Do you want to install Smithsonian MCP as a Windows service? (y/N)" if ($setupService -match '^[Yy]') { Set-WindowsService } # Setup Claude Desktop config if ($apiKey) { $setupClaude = Read-Host "Do you want to automatically configure Claude Desktop? (y/N)" if ($setupClaude -match '^[Yy]') { Set-ClaudeDesktop -ApiKey $apiKey } } # Run health check $runCheck = Read-Host "Do you want to run a health check? (Y/n)" if ($runCheck -notmatch '^[Nn]') { Invoke-HealthCheck } Write-Host "" Write-Host "🎉 Setup Complete!" -ForegroundColor Green Write-Host "" if ($apiKey) { Write-Success "✓ API key configured and validated" } else { Write-Warning "⚠ Edit .env and add your API key from https://api.data.gov/signup/" } Write-Success "✓ Dependencies installed" Write-Success "✓ Virtual environment created" Write-Host "" Write-Host "Usage:" Write-Host " Activate environment: .\venv\Scripts\Activate.ps1" Write-Host " Test connection: python examples/test-api-connection.py" Write-Host " Run server: python -m smithsonian_mcp.server" if (Get-Service -Name "SmithsonianMCP" -ErrorAction SilentlyContinue) { Write-Host " Manage service: Start-Service SmithsonianMCP / Stop-Service SmithsonianMCP" } Write-Host "" Write-Host "For troubleshooting, see README.md or run: python scripts\verify-setup.py" } catch { Write-Error "Setup failed: $($_.Exception.Message)" Write-Host "Please check the error message above and try again." -ForegroundColor Yellow exit 1 } } # Run the installation Start-Installation

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/molanojustin/smithsonian-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server