Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ async def main():
chat_client=chat_client,
agent_instructions="You are a helpful assistant that can provide weather and restaurant information.",
initial_tools=[], # Your existing tools
agent_user_id="user-123",
agentic_app_id="user-123",
environment_id="prod",
auth_token="your-auth-token"
)
Expand Down Expand Up @@ -139,7 +139,7 @@ async def main():
loaded from configured servers. Use these tools to enhance your capabilities.
""",
initial_tools=existing_tools,
agent_user_id="user-123",
agentic_app_id="user-123",
environment_id="production",
auth_token="your-auth-token"
)
Expand Down Expand Up @@ -190,7 +190,7 @@ agent = await service.add_tool_servers_to_agent(
chat_client=chat_client,
agent_instructions="You are a helpful assistant with access to various tools.",
initial_tools=[], # Your existing tools
agent_user_id="user-123",
agentic_app_id="user-123",
environment_id="prod",
auth_token="your-token"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ async def add_tool_servers_to_agent(
chat_client: Union[OpenAIChatClient, AzureOpenAIChatClient],
agent_instructions: str,
initial_tools: List[Any],
agent_user_id: str,
agentic_app_id: str,
environment_id: str,
auth: Optional[Authorization] = None,
auth_token: Optional[str] = None,
Expand All @@ -54,7 +54,7 @@ async def add_tool_servers_to_agent(
chat_client: The chat client instance (Union[OpenAIChatClient, AzureOpenAIChatClient])
agent_instructions: Instructions for the agent behavior
initial_tools: List of initial tools to add to the agent
agent_user_id: Unique identifier for the agent user
agentic_app_id: Agentic app identifier for the agent
environment_id: Environment identifier for MCP server discovery
auth: Optional authorization context
auth_token: Optional bearer token for authentication
Expand All @@ -65,12 +65,12 @@ async def add_tool_servers_to_agent(
"""
try:
self._logger.info(
f"Listing MCP tool servers for agent {agent_user_id} in environment {environment_id}"
f"Listing MCP tool servers for agent {agentic_app_id} in environment {environment_id}"
)

# Get MCP server configurations
server_configs = await self._mcp_server_configuration_service.list_tool_servers(
agent_user_id=agent_user_id,
agentic_app_id=agentic_app_id,
environment_id=environment_id,
auth_token=auth_token,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from azure.ai.agents.models import McpTool, ToolResources
from microsoft_agents.hosting.core import Authorization, TurnContext

from ...common.utils.utility import get_ppapi_token_scope, get_use_environment_id
from ...common.utils.utility import get_mcp_platform_authentication_scope, get_use_environment_id

# Local imports
from microsoft_kairo.tooling.common.services.mcp_tool_server_configuration_service import (
Expand Down Expand Up @@ -72,7 +72,7 @@ def __init__(
async def add_tool_servers_to_agent(
self,
project_client: "AIProjectClient",
agent_user_id: str,
agentic_app_id: str,
environment_id: str,
auth: Authorization,
context: TurnContext,
Expand All @@ -83,7 +83,7 @@ async def add_tool_servers_to_agent(

Args:
project_client: The Azure Foundry AIProjectClient instance.
agent_user_id: Agent User ID for the agent.
agentic_app_id: Agentic App ID for the agent.
environment_id: Environment ID for the environment.
auth_token: Authentication token to access the MCP servers.

Expand All @@ -95,19 +95,19 @@ async def add_tool_servers_to_agent(
raise ValueError("project_client cannot be None")

if not auth_token:
scopes = get_ppapi_token_scope()
scopes = get_mcp_platform_authentication_scope()
authToken = await auth.exchange_token(context, scopes, "AGENTIC")
auth_token = authToken.token

try:
# Get the tool definitions and resources using the async implementation
tool_definitions, tool_resources = await self._get_mcp_tool_definitions_and_resources(
agent_user_id, environment_id, auth_token or ""
agentic_app_id, environment_id, auth_token or ""
)

# Update the agent with the tools
project_client.agents.update_agent(
agent_user_id, tools=tool_definitions, tool_resources=tool_resources
agentic_app_id, tools=tool_definitions, tool_resources=tool_resources
)

self._logger.info(
Expand All @@ -116,20 +116,20 @@ async def add_tool_servers_to_agent(

except Exception as ex:
self._logger.error(
f"Unhandled failure during MCP tool registration workflow for agent user {agent_user_id}: {ex}"
f"Unhandled failure during MCP tool registration workflow for agent user {agentic_app_id}: {ex}"
)
raise

async def _get_mcp_tool_definitions_and_resources(
self, agent_user_id: str, environment_id: str, auth_token: str
self, agentic_app_id: str, environment_id: str, auth_token: str
) -> Tuple[List[McpTool], Optional[ToolResources]]:
"""
Internal method to get MCP tool definitions and resources.

This implements the core logic equivalent to the C# method of the same name.

Args:
agent_user_id: Agent User ID for the agent.
agentic_app_id: Agentic App ID for the agent.
environment_id: Environment ID for the environment.
auth_token: Authentication token to access the MCP servers.

Expand All @@ -143,17 +143,17 @@ async def _get_mcp_tool_definitions_and_resources(
# Get MCP server configurations
try:
servers = await self._mcp_server_configuration_service.list_tool_servers(
agent_user_id, environment_id, auth_token
agentic_app_id, environment_id, auth_token
)
except Exception as ex:
self._logger.error(
f"Failed to list MCP tool servers for AgentUserId={agent_user_id}: {ex}"
f"Failed to list MCP tool servers for AgenticAppId={agentic_app_id}: {ex}"
)
return ([], None)

if len(servers) == 0:
self._logger.info(
f"No MCP servers configured for AgentUserId={agent_user_id}, EnvironmentId={environment_id}"
f"No MCP servers configured for AgenticAppId={agentic_app_id}, EnvironmentId={environment_id}"
)
return ([], None)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ registration_service = McpToolRegistrationService()
# Add MCP tool servers to your OpenAI agent
await registration_service.add_tool_servers_to_agent(
agent=your_openai_agent,
agent_user_id="user-123",
agentic_app_id="user-123",
environment_id="prod",
auth=authorization_context,
context=turn_context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
)

from microsoft_agents_a365.tooling.utils.utility import (
get_ppapi_token_scope,
get_mcp_platform_authentication_scope,
get_use_environment_id,
)

Expand Down Expand Up @@ -51,7 +51,7 @@ def __init__(self, logger: Optional[logging.Logger] = None):
async def add_tool_servers_to_agent(
self,
agent: Agent,
agent_user_id: str,
agentic_app_id: str,
environment_id: str,
auth: Authorization,
context: TurnContext,
Expand All @@ -66,7 +66,7 @@ async def add_tool_servers_to_agent(

Args:
agent: The existing agent to add servers to
agent_user_id: Agent User ID for the agent
agentic_app_id: Agentic App ID for the agent
environment_id: Environment ID for the environment
auth_token: Authentication token to access the MCP servers

Expand All @@ -75,18 +75,20 @@ async def add_tool_servers_to_agent(
"""

if not auth_token:
scopes = get_ppapi_token_scope()
scopes = get_mcp_platform_authentication_scope()
authToken = await auth.exchange_token(context, scopes, "AGENTIC")
auth_token = authToken.token

# Get MCP server configurations from the configuration service
# mcp_server_configs = []
# TODO: radevika: Update once the common project is merged.
self._logger.info(
f"Listing MCP tool servers for agent {agent_user_id} in environment {environment_id}"
f"Listing MCP tool servers for agent {agentic_app_id} in environment {environment_id}"
)
mcp_server_configs = await self.config_service.list_tool_servers(
agent_user_id=agent_user_id, environment_id=environment_id, auth_token=auth_token
agentic_app_id=agentic_app_id,
environment_id=environment_id,
auth_token=auth_token,
)

self._logger.info(f"Loaded {len(mcp_server_configs)} MCP server configurations")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ registration_service = McpToolRegistrationService()
# Add MCP tool servers to your Semantic Kernel
await registration_service.add_tool_servers_to_kernel(
kernel=kernel,
agent_user_id="user-123",
agentic_app_id="user-123",
environment_id="prod",
auth_token="your-auth-token"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
)
from ...common.models import MCPServerConfig
from ...common.utils.constants import Constants
from ...common.utils.utility import get_tools_mode, get_ppapi_token_scope, get_use_environment_id
from ...common.utils.utility import (
get_tools_mode,
get_mcp_platform_authentication_scope,
get_use_environment_id,
)


from semantic_kernel.connectors.mcp import MCPStreamableHttpPlugin
Expand Down Expand Up @@ -80,7 +84,7 @@ def __init__(
async def add_tool_servers_to_agent(
self,
kernel: sk.Kernel,
agent_user_id: str,
agentic_app_id: str,
environment_id: str,
auth: Authorization,
context: TurnContext,
Expand All @@ -91,7 +95,7 @@ async def add_tool_servers_to_agent(

Args:
kernel: The Semantic Kernel instance to which the tools will be added.
agent_user_id: Agent User ID for the agent.
agentic_app_id: Agentic App ID for the agent.
environment_id: Environment ID for the environment.
auth_token: Authentication token to access the MCP servers.

Expand All @@ -101,15 +105,15 @@ async def add_tool_servers_to_agent(
"""

if not auth_token:
scopes = get_ppapi_token_scope()
scopes = get_mcp_platform_authentication_scope()
authToken = await auth.exchange_token(context, scopes, "AGENTIC")
auth_token = authToken.token

self._validate_inputs(kernel, agent_user_id, environment_id, auth_token)
self._validate_inputs(kernel, agentic_app_id, environment_id, auth_token)

# Get and process servers
servers = await self._mcp_server_configuration_service.list_tool_servers(
agent_user_id, environment_id, auth_token
agentic_app_id, environment_id, auth_token
)
self._logger.info(f"🔧 Adding MCP tools from {len(servers)} servers")

Expand Down Expand Up @@ -174,13 +178,13 @@ async def add_tool_servers_to_agent(
# ============================================================================

def _validate_inputs(
self, kernel: Any, agent_user_id: str, environment_id: str, auth_token: str
self, kernel: Any, agentic_app_id: str, environment_id: str, auth_token: str
) -> None:
"""Validate all required inputs."""
if kernel is None:
raise ValueError("kernel cannot be None")
if not agent_user_id or not agent_user_id.strip():
raise ValueError("agent_user_id cannot be null or empty")
if not agentic_app_id or not agentic_app_id.strip():
raise ValueError("agentic_app_id cannot be null or empty")
if not environment_id or not environment_id.strip():
raise ValueError("environment_id cannot be null or empty")
if not auth_token or not auth_token.strip():
Expand Down
2 changes: 1 addition & 1 deletion libraries/microsoft-agents-a365-tooling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ mcp_config = MCPServerConfig(
# Use configuration service to list available MCP servers
config_service = McpToolServerConfigurationService()
mcp_servers = await config_service.list_tool_servers(
agent_user_id="agent-123",
agentic_app_id="agent-123",
environment_id="prod",
auth_token="your-auth-token"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ def __init__(self, logger: Optional[logging.Logger] = None):
# --------------------------------------------------------------------------

async def list_tool_servers(
self, agent_user_id: str, environment_id: str, auth_token: str
self, agentic_app_id: str, environment_id: str, auth_token: str
) -> List[MCPServerConfig]:
"""
Gets the list of MCP Servers that are configured for the agent.

Args:
agent_user_id: Agent User ID for the agent.
agentic_app_id: Agentic App ID for the agent.
environment_id: Environment ID for the environment.
auth_token: Authentication token to access the MCP servers.

Expand All @@ -88,17 +88,17 @@ async def list_tool_servers(
Exception: If there's an error communicating with the tooling gateway.
"""
# Validate input parameters
self._validate_input_parameters(agent_user_id, environment_id, auth_token)
self._validate_input_parameters(agentic_app_id, environment_id, auth_token)

self._logger.info(
f"Listing MCP tool servers for agent {agent_user_id} in environment {environment_id}"
f"Listing MCP tool servers for agent {agentic_app_id} in environment {environment_id}"
)

# Determine configuration source based on environment
if self._is_development_scenario():
return self._load_servers_from_manifest(environment_id)
else:
return await self._load_servers_from_gateway(agent_user_id, environment_id, auth_token)
return await self._load_servers_from_gateway(agentic_app_id, environment_id, auth_token)

# --------------------------------------------------------------------------
# ENVIRONMENT DETECTION
Expand Down Expand Up @@ -290,13 +290,13 @@ def _log_manifest_search_failure(self) -> None:
# --------------------------------------------------------------------------

async def _load_servers_from_gateway(
self, agent_user_id: str, environment_id: str, auth_token: str
self, agentic_app_id: str, environment_id: str, auth_token: str
) -> List[MCPServerConfig]:
"""
Reads MCP server configurations from tooling gateway endpoint for production scenario.

Args:
agent_user_id: Agent User ID for the agent.
agentic_app_id: Agentic App ID for the agent.
environment_id: Environment ID for the environment.
auth_token: Authentication token to access the tooling gateway.

Expand All @@ -309,7 +309,7 @@ async def _load_servers_from_gateway(
mcp_servers: List[MCPServerConfig] = []

try:
config_endpoint = get_tooling_gateway_for_digital_worker(agent_user_id)
config_endpoint = get_tooling_gateway_for_digital_worker(agentic_app_id)
headers = self._prepare_gateway_headers(auth_token, environment_id)

self._logger.info(f"Calling tooling gateway endpoint: {config_endpoint}")
Expand Down Expand Up @@ -445,21 +445,21 @@ def _parse_gateway_server_config(
# --------------------------------------------------------------------------

def _validate_input_parameters(
self, agent_user_id: str, environment_id: str, auth_token: str
self, agentic_app_id: str, environment_id: str, auth_token: str
) -> None:
"""
Validates input parameters for the main API method.

Args:
agent_user_id: Agent User ID to validate.
agentic_app_id: Agentic App ID to validate.
environment_id: Environment ID to validate.
auth_token: Authentication token to validate.

Raises:
ValueError: If any parameter is invalid or empty.
"""
if not agent_user_id:
raise ValueError("agent_user_id cannot be empty or None")
if not agentic_app_id:
raise ValueError("agentic_app_id cannot be empty or None")
if not environment_id:
raise ValueError("environment_id cannot be empty or None")
if not auth_token:
Expand Down
Loading
Loading