Skip to content

Fix CLI arguments requiring environment variables for MCP server initialization #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
21 changes: 12 additions & 9 deletions src/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import argparse

from src import main
from src.config.server_config import McpServerConfig, init_server_config
from src.config.server_config import init_server_config


def parse_args():
Expand All @@ -27,16 +27,19 @@ def cli_main():
"""
# Parse command-line arguments
args = parse_args()

# Initialize server config with CLI arguments - this will also update the logger
init_server_config(
McpServerConfig(
port_client_id=args.client_id,
port_client_secret=args.client_secret,
region=args.region,
log_level=args.log_level,
api_validation_enabled=args.api_validation_enabled.lower() == "true",
).model_dump()
{
"port_client_id": args.client_id,
"port_client_secret": args.client_secret,
"region": args.region,
"log_level": args.log_level,
"api_validation_enabled": args.api_validation_enabled.lower() == "true",
}
)
# Call the main function with command-line arguments

# Call the main function
main()


Expand Down
10 changes: 5 additions & 5 deletions src/client/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from pyport import PortClient

from src.config import config
from src.config import get_config
from src.models.actions import Action
from src.utils import logger

Expand Down Expand Up @@ -52,7 +52,7 @@ async def get_all_actions(self, trigger_type: str = "self-service") -> list[Acti
else:
logger.debug(f"User lacks permission for action: {action_identifier}")

if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating actions")
return [Action(**action) for action in filtered_actions]
else:
Expand All @@ -65,7 +65,7 @@ async def get_action(self, action_identifier: str) -> Action:
response = self._client.make_request("GET", f"actions/{action_identifier}")
result = response.json().get("action")

if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating action")
return Action(**result)
else:
Expand All @@ -88,7 +88,7 @@ async def create_action(self, action_data: dict[str, Any]) -> Action:

result = result.get("action", {})

if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating action")
action = Action(**result)
else:
Expand All @@ -114,7 +114,7 @@ async def update_action(self, action_identifier: str, action_data: dict[str, Any
logger.info(f"Action '{action_identifier}' updated in Port")

result = result.get("action", {})
if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating action")
action = Action(**result)
else:
Expand Down
4 changes: 2 additions & 2 deletions src/client/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from pyport import PortClient

from src.config import config
from src.config import get_config
from src.models.agent.port_agent_response import PortAgentResponse, PortAgentTriggerResponse
from src.utils import logger
from src.utils.errors import PortError
Expand Down Expand Up @@ -59,7 +59,7 @@ async def get_invocation_status(self, identifier: str) -> PortAgentResponse:
if urls:
action_url = urls[0]

if config.api_validation_enabled:
if get_config().api_validation_enabled:
return PortAgentResponse(
identifier=identifier,
status=status,
Expand Down
10 changes: 5 additions & 5 deletions src/client/blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from pyport import PortClient

from src.config import config
from src.config import get_config
from src.models.blueprints import Blueprint
from src.utils import logger
from src.utils.errors import PortError
Expand All @@ -23,7 +23,7 @@ async def get_blueprints(self) -> list[Blueprint]:
logger.info("Got blueprints from Port")

logger.debug(f"Response for get blueprints: {blueprints}")
if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating blueprints")
return [Blueprint(**bp) for bp in blueprints]
else:
Expand All @@ -39,7 +39,7 @@ async def get_blueprint(self, blueprint_identifier: str) -> Blueprint:

logger.info(f"Got blueprint '{blueprint_identifier}' from Port")

if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating blueprint")
return Blueprint(**bp_data)
else:
Expand All @@ -62,7 +62,7 @@ async def create_blueprint(self, blueprint_data: dict[str, Any]) -> Blueprint:

result = result.get("blueprint", {})

if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating blueprint")
blueprint = Blueprint(**result)
else:
Expand All @@ -86,7 +86,7 @@ async def update_blueprint(self, blueprint_data: dict[str, Any]) -> Blueprint:
logger.info("Blueprint updated in Port")

result = result.get("blueprint", {})
if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating blueprint")
blueprint = Blueprint(**result)
else:
Expand Down
8 changes: 6 additions & 2 deletions src/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from src.client.entities import PortEntityClient
from src.client.permissions import PortPermissionsClient
from src.client.scorecards import PortScorecardClient
from src.config import config
from src.config import get_config
from src.models.action_run.action_run import ActionRun
from src.models.actions.action import Action
from src.models.agent import PortAgentResponse
Expand All @@ -31,11 +31,15 @@ def __init__(
client_id: str | None = None,
client_secret: str | None = None,
region: str = "EU",
base_url: str = config.port_api_base,
base_url: str | None = None,
):
if not client_id or not client_secret:
logger.warning("PortClient initialized without credentials")

# Set default base_url if not provided
if base_url is None:
base_url = get_config().port_api_base

self.base_url = base_url
self.client_id = client_id
self.client_secret = client_secret
Expand Down
12 changes: 6 additions & 6 deletions src/client/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from pyport import PortClient

from src.config import config
from src.config import get_config
from src.models.entities import EntityResult
from src.utils import PortError, logger

Expand All @@ -22,7 +22,7 @@ async def get_entities(self, blueprint_identifier: str) -> list[EntityResult]:

logger.info(f"Got {len(entities_data)} entities for blueprint '{blueprint_identifier}' from Port")
logger.debug(f"Response for get entities: {entities_data}")
if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating entities")
return [EntityResult(**entity_data) for entity_data in entities_data]
else:
Expand All @@ -37,7 +37,7 @@ async def search_entities(self, blueprint_identifier: str, search_query: dict[st

logger.info(f"Got {len(entities_data)} entities for blueprint '{blueprint_identifier}' from Port")
logger.debug(f"Response for search entities: {entities_data}")
if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating entities")
return [EntityResult(**entity_data) for entity_data in entities_data]
else:
Expand All @@ -51,7 +51,7 @@ async def get_entity(self, blueprint_identifier: str, entity_identifier: str) ->

logger.info(f"Got entity '{entity_identifier}' from blueprint '{blueprint_identifier}' from Port")
logger.debug(f"Response for get entity: {entity_data}")
if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating entity")
return EntityResult(**entity_data)
else:
Expand Down Expand Up @@ -83,7 +83,7 @@ async def create_entity(self, blueprint_identifier: str, entity_data: dict[str,
entity = created_data.get("entity", {})

logger.debug(f"Response for create entity: {entity}")
if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating entity")
return EntityResult(**entity)
else:
Expand All @@ -105,7 +105,7 @@ async def update_entity(self, blueprint_identifier: str, entity_identifier: str,
entity = updated_data.get("entity", {})
logger.debug(f"Response for update entity: {entity}")

if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating entity")
return EntityResult(**entity)
else:
Expand Down
8 changes: 4 additions & 4 deletions src/client/scorecards.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from pyport import PortClient

from src.config import config
from src.config import get_config
from src.models.scorecards import Scorecard
from src.utils import logger
from src.utils.errors import PortError
Expand All @@ -23,7 +23,7 @@ async def get_scorecards(self, blueprint_identifier: str) -> list[Scorecard]:
logger.info(f"Got {len(scorecards_data)} scorecards for blueprint '{blueprint_identifier}' from Port")
logger.debug(f"Response for get scorecards: {scorecards_data}")

if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating scorecards")
return [Scorecard(**scorecard_data) for scorecard_data in scorecards_data]
else:
Expand Down Expand Up @@ -65,7 +65,7 @@ async def create_scorecard(self, blueprint_id: str, scorecard_data: dict[str, An

logger.debug(f"Response for create scorecard: {data}")

if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating scorecard")
return Scorecard(**data)
else:
Expand Down Expand Up @@ -117,7 +117,7 @@ async def update_scorecard(self, blueprint_id: str, scorecard_id: str, scorecard

logger.debug(f"Response for update scorecard: {data}")

if config.api_validation_enabled:
if get_config().api_validation_enabled:
logger.debug("Validating scorecard")
return Scorecard(**data)
else:
Expand Down
4 changes: 2 additions & 2 deletions src/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Configuration package for Port.io MCP server."""

from .server_config import McpServerConfig, config, init_server_config
from .server_config import McpServerConfig, get_config, init_server_config

__all__ = ["McpServerConfig", "init_server_config", "config"]
__all__ = ["McpServerConfig", "init_server_config", "get_config"]
20 changes: 18 additions & 2 deletions src/config/server_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from dotenv import load_dotenv
from pydantic import BaseModel, Field, ValidationError

from src.utils import PortError, logger
from src.utils import PortError

# Load environment variables from .env file if it exists, but don't override existing env vars
load_dotenv(override=False)
Expand Down Expand Up @@ -56,6 +56,9 @@ def init_server_config(override: dict[str, Any] | None = None):
log_level=override.get("log_level", "ERROR"),
api_validation_enabled=override.get("api_validation_enabled", "false") == "true",
)
# Update logger with new config
from src.utils.logger import update_logger_with_config
update_logger_with_config(config)
return config
try:
client_id = os.environ.get("PORT_CLIENT_ID", "")
Expand All @@ -72,11 +75,24 @@ def init_server_config(override: dict[str, Any] | None = None):
log_level=cast(Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], log_level),
api_validation_enabled=api_validation_enabled,
)
# Update logger with new config
from src.utils.logger import update_logger_with_config
update_logger_with_config(config)
return config
except ValidationError as e:
message = f"❌ Error initializing server config: {e.errors()}"
# Import logger here to avoid circular dependency
from src.utils import logger
logger.error(message)
raise PortError(message) from e


config: McpServerConfig = init_server_config()
config: McpServerConfig | None = None


def get_config() -> McpServerConfig:
"""Get the global config, initializing it if necessary."""
global config
if config is None:
config = init_server_config()
return config
4 changes: 2 additions & 2 deletions src/maps/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""AI Agent related data models for Port.io."""

from .tool_map import tool_map
from .tool_map import get_tool_map

__all__ = ["tool_map"]
__all__ = ["get_tool_map"]
21 changes: 18 additions & 3 deletions src/maps/tool_map.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
from src.client import PortClient
from src.config import config
from src.config import get_config
from src.models.tools import ToolMap
from src.utils import logger


def init_tool_map() -> ToolMap:
config = get_config()
logger.info(f"Initializing tool map with config region: {config.region}")
logger.debug(f"Client ID available: {bool(config.port_client_id)}")
logger.debug(f"Client secret available: {bool(config.port_client_secret)}")

port_client = PortClient(
client_id=config.port_client_id,
client_secret=config.port_client_secret,
region=config.region,
)
logger.info("PortClient created successfully")

tool_map = ToolMap(port_client=port_client)
logger.info("Initialized tool map")
logger.info("Tool map created, initializing tools...")
logger.debug(f"Tool map: {tool_map}")
return tool_map


tool_map: ToolMap = init_tool_map()
tool_map: ToolMap | None = None


def get_tool_map() -> ToolMap:
"""Get the global tool map, initializing it if necessary."""
global tool_map
if tool_map is None:
tool_map = init_tool_map()
return tool_map
Loading
Loading