Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
80bdb75
add ai core tool
g2vinay Aug 19, 2025
f94d05d
add ai core tool
g2vinay Aug 21, 2025
ea6a2c2
Merge remote-tracking branch 'azure-mcp-src/add-openai-completions-cr…
g2vinay Aug 26, 2025
050c9bd
fix build issues
g2vinay Aug 27, 2025
996cf8e
update live tests
g2vinay Aug 27, 2025
4133cf7
register ai namespace
g2vinay Aug 28, 2025
22ba446
update tests and options config
g2vinay Aug 29, 2025
a9643a7
enable AOT compatibility
g2vinay Aug 29, 2025
6c1e60c
Merge branch 'main' of https://github.com/microsoft/mcp into ai-names…
g2vinay Aug 29, 2025
36fe2d4
Merge remote-tracking branch 'upstream/main' into ai-namespace-init
g2vinay Sep 17, 2025
de01065
move the tool under foundry namespace
g2vinay Sep 17, 2025
a44a8ad
address feedback
g2vinay Sep 17, 2025
2a4eb5b
update live test config
g2vinay Sep 18, 2025
0c6bef6
update live tests
g2vinay Sep 19, 2025
39e428b
Merge remote-tracking branch 'upstream/main' into ai-namespace-init
g2vinay Sep 23, 2025
f67f581
fix formatting + post deployment script
g2vinay Sep 23, 2025
845400a
add cast to tests
g2vinay Sep 23, 2025
71663a3
fix post script
g2vinay Sep 23, 2025
da24062
fix post script
g2vinay Sep 23, 2025
333a1b3
test post script change
g2vinay Sep 23, 2025
0f31caa
Merge branch 'main' of https://github.com/microsoft/mcp into ai-names…
g2vinay Sep 25, 2025
af9155b
update quota
g2vinay Sep 25, 2025
0ed7563
fix types
g2vinay Sep 25, 2025
e7e39b0
update post script
g2vinay Sep 25, 2025
3c3bd98
update bicep
g2vinay Sep 25, 2025
a29ab56
update flow
g2vinay Sep 25, 2025
15407c6
update bicep
g2vinay Sep 26, 2025
c310c95
update bicep
g2vinay Sep 26, 2025
5451772
add entra auth
g2vinay Sep 26, 2025
32ab53d
update unit tests:
g2vinay Sep 26, 2025
9977cb5
update docs
g2vinay Sep 26, 2025
4ca6cc3
Merge remote-tracking branch 'upstream/main' into ai-namespace-init
g2vinay Sep 26, 2025
2b5f866
update changelog
g2vinay Sep 26, 2025
f3b259e
Test update
g2vinay Sep 26, 2025
c0a92cc
format fix
g2vinay Sep 26, 2025
0877031
address feedback
g2vinay Sep 29, 2025
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
9 changes: 9 additions & 0 deletions docs/azmcp-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,15 @@ azmcp foundry models list [--search-for-free-playground <search-for-free-playgro
[--publisher <publisher>] \
[--license <license>] \
[--model-name <model>]

# Generate text completions using deployed Azure OpenAI models in AI Foundry
azmcp foundry openai create-completion --subscription <subscription> \
--resource-group <resource-group> \
--resource-name <resource-name> \
--deployment <deployment-name> \
--prompt-text <prompt-text> \
[--max-tokens <max-tokens>] \
[--temperature <temperature>]
```

### Azure AI Search Operations
Expand Down
1 change: 1 addition & 0 deletions docs/e2eTestPrompts.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ This file contains prompts used for end-to-end testing to ensure each tool is in
| azmcp_foundry_models_deployments_list | Show me all AI Foundry model deployments |
| azmcp_foundry_models_list | List all AI Foundry models |
| azmcp_foundry_models_list | Show me the available AI Foundry models |
| azmcp_foundry_openai_create-completion | Create a completion with the prompt "What is Azure?"|

## Azure AI Search

Expand Down
6 changes: 6 additions & 0 deletions eng/scripts/helpers/TestResourcesHelpers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ function New-TestSettings {
[string] $TestApplicationId,
[string] $ResourceGroupName,
[string] $BaseName,
[hashtable] $DeploymentOutputs,
[string] $OutputPath
)

Expand Down Expand Up @@ -52,6 +53,11 @@ function New-TestSettings {
ResourceBaseName = $BaseName
}

# Add DeploymentOutputs if provided
if($DeploymentOutputs -and $DeploymentOutputs.Count -gt 0) {
$testSettings.DeploymentOutputs = $DeploymentOutputs
}

if($OutputPath) {
if(Test-Path -Path $OutputPath -PathType Container) {
$OutputPath = Join-Path -Path $OutputPath -ChildPath ".testsettings.json"
Expand Down
3 changes: 3 additions & 0 deletions servers/Azure.Mcp.Server/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ The Azure MCP Server updates automatically by default whenever a new release com

- Adds support to proxy MCP capabilities when child servers leverage sampling or elicitation. [[#581](https://github.com/microsoft/mcp/pull/581)]
- Added support for publishing custom events to Event Grid topics via the command `azmcp_eventgrid_events_publish`. Supports EventGrid, CloudEvents, and custom schemas with structured event data delivery for event-driven architectures. [[#514](https://github.com/microsoft/mcp/pull/514)]
- `azmcp foundry openai create-completion` - Generate text completions using deployed Azure OpenAI models in AI Foundry. [[#54](https://github.com/microsoft/mcp/pull/54)]
- Supports configurable temperature and max token parameters
- Requires resource-name, deployment-name, and prompt-text parameters

### Breaking Changes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<ItemGroup>
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.ResourceManager" />
<PackageReference Include="Azure.ResourceManager.CognitiveServices" />
<PackageReference Include="Azure.AI.Agents.Persistent" />
<PackageReference Include="Azure.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System.Text.Json.Serialization;
using Azure.Mcp.Tools.Foundry.Commands;
using Azure.Mcp.Tools.Foundry.Models;
using Azure.Mcp.Tools.Foundry.Services.Models;
using Microsoft.Extensions.AI;
Expand All @@ -16,6 +17,7 @@ namespace Azure.Mcp.Tools.Foundry.Commands;
[JsonSerializable(typeof(AgentsConnectCommand.AgentsConnectCommandResult))]
[JsonSerializable(typeof(KnowledgeIndexListCommand.KnowledgeIndexListCommandResult))]
[JsonSerializable(typeof(KnowledgeIndexSchemaCommand.KnowledgeIndexSchemaCommandResult))]
[JsonSerializable(typeof(OpenAiCompletionsCreateCommand.OpenAiCompletionsCreateCommandResult))]
[JsonSerializable(typeof(JsonElement))]
[JsonSerializable(typeof(ModelCatalogFilter))]
[JsonSerializable(typeof(ModelCatalogRequest))]
Expand All @@ -25,6 +27,8 @@ namespace Azure.Mcp.Tools.Foundry.Commands;
[JsonSerializable(typeof(ModelDeploymentResult))]
[JsonSerializable(typeof(KnowledgeIndexInformation))]
[JsonSerializable(typeof(KnowledgeIndexSchema))]
[JsonSerializable(typeof(CompletionResult))]
[JsonSerializable(typeof(CompletionUsageInfo))]
[JsonSerializable(typeof(CognitiveServicesSku))]
[JsonSerializable(typeof(CognitiveServicesAccountDeploymentProperties))]
[JsonSerializable(typeof(AgentsQueryAndEvaluateCommand.AgentsQueryAndEvaluateCommandResult))]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Azure.Mcp.Core.Commands;
using Azure.Mcp.Core.Commands.Subscription;
using Azure.Mcp.Core.Models;
using Azure.Mcp.Core.Models.Option;
using Azure.Mcp.Tools.Foundry.Models;
using Azure.Mcp.Tools.Foundry.Options;
using Azure.Mcp.Tools.Foundry.Options.Models;
using Azure.Mcp.Tools.Foundry.Services;

namespace Azure.Mcp.Tools.Foundry.Commands;

public sealed class OpenAiCompletionsCreateCommand : SubscriptionCommand<OpenAiCompletionsCreateOptions>
{
private const string CommandTitle = "Create OpenAI Completion";

public override string Name => "create-completion";

public override string Description =>
$"""
Generate text completions using deployed Azure OpenAI models in AI Foundry. This tool sends prompts to Azure OpenAI
completion models and returns generated text with configurable parameters like temperature and max tokens.
Returns completion text as JSON. Requires resource-name, deployment-name, and prompt-text.
""";

public override string Title => CommandTitle;

public override ToolMetadata Metadata => new()
{
Destructive = false,
Idempotent = false,
OpenWorld = false,
ReadOnly = true,
LocalRequired = false,
Secret = false
};

protected override void RegisterOptions(Command command)
{
base.RegisterOptions(command);
command.Options.Add(OptionDefinitions.Common.ResourceGroup.AsRequired());
command.Options.Add(FoundryOptionDefinitions.ResourceNameOption);
command.Options.Add(FoundryOptionDefinitions.DeploymentNameOption);
command.Options.Add(FoundryOptionDefinitions.PromptTextOption);
command.Options.Add(FoundryOptionDefinitions.MaxTokensOption);
command.Options.Add(FoundryOptionDefinitions.TemperatureOption);
}

protected override OpenAiCompletionsCreateOptions BindOptions(ParseResult parseResult)
{
var options = base.BindOptions(parseResult);
options.ResourceGroup ??= parseResult.GetValueOrDefault<string>(OptionDefinitions.Common.ResourceGroup.Name);
options.ResourceName = parseResult.GetValueOrDefault<string>(FoundryOptionDefinitions.ResourceNameOption.Name);
options.DeploymentName = parseResult.GetValueOrDefault<string>(FoundryOptionDefinitions.DeploymentNameOption.Name);
options.PromptText = parseResult.GetValueOrDefault<string>(FoundryOptionDefinitions.PromptTextOption.Name);
options.MaxTokens = parseResult.GetValueOrDefault<int?>(FoundryOptionDefinitions.MaxTokensOption.Name);
options.Temperature = parseResult.GetValueOrDefault<double?>(FoundryOptionDefinitions.TemperatureOption.Name);
return options;
}

public override async Task<CommandResponse> ExecuteAsync(CommandContext context, ParseResult parseResult)
{
try
{
if (!Validate(parseResult.CommandResult, context.Response).IsValid)
{
return context.Response;
}

var options = BindOptions(parseResult);

var foundryService = context.GetService<IFoundryService>();
var result = await foundryService.CreateCompletionAsync(
options.ResourceName!,
options.DeploymentName!,
options.PromptText!,
options.Subscription!,
options.ResourceGroup!,
options.MaxTokens,
options.Temperature,
options.Tenant,
options.AuthMethod ?? AuthMethod.Credential,
options.RetryPolicy);

context.Response.Results = ResponseResult.Create<OpenAiCompletionsCreateCommandResult>(
new OpenAiCompletionsCreateCommandResult(result.CompletionText, result.UsageInfo),
FoundryJsonContext.Default.OpenAiCompletionsCreateCommandResult);
}
catch (Exception ex)
{
HandleException(context, ex);
}

return context.Response;
}

internal record OpenAiCompletionsCreateCommandResult(string CompletionText, CompletionUsageInfo UsageInfo);
}
5 changes: 5 additions & 0 deletions tools/Azure.Mcp.Tools.Foundry/src/FoundrySetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using Azure.Mcp.Core.Areas;
using Azure.Mcp.Core.Commands;
using Azure.Mcp.Core.Services.Azure.Subscription;
using Azure.Mcp.Tools.Foundry.Commands;
using Azure.Mcp.Tools.Foundry.Services;
using Microsoft.Extensions.DependencyInjection;
Expand Down Expand Up @@ -60,6 +61,10 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
var indexSchema = serviceProvider.GetRequiredService<KnowledgeIndexSchemaCommand>();
index.AddCommand(indexSchema.Name, indexSchema);

var openai = new CommandGroup("openai", "Foundry OpenAI operations - Commands for working with Azure OpenAI models deployed in AI Foundry.");
foundry.AddSubGroup(openai);

openai.AddCommand("create-completion", new OpenAiCompletionsCreateCommand());
var agents = new CommandGroup("agents", "Foundry agents operations - Commands for listing, querying, and evaluating agents in AI Foundry.");
foundry.AddSubGroup(agents);

Expand Down
1 change: 1 addition & 0 deletions tools/Azure.Mcp.Tools.Foundry/src/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@

global using System.CommandLine;
global using System.Text.Json;
global using Azure.Mcp.Core.Extensions;
global using Azure.Mcp.Core.Models.Command;
15 changes: 15 additions & 0 deletions tools/Azure.Mcp.Tools.Foundry/src/Models/CompletionModels.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Text.Json.Serialization;

namespace Azure.Mcp.Tools.Foundry.Models;

public sealed record CompletionResult(
[property: JsonPropertyName("completionText")] string CompletionText,
[property: JsonPropertyName("usageInfo")] CompletionUsageInfo UsageInfo);

public sealed record CompletionUsageInfo(
[property: JsonPropertyName("promptTokens")] int PromptTokens,
[property: JsonPropertyName("completionTokens")] int CompletionTokens,
[property: JsonPropertyName("totalTokens")] int TotalTokens);
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public static class FoundryOptionDefinitions
public const string AzureOpenAIEndpoint = "azure-openai-endpoint";
public const string AzureOpenAIDeployment = "azure-openai-deployment";
public const string IndexName = "index";
public const string PromptText = "prompt-text";
public const string MaxTokens = "max-tokens";
public const string Temperature = "temperature";
public const string ResourceName = "resource-name";

public static readonly Option<string> EndpointOption = new(
$"--{Endpoint}"
Expand Down Expand Up @@ -208,4 +212,34 @@ public static class FoundryOptionDefinitions
Description = "The name of the knowledge index.",
Required = true
};

public static readonly Option<string> PromptTextOption = new(
$"--{PromptText}"
)
{
Description = "The prompt text to send to the completion model.",
Required = true
};

public static readonly Option<string> ResourceNameOption = new(
$"--{ResourceName}"
)
{
Description = "The name of the Azure OpenAI resource.",
Required = true
};

public static readonly Option<int> MaxTokensOption = new(
$"--{MaxTokens}"
)
{
Description = "The maximum number of tokens to generate in the completion."
};

public static readonly Option<double> TemperatureOption = new(
$"--{Temperature}"
)
{
Description = "Controls randomness in the output. Lower values make it more deterministic."
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Text.Json.Serialization;
using Azure.Mcp.Core.Options;

namespace Azure.Mcp.Tools.Foundry.Options.Models;

public class OpenAiCompletionsCreateOptions : SubscriptionOptions
{
[JsonPropertyName(FoundryOptionDefinitions.DeploymentName)]
public string? DeploymentName { get; set; }

[JsonPropertyName(FoundryOptionDefinitions.PromptText)]
public string? PromptText { get; set; }

[JsonPropertyName(FoundryOptionDefinitions.MaxTokens)]
public int? MaxTokens { get; set; }

[JsonPropertyName(FoundryOptionDefinitions.Temperature)]
public double? Temperature { get; set; }

[JsonPropertyName(FoundryOptionDefinitions.ResourceName)]
public string? ResourceName { get; set; }
}
Loading
Loading