diff --git a/src/Service.Tests/Configuration/ConfigurationTests.cs b/src/Service.Tests/Configuration/ConfigurationTests.cs
index 65f6e6643b..4a8cdbe92d 100644
--- a/src/Service.Tests/Configuration/ConfigurationTests.cs
+++ b/src/Service.Tests/Configuration/ConfigurationTests.cs
@@ -2528,26 +2528,37 @@ public async Task TestRuntimeBaseRouteInNextLinkForPaginatedRestResponse()
/// Expected HTTP status code code for the GraphQL request
[DataTestMethod]
[TestCategory(TestCategory.MSSQL)]
- [DataRow(true, true, HttpStatusCode.OK, HttpStatusCode.OK, CONFIGURATION_ENDPOINT, DisplayName = "V1 - Both Rest and GraphQL endpoints enabled globally")]
- [DataRow(true, false, HttpStatusCode.OK, HttpStatusCode.NotFound, CONFIGURATION_ENDPOINT, DisplayName = "V1 - Rest enabled and GraphQL endpoints disabled globally")]
- [DataRow(false, true, HttpStatusCode.NotFound, HttpStatusCode.OK, CONFIGURATION_ENDPOINT, DisplayName = "V1 - Rest disabled and GraphQL endpoints enabled globally")]
- [DataRow(true, true, HttpStatusCode.OK, HttpStatusCode.OK, CONFIGURATION_ENDPOINT_V2, DisplayName = "V2 - Both Rest and GraphQL endpoints enabled globally")]
- [DataRow(true, false, HttpStatusCode.OK, HttpStatusCode.NotFound, CONFIGURATION_ENDPOINT_V2, DisplayName = "V2 - Rest enabled and GraphQL endpoints disabled globally")]
- [DataRow(false, true, HttpStatusCode.NotFound, HttpStatusCode.OK, CONFIGURATION_ENDPOINT_V2, DisplayName = "V2 - Rest disabled and GraphQL endpoints enabled globally")]
- public async Task TestGlobalFlagToEnableRestAndGraphQLForHostedAndNonHostedEnvironment(
+ [DataRow(true, true, true, HttpStatusCode.OK, HttpStatusCode.OK, HttpStatusCode.OK, CONFIGURATION_ENDPOINT, DisplayName = "V1 - Rest, GraphQL, and MCP enabled globally")]
+ [DataRow(true, true, false, HttpStatusCode.OK, HttpStatusCode.OK, HttpStatusCode.NotFound, CONFIGURATION_ENDPOINT, DisplayName = "V1 - Rest and GraphQL enabled, MCP disabled globally")]
+ [DataRow(true, false, true, HttpStatusCode.OK, HttpStatusCode.NotFound, HttpStatusCode.OK, CONFIGURATION_ENDPOINT, DisplayName = "V1 - Rest enabled, GraphQL disabled, and MCP enabled globally")]
+ [DataRow(true, false, false, HttpStatusCode.OK, HttpStatusCode.NotFound, HttpStatusCode.NotFound, CONFIGURATION_ENDPOINT, DisplayName = "V1 - Rest enabled, GraphQL and MCP enabled globally")]
+ [DataRow(false, true, true, HttpStatusCode.NotFound, HttpStatusCode.OK, HttpStatusCode.OK, CONFIGURATION_ENDPOINT, DisplayName = "V1 - Rest disabled, GraphQL and MCP enabled globally")]
+ [DataRow(false, true, false, HttpStatusCode.NotFound, HttpStatusCode.OK, HttpStatusCode.NotFound, CONFIGURATION_ENDPOINT, DisplayName = "V1 - Rest disabled, GraphQL enabled, and MCP disabled globally")]
+ [DataRow(false, false, true, HttpStatusCode.NotFound, HttpStatusCode.NotFound, HttpStatusCode.OK, CONFIGURATION_ENDPOINT, DisplayName = "V1 - Rest and GraphQL disabled, MCP enabled globally")]
+ [DataRow(true, true, true, HttpStatusCode.OK, HttpStatusCode.OK, HttpStatusCode.OK, CONFIGURATION_ENDPOINT_V2, DisplayName = "V2 - Rest, GraphQL, and MCP enabled globally")]
+ [DataRow(true, true, false, HttpStatusCode.OK, HttpStatusCode.OK, HttpStatusCode.NotFound, CONFIGURATION_ENDPOINT_V2, DisplayName = "V2 - Rest and GraphQL enabled, MCP disabled globally")]
+ [DataRow(true, false, true, HttpStatusCode.OK, HttpStatusCode.NotFound, HttpStatusCode.OK, CONFIGURATION_ENDPOINT_V2, DisplayName = "V2 - Rest enabled, GraphQL disabled, and MCP enabled globally")]
+ [DataRow(true, false, false, HttpStatusCode.OK, HttpStatusCode.NotFound, HttpStatusCode.NotFound, CONFIGURATION_ENDPOINT_V2, DisplayName = "V2 - Rest enabled, GraphQL and MCP enabled globally")]
+ [DataRow(false, true, true, HttpStatusCode.NotFound, HttpStatusCode.OK, HttpStatusCode.OK, CONFIGURATION_ENDPOINT_V2, DisplayName = "V2 - Rest disabled, GraphQL and MCP enabled globally")]
+ [DataRow(false, true, false, HttpStatusCode.NotFound, HttpStatusCode.OK, HttpStatusCode.NotFound, CONFIGURATION_ENDPOINT_V2, DisplayName = "V2 - Rest disabled, GraphQL enabled, and MCP disabled globally")]
+ [DataRow(false, false, true, HttpStatusCode.NotFound, HttpStatusCode.NotFound, HttpStatusCode.OK, CONFIGURATION_ENDPOINT_V2, DisplayName = "V2 - Rest and GraphQL disabled, MCP enabled globally")]
+ public async Task TestGlobalFlagToEnableRestGraphQLAndMcpForHostedAndNonHostedEnvironment(
bool isRestEnabled,
bool isGraphQLEnabled,
+ bool isMcpEnabled,
HttpStatusCode expectedStatusCodeForREST,
HttpStatusCode expectedStatusCodeForGraphQL,
+ HttpStatusCode expectedStatusCodeForMcp,
string configurationEndpoint)
{
GraphQLRuntimeOptions graphqlOptions = new(Enabled: isGraphQLEnabled);
RestRuntimeOptions restRuntimeOptions = new(Enabled: isRestEnabled);
+ McpRuntimeOptions mcpRuntimeOptions = new(Enabled: isMcpEnabled);
DataSource dataSource = new(DatabaseType.MSSQL,
GetConnectionStringFromEnvironmentConfig(environment: TestCategory.MSSQL), Options: null);
- RuntimeConfig configuration = InitMinimalRuntimeConfig(dataSource, graphqlOptions, restRuntimeOptions, null);
+ RuntimeConfig configuration = InitMinimalRuntimeConfig(dataSource, graphqlOptions, restRuntimeOptions, mcpRuntimeOptions);
const string CUSTOM_CONFIG = "custom-config.json";
File.WriteAllText(CUSTOM_CONFIG, configuration.ToJson());
@@ -2570,17 +2581,35 @@ public async Task TestGlobalFlagToEnableRestAndGraphQLForHostedAndNonHostedEnvir
object payload = new { query };
+ // GraphQL request
HttpRequestMessage graphQLRequest = new(HttpMethod.Post, "/graphql")
{
Content = JsonContent.Create(payload)
};
HttpResponseMessage graphQLResponse = await client.SendAsync(graphQLRequest);
- Assert.AreEqual(expectedStatusCodeForGraphQL, graphQLResponse.StatusCode);
+ Assert.AreEqual(expectedStatusCodeForGraphQL, graphQLResponse.StatusCode, "The GraphQL response is different from the expected result.");
+ // REST request
HttpRequestMessage restRequest = new(HttpMethod.Get, "/api/Book");
HttpResponseMessage restResponse = await client.SendAsync(restRequest);
- Assert.AreEqual(expectedStatusCodeForREST, restResponse.StatusCode);
+ Assert.AreEqual(expectedStatusCodeForREST, restResponse.StatusCode, "The REST response is different from the expected result.");
+
+ // MCP request
+ await Task.Delay(2000);
+ object mcpPayload = new
+ {
+ jsonrpc = "2.0",
+ id = 1,
+ method = "tools/list"
+ };
+ HttpRequestMessage mcpRequest = new(HttpMethod.Post, "/mcp")
+ {
+ Content = JsonContent.Create(mcpPayload)
+ };
+ mcpRequest.Headers.Add("Accept", "*/*");
+ HttpResponseMessage mcpResponse = await client.SendAsync(mcpRequest);
+ Assert.AreEqual(expectedStatusCodeForMcp, mcpResponse.StatusCode, "The MCP response is different from the expected result.");
}
// Hosted Scenario
@@ -2590,18 +2619,17 @@ public async Task TestGlobalFlagToEnableRestAndGraphQLForHostedAndNonHostedEnvir
{
JsonContent content = GetPostStartupConfigParams(MSSQL_ENVIRONMENT, configuration, configurationEndpoint);
- HttpResponseMessage postResult =
- await client.PostAsync(configurationEndpoint, content);
- Assert.AreEqual(HttpStatusCode.OK, postResult.StatusCode);
+ HttpResponseMessage postResult = await client.PostAsync(configurationEndpoint, content);
+ Assert.AreEqual(HttpStatusCode.OK, postResult.StatusCode, "The hydration post-response is different from the expected result.");
HttpStatusCode restResponseCode = await GetRestResponsePostConfigHydration(client);
-
- Assert.AreEqual(expected: expectedStatusCodeForREST, actual: restResponseCode);
+ Assert.AreEqual(expected: expectedStatusCodeForREST, actual: restResponseCode, "The REST hydration post-response is different from the expected result.");
HttpStatusCode graphqlResponseCode = await GetGraphQLResponsePostConfigHydration(client);
+ Assert.AreEqual(expected: expectedStatusCodeForGraphQL, actual: graphqlResponseCode, "The GraphQL hydration post-response is different from the expected result.");
- Assert.AreEqual(expected: expectedStatusCodeForGraphQL, actual: graphqlResponseCode);
-
+ HttpStatusCode mcpResponseCode = await GetMcpResponsePostConfigHydration(client);
+ Assert.AreEqual(expected: expectedStatusCodeForMcp, actual: mcpResponseCode, "The MCP hydration post-response is different from the expected result.");
}
}
@@ -5330,6 +5358,50 @@ private static async Task GetGraphQLResponsePostConfigHydration(
return responseCode;
}
+ ///
+ /// Executing MCP POST requests against the engine until a non-503 error is received.
+ ///
+ /// Client used for request execution.
+ /// ServiceUnavailable if service is not successfully hydrated with config,
+ /// else the response code from the MCP request
+ private static async Task GetMcpResponsePostConfigHydration(HttpClient httpClient)
+ {
+ // Retry request RETRY_COUNT times in 1 second increments to allow required services
+ // time to instantiate and hydrate permissions.
+ int retryCount = RETRY_COUNT;
+ HttpStatusCode responseCode = HttpStatusCode.ServiceUnavailable;
+ while (retryCount > 0)
+ {
+ // Minimal MCP request (list tools) – valid JSON-RPC request
+ await Task.Delay(2000);
+ object payload = new
+ {
+ jsonrpc = "2.0",
+ id = 1,
+ method = "tools/list"
+ };
+ HttpRequestMessage mcpRequest = new(HttpMethod.Post, "/mcp")
+ {
+ Content = JsonContent.Create(payload)
+ };
+ mcpRequest.Headers.Add("Accept", "*/*");
+
+ HttpResponseMessage mcpResponse = await httpClient.SendAsync(mcpRequest);
+ responseCode = mcpResponse.StatusCode;
+
+ if (responseCode == HttpStatusCode.ServiceUnavailable || responseCode == HttpStatusCode.NotFound)
+ {
+ retryCount--;
+ Thread.Sleep(TimeSpan.FromSeconds(RETRY_WAIT_SECONDS));
+ continue;
+ }
+
+ break;
+ }
+
+ return responseCode;
+ }
+
///
/// Helper method to instantiate RuntimeConfig object needed for multiple create tests.
///