Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions airbyte/_util/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
import requests


_MCP_MODE_ENABLED: bool = False
"""Whether we are running in MCP (Model Context Protocol) mode."""

COLAB_SESSION_URL = "http://172.28.0.12:9000/api/sessions"
"""URL to get the current Google Colab session information."""

Expand All @@ -28,10 +31,33 @@ def get_colab_release_version() -> str | None:
return None


@lru_cache
def is_ci() -> bool:
return "CI" in os.environ


def set_mcp_mode() -> None:
"""Set flag indicating we are running in MCP (Model Context Protocol) mode.

This should be called early in MCP server initialization to ensure
proper detection and prevent interactive prompts.
"""
global _MCP_MODE_ENABLED
_MCP_MODE_ENABLED = True


def is_mcp_mode() -> bool:
"""Return True if running in MCP (Model Context Protocol) mode."""
if _MCP_MODE_ENABLED:
return True

script_name = get_python_script_name()
if script_name and "airbyte-mcp" in script_name:
return True

return "fastmcp" in sys.modules


@lru_cache
def is_langchain() -> bool:
"""Return True if running in a Langchain environment.
Expand All @@ -55,15 +81,16 @@ def is_colab() -> bool:
return bool(get_colab_release_version())


@lru_cache
def is_interactive() -> bool:
"""Return True if running in an interactive environment where we can prompt users for input."""
try:
if is_colab() or is_jupyter():
return True

if is_ci():
if is_ci() or is_mcp_mode():
return False

# No special modes detected. Return result based on whether stdin and stdout are ttys.
return bool(
sys.__stdin__ and sys.__stdin__.isatty() and sys.__stdout__ and sys.__stdout__.isatty()
)
Expand Down
1 change: 1 addition & 0 deletions airbyte/_util/telemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ def get_env_flags() -> dict[str, Any]:
flags: dict[str, bool | str] = {
"CI": meta.is_ci(),
"LANGCHAIN": meta.is_langchain(),
"MCP": meta.is_mcp_mode(),
"NOTEBOOK_RUNTIME": (
"GOOGLE_COLAB"
if meta.is_colab()
Expand Down
8 changes: 8 additions & 0 deletions airbyte/mcp/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ def _load_dotenv_file(dotenv_path: Path | str) -> None:
def initialize_secrets() -> None:
"""Initialize dotenv to load environment variables from .env files."""
# Load the .env file from the current working directory.
envrc_path = Path.cwd() / ".envrc"
if envrc_path.exists():
envrc_secret_mgr = DotenvSecretManager(envrc_path)
_load_dotenv_file(envrc_path)
register_secret_manager(
envrc_secret_mgr,
)

if AIRBYTE_MCP_DOTENV_PATH_ENVVAR in os.environ:
dotenv_path = Path(os.environ[AIRBYTE_MCP_DOTENV_PATH_ENVVAR]).absolute()
custom_dotenv_secret_mgr = DotenvSecretManager(dotenv_path)
Expand Down
2 changes: 2 additions & 0 deletions airbyte/mcp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@

from fastmcp import FastMCP

from airbyte._util.meta import set_mcp_mode
from airbyte.mcp._cloud_ops import register_cloud_ops_tools
from airbyte.mcp._connector_registry import register_connector_registry_tools
from airbyte.mcp._local_ops import register_local_ops_tools
from airbyte.mcp._util import initialize_secrets


set_mcp_mode()
initialize_secrets()

app: FastMCP = FastMCP("airbyte-mcp")
Expand Down
Loading