Skip to main content
Glama
models.py9.61 kB
""" Database models for RESOURCE_NAME custom resource This file defines database models that your custom resource needs. When this file exists, Alembic will automatically discover it and include the models in migration generation. Replace RESOURCE_NAME with your actual resource name throughout this file. """ from datetime import datetime from typing import Dict, Any, Optional import uuid from sqlalchemy import DateTime, Integer, String, func, ForeignKey, Text, Boolean, Index from sqlalchemy.dialects.postgresql import JSONB, UUID from sqlalchemy.orm import Mapped, mapped_column, relationship # Import the base class from mcpeasy core from src.models.base import Base # Import for type hints (optional) from typing import TYPE_CHECKING if TYPE_CHECKING: from src.models.client import Client class RESOURCENAMEItem(Base): """ Example model for storing RESOURCE_NAME items This demonstrates how to create custom models for resources that: - Store resource data in the database - Support client-specific filtering - Cache external API data - Enable fast searching and filtering """ __tablename__ = "resourcename_items" # Replace with your resource name # Primary key id: Mapped[int] = mapped_column(Integer, primary_key=True) # External identifier (from source system) external_id: Mapped[str] = mapped_column(String(255), nullable=False) # Resource content name: Mapped[str] = mapped_column(String(500), nullable=False) description: Mapped[Optional[str]] = mapped_column(Text, nullable=True) content: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB, nullable=True) # Resource metadata category: Mapped[Optional[str]] = mapped_column(String(100), nullable=True) tags: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB, nullable=True) # Array of strings mime_type: Mapped[str] = mapped_column(String(100), default="text/plain", nullable=False) # Access control and filtering is_public: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False) allowed_clients: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB, nullable=True) # Array of client IDs # Cache management source_url: Mapped[Optional[str]] = mapped_column(String(1000), nullable=True) last_synced: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True) sync_hash: Mapped[Optional[str]] = mapped_column(String(64), nullable=True) # For detecting changes # Metadata created_at: Mapped[datetime] = mapped_column(DateTime, default=func.now(), nullable=False) updated_at: Mapped[datetime] = mapped_column( DateTime, default=func.now(), onupdate=func.now(), nullable=False ) # Add indexes for common queries __table_args__ = ( Index('ix_resourcename_external_id', 'external_id'), Index('ix_resourcename_category', 'category'), Index('ix_resourcename_public', 'is_public'), Index('ix_resourcename_last_synced', 'last_synced'), ) def __repr__(self) -> str: return f"<RESOURCENAMEItem(id={self.id}, external_id='{self.external_id}', name='{self.name}')>" def to_dict(self) -> Dict[str, Any]: """Convert to dictionary for API responses""" return { "id": self.id, "external_id": self.external_id, "name": self.name, "description": self.description, "content": self.content, "category": self.category, "tags": self.tags, "mime_type": self.mime_type, "is_public": self.is_public, "source_url": self.source_url, "last_synced": self.last_synced.isoformat() if self.last_synced else None, "created_at": self.created_at.isoformat(), "updated_at": self.updated_at.isoformat() } def to_mcp_resource(self) -> Dict[str, Any]: """Convert to MCP Resource format""" return { "uri": f"resourcename://{self.external_id}", # Replace with your URI scheme "name": self.name, "description": self.description or "", "mimeType": self.mime_type } class RESOURCENAMEAccess(Base): """ Example model for tracking resource access per client This demonstrates how to: - Log resource usage for analytics - Track client-specific access patterns - Support billing/usage reporting """ __tablename__ = "resourcename_access" # Primary key id: Mapped[int] = mapped_column(Integer, primary_key=True) # Link to mcpeasy core client model client_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("clients.id"), nullable=False ) # Link to resource item resource_item_id: Mapped[int] = mapped_column( Integer, ForeignKey("resourcename_items.id"), nullable=False ) # Access details operation: Mapped[str] = mapped_column(String(50), nullable=False) # 'list', 'read' uri_requested: Mapped[str] = mapped_column(String(1000), nullable=False) success: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False) error_message: Mapped[Optional[str]] = mapped_column(Text, nullable=True) # Performance tracking response_time_ms: Mapped[Optional[int]] = mapped_column(Integer, nullable=True) bytes_returned: Mapped[Optional[int]] = mapped_column(Integer, nullable=True) # Metadata created_at: Mapped[datetime] = mapped_column(DateTime, default=func.now(), nullable=False) # Relationships client: Mapped["Client"] = relationship("Client") resource_item: Mapped["RESOURCENAMEItem"] = relationship("RESOURCENAMEItem") # Indexes for analytics queries __table_args__ = ( Index('ix_resourcename_access_client', 'client_id'), Index('ix_resourcename_access_created', 'created_at'), Index('ix_resourcename_access_operation', 'operation'), ) def __repr__(self) -> str: return f"<RESOURCENAMEAccess(id={self.id}, client_id={self.client_id}, operation='{self.operation}')>" class RESOURCENAMESync(Base): """ Example model for tracking synchronization with external systems This demonstrates how to: - Track sync operations with external APIs - Store sync metadata and status - Enable sync scheduling and monitoring """ __tablename__ = "resourcename_sync" # Primary key id: Mapped[int] = mapped_column(Integer, primary_key=True) # Sync details sync_type: Mapped[str] = mapped_column(String(50), nullable=False) # 'full', 'incremental' source_system: Mapped[str] = mapped_column(String(100), nullable=False) source_url: Mapped[Optional[str]] = mapped_column(String(1000), nullable=True) # Sync status status: Mapped[str] = mapped_column(String(50), default="running", nullable=False) # 'running', 'completed', 'failed' started_at: Mapped[datetime] = mapped_column(DateTime, default=func.now(), nullable=False) completed_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True) # Sync results items_processed: Mapped[int] = mapped_column(Integer, default=0, nullable=False) items_created: Mapped[int] = mapped_column(Integer, default=0, nullable=False) items_updated: Mapped[int] = mapped_column(Integer, default=0, nullable=False) items_deleted: Mapped[int] = mapped_column(Integer, default=0, nullable=False) # Error handling error_message: Mapped[Optional[str]] = mapped_column(Text, nullable=True) error_details: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB, nullable=True) # Sync metadata sync_config: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB, nullable=True) last_cursor: Mapped[Optional[str]] = mapped_column(String(500), nullable=True) # For incremental sync def __repr__(self) -> str: return f"<RESOURCENAMESync(id={self.id}, status='{self.status}', items_processed={self.items_processed})>" def to_dict(self) -> Dict[str, Any]: """Convert to dictionary for API responses""" return { "id": self.id, "sync_type": self.sync_type, "source_system": self.source_system, "status": self.status, "started_at": self.started_at.isoformat(), "completed_at": self.completed_at.isoformat() if self.completed_at else None, "items_processed": self.items_processed, "items_created": self.items_created, "items_updated": self.items_updated, "items_deleted": self.items_deleted, "error_message": self.error_message } # TODO: Add your own custom models here # # Example patterns for resources: # # 1. Item storage models (like RESOURCENAMEItem above) # 2. Access tracking models (like RESOURCENAMEAccess above) # 3. Sync/cache models (like RESOURCENAMESync above) # 4. Category/taxonomy models for organizing resources # 5. Permission/ACL models for fine-grained access control # 6. Metadata/annotation models for enriching resources # # Best practices: # - Always consider client-specific access patterns # - Add indexes for common query patterns # - Use JSONB for flexible metadata storage # - Include sync/cache management if using external data # - Track usage for analytics and billing # - Follow naming convention: resourcename_tablename

Latest Blog Posts

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/GeorgeStrakhov/mcpeasy'

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