microsoft/semantic-kernel · critical · InvalidOperationException
Please provide a valid OpenAI:ApiKey to run this sample. See
Error message
Please provide a valid OpenAI:ApiKey to run this sample. See the associated README.md for more details.
What it means
MCPServer's GetConfiguration builds config from user secrets + env vars and throws InvalidOperationException if OpenAI:ApiKey is absent. EmbeddingModelId and ChatModelId have defaults (text-embedding-3-small, gpt-4o-mini), but the API key is mandatory. The message is written to stderr first, then thrown.
Source
Thrown at dotnet/samples/Demos/ModelContextProtocolClientServer/MCPServer/Program.cs:74
await builder.Build().RunAsync();
/// <summary>
/// Gets configuration.
/// </summary>
static (string EmbeddingModelId, string ChatModelId, string ApiKey) GetConfiguration()
{
// Load and validate configuration
IConfigurationRoot config = new ConfigurationBuilder()
.AddUserSecrets<Program>()
.AddEnvironmentVariables()
.Build();
if (config["OpenAI:ApiKey"] is not { } apiKey)
{
const string Message = "Please provide a valid OpenAI:ApiKey to run this sample. See the associated README.md for more details.";
Console.Error.WriteLine(Message);
throw new InvalidOperationException(Message);
}
string embeddingModelId = config["OpenAI:EmbeddingModelId"] ?? "text-embedding-3-small";
string chatModelId = config["OpenAI:ChatModelId"] ?? "gpt-4o-mini";
return (embeddingModelId, chatModelId, apiKey);
}
static ResourceTemplateDefinition CreateVectorStoreSearchResourceTemplate(Kernel? kernel = null)
{
return new ResourceTemplateDefinition
{
Kernel = kernel,
ResourceTemplate = new()
{
UriTemplate = "vectorStore://{collection}/{prompt}",
Name = "Vector Store Record Retrieval",
Description = "Retrieves relevant records from the vector store based on the provided prompt."View on GitHub (pinned to c028a0c7dc)
Solutions
- dotnet user-secrets set OpenAI:ApiKey <key>.
- Or export OPENAI__ApiKey (and optionally OPENAI__EmbeddingModelId / OPENAI__ChatModelId) env vars.
- Verify the user-secrets ID matches this MCPServer project.
- Confirm the key is valid for the models you reference.
Example fix
// before
if (config["OpenAI:ApiKey"] is not { } apiKey)
{
const string Message = "Please provide a valid OpenAI:ApiKey to run this sample...";
Console.Error.WriteLine(Message);
throw new InvalidOperationException(Message);
}
// after (user secret)
// dotnet user-secrets set OpenAI:ApiKey sk-...
// dotnet user-secrets set OpenAI:ChatModelId gpt-4o
// dotnet user-secrets set OpenAI:EmbeddingModelId text-embedding-3-small Defensive patterns
Strategy: validation
Validate before calling
if (config["OpenAI:ApiKey"] is not { } apiKey)
throw new InvalidOperationException(
"Set OpenAI:ApiKey via user secrets or OPENAI__ApiKey env var."); Type guard
static bool HasOpenAiKey(IConfigurationRoot c) =>
!string.IsNullOrEmpty(c["OpenAI:ApiKey"]); Prevention
- Use dotnet user-secrets set OpenAI:ApiKey locally.
- Use OPENAI__ApiKey (and optional OPENAI__ChatModelId/OPENAI__EmbeddingModelId) for CI.
- Confirm the user-secrets ID matches this MCPServer project.
When it happens
Trigger: config["OpenAI:ApiKey"] is null after merging user secrets and environment variables.
Common situations: Server run without user secrets set, OPENAI__ApiKey not exported, or the user-secrets ID bound to a different assembly.
Related errors
- Please provide a valid OpenAI:ApiKey to run this sample. See
- Configuration is not setup correctly.
- Please provide valid OpenAI configuration in appsettings.Dev
- OpenAI/Azure OpenAI configuration was not found.
- Configuration section '{section}' not found
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/4887f134eb39e241.
Report an issue: GitHub.