Skip to main content
Glama

MCP Context Forge Gateway

by SPRIME01
Apache 2.0
pyproject.toml14.3 kB
# ---------------------------------------------------------------- # 💡 Build system (PEP 517) # - setuptools ≥ 77 gives SPDX licence support (PEP 639) # - wheel is needed by most build front-ends # ---------------------------------------------------------------- [build-system] requires = ["setuptools>=77", "wheel"] build-backend = "setuptools.build_meta" # ---------------------------------------------------------------- # 📦 Core project metadata (PEP 621) # ---------------------------------------------------------------- [project] name = "mcp-contextforge-gateway" version = "0.3.1" description = "A production-grade MCP Gateway & Proxy built with FastAPI. Supports multi-server registration, virtual server composition, authentication, retry logic, observability, protocol translation, and a unified federated tool catalog." keywords = ["MCP","API","gateway","proxy","tools", "agents","agentic ai","model context protocol","multi-agent","fastapi", "json-rpc","sse","websocket","federation","security","authentication" ] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Framework :: FastAPI", "Framework :: AsyncIO", "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", "Topic :: Software Development :: Libraries :: Application Frameworks" ] readme = "README.md" requires-python = ">=3.11,<3.14" # SPDX licence expression + explicit licence file (PEP 639) license = "Apache-2.0" license-files = ["LICENSE"] # Maintainers maintainers = [ {name = "Mihai Criveti", email = "redacted@ibm.com"} ] # ---------------------------------------------------------------- # Runtime dependencies # ---------------------------------------------------------------- dependencies = [ "alembic>=1.16.4", "cryptography>=45.0.5", "fastapi>=0.116.1", "filelock>=3.18.0", "gunicorn>=23.0.0", "httpx>=0.28.1", "jinja2>=3.1.6", "jq>=1.10.0", "jsonpath-ng>=1.7.0", "jsonschema>=4.24.0", "mcp>=1.11.0", "parse>=1.20.2", "psutil>=7.0.0", "pydantic>=2.11.7", "pydantic-settings>=2.10.1", "pyjwt>=2.10.1", "sqlalchemy>=2.0.41", "sse-starlette>=2.4.1", "starlette>=0.46.2", "uvicorn>=0.35.0", "zeroconf>=0.147.0", ] # ---------------------------------------------------------------- # Optional dependency groups (extras) # ---------------------------------------------------------------- [project.optional-dependencies] # Optional dependency groups (runtime) redis = [ "redis>=6.2.0", ] postgres = [ "psycopg2-binary>=2.9.10", ] alembic = [ "alembic>=1.16.4", ] # Async SQLite Driver (optional) aiosqlite = [ "aiosqlite>=0.21.0", ] # Async PostgreSQL driver (optional) asyncpg = [ "asyncpg>=0.30.0", ] # Optional dependency groups (development) dev = [ "argparse-manpage>=4.6", "autoflake>=2.3.1", "bandit>=1.8.6", "black>=25.1.0", "bump2version>=1.0.1", "check-manifest>=0.50", "code2flow>=2.5.1", "cookiecutter>=2.6.0", "coverage>=7.9.2", "coverage-badge>=1.1.2", "darglint>=1.8.1", "dlint>=0.16.0", "dodgy>=0.2.1", "fawltydeps>=0.20.0", "flake8>=7.3.0", "gprof2dot>=2025.4.14", "importchecker>=3.0", "interrogate>=1.7.0", "isort>=6.0.1", "mypy>=1.17.0", "pexpect>=4.9.0", "pip-licenses>=5.0.0", "pip_audit>=2.9.0", "pre-commit>=4.2.0", "prospector[with_everything]>=1.17.2", "pydocstyle>=6.3.0", "pylint>=3.3.7", "pylint-pydantic>=0.3.5", "pyre-check>=0.9.25", "pyrefly>=0.24.2", "pyright>=1.1.403", "pyroma>=5.0", "pyspelling>=2.10", "pytest>=8.4.1", "pytest-asyncio>=1.0.0", "pytest-cov>=6.2.1", "pytest-env>=1.1.5", "pytest-examples>=0.0.18", "pytest-md-report>=0.7.0", "pytest-rerunfailures>=15.1", "pytest-trio>=0.8.0", "pytest-xdist>=3.8.0", "pytype>=2024.10.11", "pyupgrade>=3.20.0", "radon>=6.0.1", "redis>=6.2.0", "ruff>=0.12.3", "semgrep>=1.128.1", "settings-doc>=4.3.2", "snakeviz>=2.2.2", "tomlcheck>=0.2.3", "tox>=4.27.0", "tox-uv>=1.26.1", "twine>=6.1.0", "ty>=0.0.1a14", "types-tabulate>=0.9.0.20241207", "unimport>=1.2.1", "uv>=0.7.21", "vulture>=2.14", "yamllint>=1.37.1", ] # UI Testing playwright = [ "playwright>=1.53.0", "pytest-html>=4.1.1", "pytest-playwright>=0.7.0", "pytest-timeout>=2.4.0", ] # Convenience meta-extras all = [ "mcp-contextforge-gateway[redis]>=0.3.1", ] dev-all = [ "mcp-contextforge-gateway[redis,dev]>=0.3.1", ] # -------------------------------------------------------------------- # Authors and URLs # -------------------------------------------------------------------- [[project.authors]] name = "Mihai Criveti" email = "redacted@ibm.com" [project.urls] Homepage = "https://ibm.github.io/mcp-context-forge/" Documentation = "https://ibm.github.io/mcp-context-forge/" Repository = "https://github.com/IBM/mcp-context-forge" "Bug Tracker" = "https://github.com/IBM/mcp-context-forge/issues" Changelog = "https://github.com/IBM/mcp-context-forge/blob/main/CHANGELOG.md" # -------------------------------------------------------------------- # 💻 Project scripts (cli entrypoint) # -------------------------------------------------------------------- [project.scripts] mcpgateway = "mcpgateway.cli:main" # -------------------------------------------------------------------- # 🔧 setuptools-specific configuration # -------------------------------------------------------------------- [tool.setuptools] include-package-data = true # ensure wheels include the data files # Automatic discovery: keep every package that starts with "mcpgateway" [tool.setuptools.packages.find] include = ["mcpgateway*"] exclude = ["tests*"] ## Runtime data files ------------------------------------------------ # - py.typed -> advertises inline type hints (PEP 561) # - static/* -> CSS/JS for the admin UI # - templates -> Jinja2 templates shipped at runtime [tool.setuptools.package-data] mcpgateway = [ "py.typed", "static/*.css", "static/*.js", "templates/*.html", "alembic.ini", "alembic/*.py", "alembic/*.mako", "alembic/*.md", "alembic/versions/*.py", ] # -------------------------------------------------------------------- # 🛠 Tool configurations (black, mypy, etc.) # -------------------------------------------------------------------- [tool.pytype] # Directory-specific options: inputs = ["mcpgateway"] python_version = "3.11" # match default runtime [tool.check-manifest] ignore = [ "docs/**", "tests/**", ".github/**", "Makefile", ] [tool.black] line-length = 200 target-version = ["py310", "py311", "py312"] include = "\\.pyi?$" # isort configuration [tool.isort] ############################################################################### # Core behaviour ############################################################################### profile = "black" # inherit Black's own import-sorting profile line_length = 200 # match Black's custom line length multi_line_output = 3 # vertical-hanging-indent style include_trailing_comma = true # keep trailing commas for Black from_first = true # place all "from ... import ..." before plain "import ..." ############################################################################### # Section ordering & headings ############################################################################### sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"] import_heading_future = "Future" # header above FUTURE imports (if headings enabled) import_heading_stdlib = "Standard" # header for built-in Stdlib imports import_heading_thirdparty = "Third-Party" # header for pip-installed packages import_heading_firstparty = "First-Party" # header for internal 'mcpgateway' code import_heading_localfolder = "Local" # header for ad-hoc scripts / tests ############################################################################### # What belongs where ############################################################################### known_first_party = ["mcpgateway"] # treat "mcpgateway.*" as FIRSTPARTY known_local_folder = ["tests", "scripts"] # treat these folders as LOCALFOLDER # src_paths = ["src/mcpgateway"] # uncomment only if package moves under src/ ############################################################################### # Style niceties ############################################################################### force_sort_within_sections = true # always alphabetise names inside each block order_by_type = false # don't group imports by "type vs. straight name" balanced_wrapping = true # spread wrapped imports evenly between lines lines_between_sections = 1 # exactly one blank line between the five groups lines_between_types = 1 # one blank line between 'import X' and 'from X import ...' no_lines_before = ["LOCALFOLDER"] # suppress blank line *before* the LOCALFOLDER block ensure_newline_before_comments = true # newline before any inline # comment after an import ############################################################################### # Ignore junk we never want to touch ############################################################################### extend_skip = [ ".md", ".json", ".yaml", ".yml", "dist", "build", ".venv", ".tox", "*.tmp", "*.bak", ] skip_glob = ["**/__init__.py"] # leave namespace init files alone # ---- Optional CI toggles ---------------------------------------------------- # check_only = true # dry-run mode: non-zero exit if files would change # verbose = true # print every file name processed # case_sensitive = true # treat upper/lowercase differences as significant [tool.mypy] # Target Python version python_version = "3.11" # Full strictness and individual checks strict = true # Enable all strict checks check_untyped_defs = true # Type-check the bodies of untyped functions no_implicit_optional = true # Require explicit Optional for None default disallow_untyped_defs = true # Require type annotations for all functions disallow_untyped_calls = true # Disallow calling functions without type info disallow_any_unimported = true # Disallow Any from missing imports warn_return_any = true # Warn if a function returns Any warn_unreachable = true # Warn about unreachable code warn_unused_ignores = true # Warn if a "# type: ignore" is unnecessary warn_unused_configs = true # Warn about unused config options warn_redundant_casts = true # Warn if a cast does nothing strict_equality = true # Disallow ==/!= between incompatible types # Output formatting show_error_codes = true # Show error codes in output pretty = true # Format output nicely # Exclude these paths from analysis exclude = [ '^build/', '^\\.venv/', '^\\.mypy_cache/', ] [tool.pytest.ini_options] minversion = "6.0" addopts = "-ra -q --cov=mcpgateway --ignore=tests/playwright" testpaths = [ "tests",] asyncio_mode = "auto" filterwarnings = [ "ignore:Passing 'msg' argument to .*\\.cancel\\(\\) is deprecated:DeprecationWarning", # From 3rd party libraries ] # Set environment variables for all tests env = [ "MCPGATEWAY_ADMIN_API_ENABLED=true", "MCPGATEWAY_UI_ENABLED=true" ] # ===== PLAYWRIGHT-SPECIFIC CONFIGURATIONS ===== # Playwright test markers markers = [ "slow: marks tests as slow (deselect with '-m \"not slow\"')", "ui: marks tests as UI tests", "api: marks tests as API tests", "smoke: marks tests as smoke tests for quick validation", "e2e: marks tests as end-to-end tests", ] # Playwright-specific test discovery patterns python_files = ["test_*.py", "*_test.py"] python_classes = ["Test*"] python_functions = ["test_*"] # Playwright browser configuration (can be overridden via CLI) # These are custom options that your conftest.py can read playwright_browser = "chromium" # default browser playwright_headed = false # run headless by default playwright_slow_mo = 0 # milliseconds delay between actions playwright_screenshot = "only-on-failure" playwright_video = "retain-on-failure" playwright_trace = "retain-on-failure" # ── fawltydeps ───────────────────────────────────────────────────── [tool.fawltydeps] # only parse main pyproject.toml deps = ["pyproject.toml"] # ignore 'dev' extras so they won't show up in fawltydeps ignore_unused = [ "autoflake", "argparse-manpage", "bandit", "black", "bump2version", "check-manifest", "code2flow", "cookiecutter", "coverage", "coverage-badge", "darglint", "flake8", "fawltydeps", "gprof2dot", "gunicorn", "importchecker", "isort", "ty", "tomlcheck", "mypy", "pexpect", "pip-licenses", "pip_audit", "pre-commit", "pydocstyle", "pylint", "pylint-pydantic", "pyre-check", "pyright", "pyroma", "pyspelling", "pytest", "pytest-asyncio", "pytest-cov", "pytest-examples", "pytest-md-report", "pytest-rerunfailures", "pytest-xdist", "pytype", "radon", "ruff", "settings-doc", "snakeviz", "types-tabulate", "twine", "uvicorn" ] # -------------------------------------------------------------------- # 🛠 https://github.com/facebook/pyrefly (replaces pyre) # -------------------------------------------------------------------- [tool.pyrefly] project-excludes = [ "**/build/", '**/\.venv/', '**/\.mypy_cache/', ] python-version = "3.11.0"

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/SPRIME01/MCPContextForge'

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