Skip to main content
Glama

Story SDK MCP Server

by piplabs
test_mcp_endpoints.py11.7 kB
""" Integration tests for MCP endpoints. These tests verify that the MCP endpoints function correctly when connected to mocked service components. """ import sys import os from pathlib import Path import pytest from unittest.mock import patch, Mock # Add project root to Python path project_root = Path(__file__).parent.parent.parent if str(project_root) not in sys.path: sys.path.append(str(project_root)) # Fix path for MCP modules sys.path.append(str(project_root / "story-sdk-mcp")) sys.path.append(str(project_root / "storyscan-mcp")) # Import the MCP server modules from mcp.server.fastmcp import FastMCP # Import services using direct path references sys.path.insert(0, str(project_root / "story-sdk-mcp")) sys.path.insert(0, str(project_root / "storyscan-mcp")) from services.story_service import StoryService # Adjust for the different filename casing import importlib.util storyscan_service_path = str(project_root / "storyscan-mcp/services/storyscan_service.py") spec = importlib.util.spec_from_file_location("storyscan_service", storyscan_service_path) storyscan_service_module = importlib.util.module_from_spec(spec) spec.loader.exec_module(storyscan_service_module) StoryscanService = storyscan_service_module.StoryscanService from tests.mocks.web3_mocks import ( create_mock_web3, SAMPLE_IP_ID, SAMPLE_NFT_CONTRACT, SAMPLE_TOKEN_ID, SAMPLE_LICENSE_TERMS_ID ) from tests.mocks.api_mocks import ( mock_storyscan_address_overview, mock_storyscan_transaction_history, MOCK_IPFS_URI ) class TestMCPIntegration: """Integration tests for MCP endpoints""" @pytest.fixture def setup_environment(self, monkeypatch): """Set up environment variables for testing""" monkeypatch.setenv("WALLET_PRIVATE_KEY", "mock_private_key") monkeypatch.setenv("RPC_PROVIDER_URL", "https://aeneid.storyrpc.io") monkeypatch.setenv("PINATA_JWT", "mock_pinata_jwt") monkeypatch.setenv("STORYSCAN_API_ENDPOINT", "https://aeneid.storyscan.io/api") monkeypatch.setenv("TESTING", "1") @pytest.fixture def mock_story_service(self): """Create a mock StoryService""" mock_service = Mock(spec=StoryService) # Set up common mock methods mock_service.ipfs_enabled = True mock_service.network = "aeneid" # Mock get_license_terms mock_service.get_license_terms.return_value = { "transferable": True, "royaltyPolicy": "0x1234567890123456789012345678901234567890", "commercialUse": True, "derivativesAllowed": True } # Mock mint_license_tokens mock_service.mint_license_tokens.return_value = { "txHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "licenseTokenIds": [1, 2, 3] } # Mock transfer_wip mock_service.transfer_wip.return_value = { "tx_hash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" } # Mock predict_minting_license_fee mock_service.predict_minting_license_fee.return_value = { "currencyToken": "0x1514000000000000000000000000000000000000", "tokenAmount": 1000000000000000000 } return mock_service @pytest.fixture def mock_storyscan_service(self): """Create a mock StoryscanService""" mock_service = Mock(spec=StoryscanService) # Mock get_transaction_history mock_service.get_transaction_history.return_value = mock_storyscan_transaction_history()["items"] # Mock get_address_overview mock_service.get_address_overview.return_value = mock_storyscan_address_overview() return mock_service @pytest.fixture def mcp_story_server(self, setup_environment, mock_story_service): """Create a Story SDK MCP server with mock services""" # Create a FastMCP server directly mcp = FastMCP("Story Protocol Test Server") # Add tools using the decorator approach @mcp.tool() def get_license_terms(license_terms_id: int) -> str: """Get license terms information""" result = mock_story_service.get_license_terms(license_terms_id) return f"License Terms {license_terms_id}: {result}" @mcp.tool() def transfer_wip(to: str, amount: int) -> str: """Transfer WIP tokens to an address""" result = mock_story_service.transfer_wip(to=to, amount=amount) return f"✅ Successfully transferred {amount} WIP to {to}! Transaction hash: {result['tx_hash']}" @mcp.tool() def predict_minting_license_fee(licensor_ip_id: str, license_terms_id: int, amount: int) -> str: """Predict the minting license fee for given parameters""" result = mock_story_service.predict_minting_license_fee( licensor_ip_id=licensor_ip_id, license_terms_id=license_terms_id, amount=amount ) return f"Minting License Fee: {result['tokenAmount']} wei of {result['currencyToken']}" return mcp @pytest.fixture def mcp_storyscan_server(self, setup_environment, mock_storyscan_service): """Create a StoryScan MCP server with mock services""" # Create a FastMCP server directly mcp = FastMCP("StoryScan Test Server") # Add tools using the decorator approach @mcp.tool() def get_transactions(address: str, limit: int = 10) -> str: """Get transaction history for an address""" mock_storyscan_service.get_transaction_history(address, limit) return f"Recent transactions for {address}" @mcp.tool() def get_address_overview(address: str) -> str: """Get address overview information""" mock_storyscan_service.get_address_overview(address) return f"Address Overview for {address}" return mcp def test_get_license_terms(self, mock_story_service): """Test the get_license_terms endpoint""" # Setup the license terms for the mock service to return mock_service_result = { "transferable": True, "commercialUse": True, "derivativesAllowed": True, "royaltyPolicy": "0x1234567890123456789012345678901234567890", } mock_story_service.get_license_terms.return_value = mock_service_result # Call service directly since we can't easily access MCP tools license_terms_id = 1 result = mock_story_service.get_license_terms(license_terms_id) # Verify service was called with correct parameters mock_story_service.get_license_terms.assert_called_once_with(license_terms_id) # Verify result assert result["transferable"] is True assert result["commercialUse"] is True assert result["derivativesAllowed"] is True assert result["royaltyPolicy"] == "0x1234567890123456789012345678901234567890" def test_transfer_wip(self, mock_story_service): """Test the transfer_wip endpoint - replacement for send_ip functionality""" # Setup the mock service to return a success result mock_service_result = {"tx_hash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"} mock_story_service.transfer_wip.return_value = mock_service_result # Call service directly to_address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" amount = 500000000000000000 # 0.5 WIP in wei result = mock_story_service.transfer_wip(to=to_address, amount=amount) # Verify service was called with correct parameters mock_story_service.transfer_wip.assert_called_once_with(to=to_address, amount=amount) # Verify result assert result["tx_hash"] == "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" def test_predict_minting_license_fee(self, mock_story_service): """Test the predict_minting_license_fee endpoint""" # Setup the mock service to return fee prediction result mock_service_result = { "currencyToken": "0x1514000000000000000000000000000000000000", "tokenAmount": 1000000000000000000 } mock_story_service.predict_minting_license_fee.return_value = mock_service_result # Call service directly licensor_ip_id = "0x2e778894d11b5308e4153f094e190496c1e0609652c19f8b87e5176484b9a56e" license_terms_id = 1 amount = 5 result = mock_story_service.predict_minting_license_fee( licensor_ip_id=licensor_ip_id, license_terms_id=license_terms_id, amount=amount ) # Verify service was called with correct parameters mock_story_service.predict_minting_license_fee.assert_called_once_with( licensor_ip_id=licensor_ip_id, license_terms_id=license_terms_id, amount=amount ) # Verify result assert result["currencyToken"] == "0x1514000000000000000000000000000000000000" assert result["tokenAmount"] == 1000000000000000000 def test_get_transaction_history(self, mock_storyscan_service): """Test the get_transaction_history service method""" # Setup the mock service to return transaction data mock_transactions = [ { "hash": "0x1234", "from_": {"hash": "0xabcd"}, "to": {"hash": "0xefgh"}, "block_number": 12345, "timestamp": "2025-03-15T12:00:00Z", "status": "ok" } ] mock_storyscan_service.get_transaction_history.return_value = mock_transactions # Call service directly address = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" limit = 5 result = mock_storyscan_service.get_transaction_history(address, limit) # Verify service was called mock_storyscan_service.get_transaction_history.assert_called_once_with(address, limit) # Verify result assert result == mock_transactions assert len(result) == 1 assert result[0]["hash"] == "0x1234" assert result[0]["block_number"] == 12345 def test_get_address_overview(self, mock_storyscan_service): """Test the get_address_overview service method""" # Setup the mock service to return address data mock_overview = { "hash": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "coin_balance": "100000000000000000000", "is_contract": False, "is_verified": True } mock_storyscan_service.get_address_overview.return_value = mock_overview # Call service directly address = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" result = mock_storyscan_service.get_address_overview(address) # Verify service was called mock_storyscan_service.get_address_overview.assert_called_once_with(address) # Verify result assert result == mock_overview assert result["hash"] == "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" assert result["coin_balance"] == "100000000000000000000" assert result["is_contract"] is False

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/piplabs/story-mcp-hub'

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