Update McpErrorCode XML docs and fix error code usage to align with MCP spec (#1291)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
This commit is contained in:
parent
5651e9ebfe
commit
186cb93630
6 changed files with 30 additions and 17 deletions
|
|
@ -424,8 +424,8 @@ Task operations may throw <xref:ModelContextProtocol.McpException> with these er
|
||||||
|
|
||||||
| Error Code | Scenario |
|
| Error Code | Scenario |
|
||||||
|------------|----------|
|
|------------|----------|
|
||||||
| `InvalidParams` | Invalid or nonexistent task ID |
|
| `InvalidParams` | Invalid or nonexistent task ID or invalid cursor |
|
||||||
| `InvalidRequest` | Tool with `taskSupport: forbidden` called with task metadata, or tool with `taskSupport: required` called without task metadata |
|
| `InvalidParams` | Tool with `taskSupport: forbidden` called with task metadata, or tool with `taskSupport: required` called without task metadata |
|
||||||
| `InternalError` | Task execution failure or result unavailable |
|
| `InternalError` | Task execution failure or result unavailable |
|
||||||
|
|
||||||
Example error handling:
|
Example error handling:
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,19 @@ public enum McpErrorCode
|
||||||
InvalidRequest = -32600,
|
InvalidRequest = -32600,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates that the requested method does not exist or is not available on the server.
|
/// Indicates that the requested method does not exist or is not available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This error is returned when the method name specified in the request cannot be found.
|
/// <para>
|
||||||
|
/// In MCP, this error is returned when a request is made for a method that requires a capability
|
||||||
|
/// that has not been declared. This can occur in either direction:
|
||||||
|
/// </para>
|
||||||
|
/// <list type="bullet">
|
||||||
|
/// <item><description>A server returning this error when the client requests a capability it doesn't support
|
||||||
|
/// (for example, requesting completions when the <c>completions</c> capability was not advertised).</description></item>
|
||||||
|
/// <item><description>A client returning this error when the server requests a capability it doesn't support
|
||||||
|
/// (for example, requesting roots when the client did not declare the <c>roots</c> capability).</description></item>
|
||||||
|
/// </list>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
MethodNotFound = -32601,
|
MethodNotFound = -32601,
|
||||||
|
|
||||||
|
|
@ -51,15 +60,19 @@ public enum McpErrorCode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// This error is returned for protocol-level parameter issues, such as:
|
/// In MCP, this error is returned for protocol-level parameter validation failures in various contexts:
|
||||||
/// </para>
|
/// </para>
|
||||||
/// <list type="bullet">
|
/// <list type="bullet">
|
||||||
/// <item><description>Malformed requests that fail to satisfy the request schema (for example, CallToolRequest)</description></item>
|
/// <item><description><b>Tools</b>: Unknown tool name or invalid protocol-level tool arguments.</description></item>
|
||||||
/// <item><description>Unknown or unrecognized primitive names (for example, tool, prompt, or resource names)</description></item>
|
/// <item><description><b>Prompts</b>: Unknown prompt name or missing required protocol-level arguments.</description></item>
|
||||||
/// <item><description>Missing required protocol-level parameters</description></item>
|
/// <item><description><b>Pagination</b>: Invalid or expired cursor values.</description></item>
|
||||||
|
/// <item><description><b>Logging</b>: Invalid log level.</description></item>
|
||||||
|
/// <item><description><b>Tasks</b>: Invalid or nonexistent task ID or invalid cursor.</description></item>
|
||||||
|
/// <item><description><b>Elicitation</b>: Server requests an elicitation mode not declared in client capabilities.</description></item>
|
||||||
|
/// <item><description><b>Sampling</b>: Missing tool result or tool results mixed with other content.</description></item>
|
||||||
/// </list>
|
/// </list>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// Note: Input validation errors within tool/prompt/resource arguments should be reported as execution errors
|
/// Note: Application-layer validation errors within tool/prompt/resource arguments should be reported as execution errors
|
||||||
/// (for example, via <see cref="Protocol.CallToolResult.IsError"/>) rather than as protocol errors, allowing language
|
/// (for example, via <see cref="Protocol.CallToolResult.IsError"/>) rather than as protocol errors, allowing language
|
||||||
/// models to receive error feedback and self-correct.
|
/// models to receive error feedback and self-correct.
|
||||||
/// </para>
|
/// </para>
|
||||||
|
|
|
||||||
|
|
@ -591,7 +591,7 @@ internal sealed partial class McpServerImpl : McpServer
|
||||||
{
|
{
|
||||||
throw new McpProtocolException(
|
throw new McpProtocolException(
|
||||||
$"Tool '{tool.ProtocolTool.Name}' does not support task-augmented execution.",
|
$"Tool '{tool.ProtocolTool.Name}' does not support task-augmented execution.",
|
||||||
McpErrorCode.MethodNotFound);
|
McpErrorCode.InvalidParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Task augmentation requested - return CreateTaskResult
|
// Task augmentation requested - return CreateTaskResult
|
||||||
|
|
@ -604,7 +604,7 @@ internal sealed partial class McpServerImpl : McpServer
|
||||||
throw new McpProtocolException(
|
throw new McpProtocolException(
|
||||||
$"Tool '{tool.ProtocolTool.Name}' requires task-augmented execution. " +
|
$"Tool '{tool.ProtocolTool.Name}' requires task-augmented execution. " +
|
||||||
"Include a 'task' parameter with the request.",
|
"Include a 'task' parameter with the request.",
|
||||||
McpErrorCode.MethodNotFound);
|
McpErrorCode.InvalidParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal synchronous execution
|
// Normal synchronous execution
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ public class McpServerTaskAugmentedValidationTests : LoggedTest
|
||||||
TestContext.Current.CancellationToken));
|
TestContext.Current.CancellationToken));
|
||||||
|
|
||||||
Assert.Contains("does not support task-augmented execution", exception.Message, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("does not support task-augmented execution", exception.Message, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Equal(McpErrorCode.MethodNotFound, exception.ErrorCode);
|
Assert.Equal(McpErrorCode.InvalidParams, exception.ErrorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -227,7 +227,7 @@ public class McpServerTaskAugmentedValidationTests : LoggedTest
|
||||||
TestContext.Current.CancellationToken));
|
TestContext.Current.CancellationToken));
|
||||||
|
|
||||||
Assert.Contains("requires task-augmented execution", exception.Message, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("requires task-augmented execution", exception.Message, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Equal(McpErrorCode.MethodNotFound, exception.ErrorCode);
|
Assert.Equal(McpErrorCode.InvalidParams, exception.ErrorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -460,7 +460,7 @@ public class TerminalTaskStatusTransitionTests : ClientServerTestBase
|
||||||
|
|
||||||
Assert.Equal(McpTaskStatus.Completed, taskStatus.Status);
|
Assert.Equal(McpTaskStatus.Completed, taskStatus.Status);
|
||||||
|
|
||||||
// Act - Try to cancel a completed task
|
// Act - Try to cancel a completed task (should be idempotent)
|
||||||
var cancelResult = await client.CancelTaskAsync(taskId, cancellationToken: TestContext.Current.CancellationToken);
|
var cancelResult = await client.CancelTaskAsync(taskId, cancellationToken: TestContext.Current.CancellationToken);
|
||||||
|
|
||||||
// Assert - Status should still be completed (not cancelled)
|
// Assert - Status should still be completed (not cancelled)
|
||||||
|
|
@ -500,7 +500,7 @@ public class TerminalTaskStatusTransitionTests : ClientServerTestBase
|
||||||
|
|
||||||
Assert.Equal(McpTaskStatus.Failed, taskStatus.Status);
|
Assert.Equal(McpTaskStatus.Failed, taskStatus.Status);
|
||||||
|
|
||||||
// Act - Try to cancel a failed task
|
// Act - Try to cancel a failed task (should be idempotent)
|
||||||
var cancelResult = await client.CancelTaskAsync(taskId, cancellationToken: TestContext.Current.CancellationToken);
|
var cancelResult = await client.CancelTaskAsync(taskId, cancellationToken: TestContext.Current.CancellationToken);
|
||||||
|
|
||||||
// Assert - Status should still be failed
|
// Assert - Status should still be failed
|
||||||
|
|
|
||||||
|
|
@ -526,8 +526,8 @@ public class ToolTaskSupportTests : LoggedTest
|
||||||
arguments: new Dictionary<string, object?> { ["input"] = "test" },
|
arguments: new Dictionary<string, object?> { ["input"] = "test" },
|
||||||
cancellationToken: TestContext.Current.CancellationToken).AsTask());
|
cancellationToken: TestContext.Current.CancellationToken).AsTask());
|
||||||
|
|
||||||
// The server returns MethodNotFound because direct invocation is not allowed for required-task tools
|
// The server returns InvalidParams because direct invocation is not allowed for required-task tools
|
||||||
Assert.Equal(McpErrorCode.MethodNotFound, exception.ErrorCode);
|
Assert.Equal(McpErrorCode.InvalidParams, exception.ErrorCode);
|
||||||
Assert.Contains("task", exception.Message, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("task", exception.Message, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue