Skip to content

MCP client converted into semantic kernel tools doesn't handle complex argument objects #368

@Vifill

Description

@Vifill

Describe the bug
I'm trying to add the memory-server that is referenced as an example in the official mcp repo.

I've created the client like this

McpClientFactory.CreateAsync(), which works and I get get the list of tools.

Then I do

var tools = await mcpClient.ListToolsAsync();
            kernel.ImportPluginFromFunctions("memory_server", tools.Select(a => a.AsKernelFunction()));

which "succeeeds", but when asking gpt4o to save my name, it fails with the following:
"stdio-npx request failed for method 'tools/call': entities.filter is not a function (-32603)."

Which makes sense, because when looking at the payload that the mcp client tries to send to the mcp server it looks like this:

{"name":"create_entities","arguments":{"entities":"[{\u0022name\u0022:\u0022John Banana\u0022,\u0022entityType\u0022:\u0022Person\u0022,\u0022observations\u0022:[\u0022The name of the person is John Banana.\u0022]}]"}}

Where you can see that instead of having entities as a array of objects, it's just a string, with json of an array.

This MCP server works for example in Cursor, so I would assume this has something to do with how complex argument objects handled in the SDK, but I would be glad if I'm doing something wrong.

To Reproduce
Steps to reproduce the behavior:

  1. Have Semantic kernel and this dotnet MCP SDK setup.
  2. Create a MCP client instance created against the memory-server MCP server
  3. Add these tools to semantic kernel kernel
  4. Try to talk to the kernel, asking it to save something to memory.

Expected behavior
Should work instead of erroring.

Logs

[2025-04-30 15:53:29,473] [WARN] ModelContextProtocol.Client.McpClient: stdio-npx request failed for method 'tools/call': entities.filter is not a function (-32603).
[2025-04-30 15:53:29,548] [ERRO] AgentsController: Something went wrong during function invocation
ModelContextProtocol.McpException: Request failed (remote): entities.filter is not a function
   at ModelContextProtocol.Shared.McpSession.SendRequestAsync(JsonRpcRequest request, CancellationToken cancellationToken)
   at ModelContextProtocol.McpEndpointExtensions.SendRequestAsync[TParameters,TResult](IMcpEndpoint endpoint, String method, TParameters parameters, JsonTypeInfo`1 parametersTypeInfo, JsonTypeInfo`1 resultTypeInfo, RequestId requestId, CancellationToken cancellationToken)
   at ModelContextProtocol.Client.McpClientTool.InvokeCoreAsync(AIFunctionArguments arguments, CancellationToken cancellationToken)
   at Microsoft.SemanticKernel.ChatCompletion.AIFunctionKernelFunction.InvokeCoreAsync(Kernel kernel, KernelArguments arguments, CancellationToken cancellationToken)
   at Microsoft.SemanticKernel.KernelFunction.<>c__DisplayClass31_0.<<InvokeAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.SemanticKernel.Kernel.InvokeFilterOrFunctionAsync(NonNullCollection`1 functionFilters, Func`2 functionCallback, FunctionInvocationContext context, Int32 index)

Additional Context
If I call it manually with correct payload, without semantic kernel, it works. Here's how I do it:

var mcpClient = await McpClientFactory.CreateAsync(new StdioClientTransport(stdioOptions), loggerFactory: _loggerFactory);
            var entities = new[]
            {
                new Dictionary<string, object>
                {
                    ["name"]         = "John_Smith",
                    ["entityType"]   = "person",
                    ["observations"] = new[] { "Speaks fluent Spanish" }
                },
                new Dictionary<string, object>
                {
                    ["name"]         = "ACME_Corp",
                    ["entityType"]   = "organization",
                    ["observations"] = new[] { "Headquartered in Berlin", "Founded 1998" }
                }
            };

            var payload = new Dictionary<string, object>
            {
                ["entities"] = entities
            };
            var result = await mcpClient.CallToolAsync("create_entities", payload);

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions