Skip to main content
Glama
cbcoutinho

Nextcloud MCP Server

by cbcoutinho
env.py4.08 kB
"""Alembic environment configuration for nextcloud-mcp-server. This module configures how Alembic runs database migrations for the token storage database. It supports both online and offline migration modes. Uses anyio for async operations, consistent with the project's async patterns. """ import logging from pathlib import Path import anyio from sqlalchemy import pool from sqlalchemy.engine import Connection from sqlalchemy.ext.asyncio import async_engine_from_config from alembic import context # Configure logging logger = logging.getLogger("alembic.env") # This is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config # Update script location to point to package location # This allows alembic to find migrations when installed in site-packages script_location = Path(__file__).parent config.set_main_option("script_location", str(script_location)) # We don't use SQLAlchemy models, so target_metadata is None # Migrations will be written manually using op.execute() for raw SQL target_metadata = None def get_database_url() -> str: """ Get the database URL from Alembic config or environment. The URL can be set in alembic.ini or passed via -x database_url=... when running Alembic commands. Returns: Database URL (SQLite URL format) """ # Check if URL is passed via -x database_url=... url = context.get_x_argument(as_dictionary=True).get("database_url") if not url: # Fall back to alembic.ini configuration url = config.get_main_option("sqlalchemy.url") if not url: # Default to /app/data/tokens.db for Docker deployments db_path = Path("/app/data/tokens.db") url = f"sqlite+aiosqlite:///{db_path}" logger.warning( f"No database URL configured, using default: {url}. " "Set sqlalchemy.url in alembic.ini or pass -x database_url=..." ) return url def run_migrations_offline() -> None: """Run migrations in 'offline' mode. This configures the context with just a URL and not an Engine, though an Engine is acceptable here as well. By skipping the Engine creation we don't even need a DBAPI to be available. Calls to context.execute() here emit the given string to the script output. This mode is useful for generating SQL scripts without database access. """ url = get_database_url() context.configure( url=url, target_metadata=target_metadata, literal_binds=True, dialect_opts={"paramstyle": "named"}, ) with context.begin_transaction(): context.run_migrations() def do_run_migrations(connection: Connection) -> None: """Execute migrations within a database connection.""" context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() async def run_async_migrations() -> None: """Run migrations in 'online' mode with async support. In this scenario we create an async Engine and associate a connection with the context. """ # Get database URL and update config url = get_database_url() config.set_main_option("sqlalchemy.url", url) # Create async engine connectable = async_engine_from_config( config.get_section(config.config_ini_section, {}), prefix="sqlalchemy.", poolclass=pool.NullPool, # Don't pool connections for migrations ) async with connectable.connect() as connection: await connection.run_sync(do_run_migrations) await connectable.dispose() def run_migrations_online() -> None: """Run migrations in 'online' mode. This function is called from storage.py's initialize() method via anyio.to_thread.run_sync(), so it always runs in a worker thread with its own event loop. We can safely use anyio.run() here. """ anyio.run(run_async_migrations) if context.is_offline_mode(): run_migrations_offline() else: run_migrations_online()

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/cbcoutinho/nextcloud-mcp-server'

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