Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 0 additions & 5 deletions packages/agents-a365-tooling-extensions-claude/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ const toolService = new McpToolRegistrationService();
await toolService.addToolServers(
agentOptions,
process.env.AGENTIC_USER_ID || '',
process.env.MCP_ENVIRONMENT_ID || '',
app.authorization,
turnContext,
process.env.MCP_AUTH_TOKEN || ''
Expand Down Expand Up @@ -100,7 +99,6 @@ const mcpServerConfig: McpServerConfig = {
url: 'https://your-mcp-server.com',
headers: {
'Authorization': `Bearer ${authToken}`,
'x-ms-environment-id': environmentId,
}
};

Expand All @@ -118,7 +116,6 @@ The following environment variables are commonly used:
```bash
# Agent365 Authentication
AGENTIC_USER_ID=your-user-id
MCP_ENVIRONMENT_ID=your-environment-id
MCP_AUTH_TOKEN=your-auth-token

# Agent Configuration
Expand All @@ -135,7 +132,6 @@ The SDK supports multiple authentication methods:
await toolService.addToolServers(
agentOptions,
userId,
environmentId,
authorization,
turnContext,
'' // Empty auth token - will be acquired automatically
Expand All @@ -148,7 +144,6 @@ The SDK supports multiple authentication methods:
await toolService.addToolServers(
agentOptions,
userId,
environmentId,
authorization,
turnContext,
process.env.MCP_AUTH_TOKEN
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { McpToolServerConfigurationService, McpClientTool, Utility } from '@microsoft/agents-a365-tooling';

Check failure on line 4 in packages/agents-a365-tooling-extensions-claude/src/McpToolRegistrationService.ts

View workflow job for this annotation

GitHub Actions / Node.js SDK (18)

'Utility' is defined but never used. Allowed unused vars must match /^_/u

Check failure on line 4 in packages/agents-a365-tooling-extensions-claude/src/McpToolRegistrationService.ts

View workflow job for this annotation

GitHub Actions / Node.js SDK (20)

'Utility' is defined but never used. Allowed unused vars must match /^_/u
import { AgenticAuthenticationService, Authorization } from '@microsoft/agents-a365-runtime';

import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
Expand All @@ -20,12 +20,11 @@

/**
* Registers MCP tool servers and updates agent options with discovered tools and server configs.
* Call this to enable dynamic Claude tool access based on the current MCP environment.
* Call this to enable dynamic Claude tool access.
*/
async addToolServers(
agentOptions: Options,
agentUserId: string,
environmentId: string,
authorization: Authorization,
turnContext: TurnContext,
authToken: string
Expand All @@ -39,7 +38,7 @@
authToken = await AgenticAuthenticationService.GetAgenticUserToken(authorization, turnContext);
}

const servers = await this.configService.listToolServers(agentUserId, environmentId, authToken);
const servers = await this.configService.listToolServers(agentUserId, authToken);
const mcpServers: Record<string, McpServerConfig> = {};
const tools: McpClientTool[] = [];

Expand All @@ -50,10 +49,6 @@
headers['Authorization'] = `Bearer ${authToken}`;
}

if (Utility.GetUseEnvironmentId() && environmentId) {
headers['x-ms-environment-id'] = environmentId;
}

// Add each server to the config object
mcpServers[server.mcpServerName] = {
type: 'http',
Expand Down
5 changes: 0 additions & 5 deletions packages/agents-a365-tooling-extensions-langchain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ const mcpClientConfig = {} as ClientConfig;
const tools = await toolService.addMcpToolServers(
mcpClientConfig,
process.env.AGENTIC_USER_ID || '',
process.env.MCP_ENVIRONMENT_ID || '',
authorization,
turnContext,
process.env.MCP_AUTH_TOKEN || ''
Expand Down Expand Up @@ -123,7 +122,6 @@ const mcpServerConnection: Connection = {
url: 'https://your-mcp-server.com',
headers: {
'Authorization': `Bearer ${authToken}`,
'x-ms-environment-id': environmentId,
}
};

Expand All @@ -141,7 +139,6 @@ The following environment variables are commonly used:
```bash
# Agent365 Authentication
AGENTIC_USER_ID=your-user-id
MCP_ENVIRONMENT_ID=your-environment-id
MCP_AUTH_TOKEN=your-auth-token

# Agent Configuration
Expand All @@ -158,7 +155,6 @@ The SDK supports multiple authentication methods:
await toolService.addMcpToolServers(
mcpClientConfig,
userId,
environmentId,
authorization,
turnContext,
'' // Empty auth token - will be acquired automatically
Expand All @@ -171,7 +167,6 @@ The SDK supports multiple authentication methods:
await toolService.addMcpToolServers(
mcpClientConfig,
userId,
environmentId,
authorization,
turnContext,
process.env.MCP_AUTH_TOKEN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

// Agent365 SDK
import { McpToolServerConfigurationService, McpClientTool, Utility } from '@microsoft/agents-a365-tooling';

Check failure on line 5 in packages/agents-a365-tooling-extensions-langchain/src/McpToolRegistrationService.ts

View workflow job for this annotation

GitHub Actions / Node.js SDK (18)

'Utility' is defined but never used. Allowed unused vars must match /^_/u

Check failure on line 5 in packages/agents-a365-tooling-extensions-langchain/src/McpToolRegistrationService.ts

View workflow job for this annotation

GitHub Actions / Node.js SDK (20)

'Utility' is defined but never used. Allowed unused vars must match /^_/u
import { AgenticAuthenticationService, Authorization } from '@microsoft/agents-a365-runtime';

// Agents SDK
Expand All @@ -22,7 +22,6 @@
async addMcpToolServers(
mcpClientConfig: ClientConfig,
agentUserId: string,
environmentId: string,
authorization: Authorization,
turnContext: TurnContext,
authToken: string
Expand All @@ -36,7 +35,7 @@
authToken = await AgenticAuthenticationService.GetAgenticUserToken(authorization, turnContext);
}

const servers = await this.configService.listToolServers(agentUserId, environmentId, authToken);
const servers = await this.configService.listToolServers(agentUserId, authToken);
const mcpServers: Record<string, Connection> = {};

for (const server of servers) {
Expand All @@ -45,9 +44,6 @@
if (authToken) {
headers['Authorization'] = `Bearer ${authToken}`;
}
if (Utility.GetUseEnvironmentId() && environmentId) {
headers['x-ms-environment-id'] = environmentId;
}

// Create Connection instance for OpenAI agents
mcpServers[server.mcpServerName] = {
Expand Down
5 changes: 0 additions & 5 deletions packages/agents-a365-tooling-extensions-openai/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ const toolService = new McpToolRegistrationService();
await toolService.addMcpToolServers(
agent,
process.env.AGENTIC_USER_ID || '',
process.env.MCP_ENVIRONMENT_ID || '',
authorization,
turnContext,
process.env.MCP_AUTH_TOKEN || ''
Expand Down Expand Up @@ -109,7 +108,6 @@ const mcpServer = new MCPServerStreamableHttp({
requestInit: {
headers: {
'Authorization': `Bearer ${authToken}`,
'x-ms-environment-id': environmentId,
}
}
});
Expand All @@ -128,7 +126,6 @@ The following environment variables are commonly used:
```bash
# Agent365 Authentication
AGENTIC_USER_ID=your-user-id
MCP_ENVIRONMENT_ID=your-environment-id
MCP_AUTH_TOKEN=your-auth-token

# Agent Configuration
Expand All @@ -145,7 +142,6 @@ The SDK supports multiple authentication methods:
await toolService.addMcpToolServers(
agent,
userId,
environmentId,
authorization,
turnContext,
'' // Empty auth token - will be acquired automatically
Expand All @@ -158,7 +154,6 @@ The SDK supports multiple authentication methods:
await toolService.addMcpToolServers(
agent,
userId,
environmentId,
authorization,
turnContext,
process.env.MCP_AUTH_TOKEN
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { McpToolServerConfigurationService, McpClientTool, Utility } from '@microsoft/agents-a365-tooling';

Check failure on line 4 in packages/agents-a365-tooling-extensions-openai/src/McpToolRegistrationService.ts

View workflow job for this annotation

GitHub Actions / Node.js SDK (18)

'Utility' is defined but never used. Allowed unused vars must match /^_/u

Check failure on line 4 in packages/agents-a365-tooling-extensions-openai/src/McpToolRegistrationService.ts

View workflow job for this annotation

GitHub Actions / Node.js SDK (20)

'Utility' is defined but never used. Allowed unused vars must match /^_/u
import { AgenticAuthenticationService, Authorization } from '@microsoft/agents-a365-runtime';

// OpenAI Agents SDK
Expand All @@ -18,7 +18,6 @@
async addMcpToolServers(
agent: Agent,
agentUserId: string,
environmentId: string,
authorization: Authorization,
turnContext: TurnContext,
authToken: string
Expand All @@ -32,7 +31,7 @@
authToken = await AgenticAuthenticationService.GetAgenticUserToken(authorization, turnContext);
}

const servers = await this.configService.listToolServers(agentUserId, environmentId, authToken);
const servers = await this.configService.listToolServers(agentUserId, authToken);
const mcpServers: MCPServerStreamableHttp[] = [];

for (const server of servers) {
Expand All @@ -41,9 +40,6 @@
if (authToken) {
headers['Authorization'] = `Bearer ${authToken}`;
}
if (Utility.GetUseEnvironmentId() && environmentId) {
headers['x-ms-environment-id'] = environmentId;
}

// Create MCPServerStreamableHttp instance for OpenAI agents
const mcpServer = new MCPServerStreamableHttp({
Expand Down
13 changes: 5 additions & 8 deletions packages/agents-a365-tooling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The package name is **@microsoft/agents-a365-tooling**
- **Automatic Server Discovery**: Discovers MCP tool servers in development and production environments
- **Environment-Aware Configuration**: Different behavior for development vs production environments
- **Flexible Tool Server Sources**: Supports local manifest files and remote tooling gateway
- **URL Generation**: Automatically builds proper MCP server URLs for different environments
- **URL Generation**: Automatically builds proper MCP server URLs
- **Error Handling**: Comprehensive error handling and fallback mechanisms

## Core Components
Expand All @@ -30,7 +30,7 @@ Helper class for URL construction and environment detection.
import { McpToolServerConfigurationService } from '@microsoft/agents-a365-tooling';

const configService = new McpToolServerConfigurationService();
const servers = await configService.listToolServers(agentUserId, environmentId, authToken);
const servers = await configService.listToolServers(agentUserId, authToken);
```

### Understanding Tool Server Discovery
Expand Down Expand Up @@ -109,15 +109,13 @@ Create a `ToolingManifest.json` file in your project root:
For production environments, ensure you have:

1. **Valid Agent User ID**: The unique identifier for your digital worker/agent
2. **Environment ID**: Your MCP environment identifier (format: `default-[uuid]` or `uuid`)
3. **Authentication Token**: Bearer token for accessing the tooling gateway.
2. **Authentication Token**: Bearer token for accessing the tooling gateway.

```typescript
const agentUserId = process.env.AGENTIC_USER_ID || 'your-agent-user-id';
const environmentId = process.env.MCP_ENVIRONMENT_ID || 'default-your-env-id';
const authToken = process.env.MCP_AUTH_TOKEN || await getAuthToken();

const servers = await configService.listToolServers(agentUserId, environmentId, authToken);
const servers = await configService.listToolServers(agentUserId, authToken);
```

## Troubleshooting Tool Discovery
Expand All @@ -140,7 +138,7 @@ const configService = new McpToolServerConfigurationService();
console.log('Environment:', process.env.NODE_ENV);
console.log('Current working directory:', process.cwd());

const servers = await configService.listToolServers(agentUserId, environmentId, authToken);
const servers = await configService.listToolServers(agentUserId, authToken);
console.log('Discovered servers:', servers);
```

Expand All @@ -149,7 +147,6 @@ console.log('Discovered servers:', servers);
**Problem**: Generated URLs don't work or return 404 errors.

**Solutions:**
- Verify `environmentId` is correct and exists
- Check `mcpServerUniqueName` values in your manifest match available servers
- Ensure the environment's base URL is accessible

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,25 @@ export class McpToolServerConfigurationService {
}

/**
* Return MCP server definitions for the given agent and environment. In development (NODE_ENV=Development) this reads the local ToolingManifest.json; otherwise it queries the remote tooling gateway.
* Return MCP server definitions for the given agent. In development (NODE_ENV=Development) this reads the local ToolingManifest.json; otherwise it queries the remote tooling gateway.
*
* @param agentUserId The unique identifier of the digital worker/agent user for which to discover servers.
* @param environmentId The MCP environment identifier (e.g. 'default-...') used to normalize server URLs.
* @param authToken Optional bearer token used when querying the remote tooling gateway.
* @returns A promise resolving to an array of normalized MCP server configuration objects.
*/
async listToolServers(agentUserId: string, environmentId: string, authToken: string): Promise<MCPServerConfig[]> {
return await (this.isDevScenario() ? this.getMCPServerConfigsFromManifest(environmentId) : this.getMCPServerConfigsFromToolingGateway(agentUserId, environmentId, authToken));
async listToolServers(agentUserId: string, authToken: string): Promise<MCPServerConfig[]> {
return await (this.isDevScenario() ? this.getMCPServerConfigsFromManifest() : this.getMCPServerConfigsFromToolingGateway(agentUserId, authToken));
}

/**
* Query the tooling gateway for MCP servers for the specified agent and normalize each entry's mcpServerUniqueName into a full URL using Utility.BuildMcpServerUrl.
* Throws an error if the gateway call fails.
*
* @param agentId The digital worker/agent id used by the tooling gateway to scope results.
* @param environmentId The MCP environment id used to build normalized MCP server URLs.
* @param authToken Optional Bearer token to include in the Authorization header when calling the gateway.
* @throws Error when the gateway call fails or returns an unexpected payload.
*/
private async getMCPServerConfigsFromToolingGateway(agentUserId: string, environmentId: string, authToken: string): Promise<MCPServerConfig[]> {
private async getMCPServerConfigsFromToolingGateway(agentUserId: string, authToken: string): Promise<MCPServerConfig[]> {
const configEndpoint = Utility.GetToolingGatewayForDigitalWorker(agentUserId);

try {
Expand All @@ -47,7 +45,6 @@ export class McpToolServerConfigurationService {
{
headers: {
'Authorization': authToken ? `Bearer ${authToken}` : undefined,
'x-ms-environment-id': Utility.GetUseEnvironmentId() ? environmentId : undefined,
},
timeout: 10000 // 10 seconds timeout
}
Expand Down Expand Up @@ -81,7 +78,7 @@ export class McpToolServerConfigurationService {
* ]
* }
*/
private async getMCPServerConfigsFromManifest(environmentId: string): Promise<MCPServerConfig[]> {
private async getMCPServerConfigsFromManifest(): Promise<MCPServerConfig[]> {
let manifestPath = path.join(process.cwd(), 'ToolingManifest.json');
if (!fs.existsSync(manifestPath)) {
this.logger.warn(`ToolingManifest.json not found at ${manifestPath}, checking argv[1] location.`);
Expand All @@ -101,7 +98,7 @@ export class McpToolServerConfigurationService {
return mcpServers.map((s: MCPServerConfig) => {
return {
mcpServerName: s.mcpServerName,
url: Utility.BuildMcpServerUrl(environmentId, s.mcpServerName)
url: Utility.BuildMcpServerUrl(s.mcpServerName)
};
});
} catch (err: unknown) {
Expand Down
36 changes: 5 additions & 31 deletions packages/agents-a365-tooling/src/Utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,36 +38,22 @@ export class Utility {
}
}

if (!this.GetUseEnvironmentId()) {
return `${this.getMcpPlatformBaseUrl()}/agents/servers`;
}

return `${this.getMcpPlatformBaseUrl()}/mcp/environments`;
return `${this.getMcpPlatformBaseUrl()}/agents/servers`;
}

/**
* Build the full URL for accessing a specific MCP server in a given environment.
* This appends the environment id and server name to the base MCP environments URL.
* Build the full URL for accessing a specific MCP server.
*
* Example:
* Utility.BuildMcpServerUrl('default-abc', 'MyServer')
* // => "https://agent365.svc.cloud.microsoft/mcp/environments/default-abc/servers/MyServer/"
* // => "https://agent365.svc.cloud.microsoft/agents/servers/MyServer/"
Comment thread
joratz marked this conversation as resolved.
*
* @param environmentId - The environment identifier (for example 'default-...').
* @param serverName - The MCP server resource name.
* @returns The fully-qualified MCP server URL including trailing slash.
*/
public static BuildMcpServerUrl(environmentId: string, serverName: string) : string {
public static BuildMcpServerUrl(serverName: string) : string {
const baseUrl = this.GetMcpBaseUrl();
if (
!this.GetUseEnvironmentId() ||
(this.getCurrentEnvironment().toLowerCase() === 'development' &&
baseUrl.endsWith('servers'))
) {
return `${baseUrl}/${serverName}`;
} else {
return `${baseUrl}/${environmentId}/servers/${serverName}`;
}
return `${baseUrl}/${serverName}`;
}

public static GetToolsMode(): ToolsMode {
Expand Down Expand Up @@ -106,16 +92,4 @@ export class Utility {

return MCP_PLATFORM_PROD_BASE_URL;
}

/**
* Determines whether to use the environment ID in MCP server URLs.
* Reads the USE_ENVIRONMENT_ID environment variable (case-insensitive).
* If not set, defaults to 'true'.
*
* @returns {boolean} True if environment ID should be used in URLs; otherwise, false.
*/
public static GetUseEnvironmentId(): boolean {
const useEnvId = process.env.USE_ENVIRONMENT_ID || 'true';
return useEnvId.toLowerCase() === 'true';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# Mock MCP Server
TOOLS_MODE=MockMCPServer
MCP_AUTH_TOKEN=
MCP_ENVIRONMENT_ID=

# Agent365 Authentication Configuration
AGENT_APPLICATION_ID=
Expand Down
5 changes: 1 addition & 4 deletions tests-agent/openai-agent-auto-instrument-sample/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,7 @@ If you'd like to use Agentic authentication, you should set the values under Age
Otherwise, you can set the value `MCP_AUTH_TOKEN` to authentication against your MCP servers.

`NODE_ENV` should be set to `Development` if you'd like to use your tooling manifest. Otherwise, the tooling sdk will
default to retrieving MCP servers from the agent's tooling gateway, in which case you will need to set `AGENTIC_USER_ID`
and `MCP_ENVIRONMENT_ID`.

**Note** If you are using servers from the MCPPlatform but don't want to use the tooling gateway, you only need to set `MCP_ENVIRONMENT_ID`.
default to retrieving MCP servers from the agent's tooling gateway, in which case you will need to set `AGENTIC_USER_ID`.

### Interacting with your Agent
Start the agent application:
Expand Down
Loading
Loading