Skip to content

MCP Agent Mode Fails to Handle Multiple Tools call - JSON.parse Error #5590

@AfterStories

Description

@AfterStories

Before submitting your bug report

Relevant environment info

- OS:Windows 10
- Continue version:
- IDE version: JetBrains IntelliJ IDEA 2022.3

- config:

name: Local Assistant
version: 1.0.0
schema: v1
models:
  - name: azure.gpt-4o-mini
    provider: openai
    model: azure.gpt-4o-mini
    roles:
      - chat
      - edit
      - apply
    apiKey: xxxxx
    apiBase: xxxxx
    apiType: azure-openai
    deployment: azure.gpt-4o-mini
    capabilities:
      - tool_use
      - image_input
 
context:
  - provider: file
  - provider: folder
  - provider: codebase
 
# Using this mcpServers temporary solution recommended by  @Patrick-Erichsen 
# https://github.com/continuedev/continue/issues/4913#issuecomment-2852460359
 
mcpServers:
  - name: Filesystem
    command: cmd
    connectionTimeout: 20000
    args:
      - /c
      - npx
      - -y
      - "@modelcontextprotocol/server-filesystem"
      - C:/Users/hzheng057/Desktop/Code/continue/manual-testing-sandbox

Description

I've identified the root cause of an issue where the MCP Agent fails when handling multiple tool calls. When the LLM returns responses requiring multiple tools, the current continue code attempts to process them as a single tool JSON data, resulting in a JSON parsing error.

To reproduce

  1. Input the following promp to Agent model:
     
           please create unit test function for ABC.py, Create all of entities byData setup class DEF.py, save these two file in gtest folder, if file not exist, you should create it.    
     
       (I think any prompt requesting the LLM to generate multiple files or use multiple tools will trigger this issue)
     
  2. When the LLM generates code and Agent attempts to use tools to write files, an error occur :

Error Message

 

Error running handler for "tools/call":  SyntaxError: Unexpected non-whitespace character after JSON at position 234 (line 1 column 235)
    at JSON.parse (<anonymous>)
    at Pdn (c:\Users\hzheng057\Desktop\Code\continue\core\tools\callTool.ts:149:21)

 

Root Cause Analysis

 
I traced the issue to core\tools\callTool.ts in the callTool function, where it attempts to parse the arguments string:
 

const args = JSON.parse(callArgs || "{}");

 
So I console.log callArgs, I found it is a string contains three JSON objects text, which JSON.parse cannot handle:
 

{"path": "C:\\Users\\hzheng057\\Desktop\\Code\\continue\\manual-testing-sandbox\\gtest\\ABC.py", "content": "class SampleClass:\n    def add(self, a, b):\n        return a + b\n\n    def subtract(self, a, b):\n        return a - b\n"}

{"path": "C:\\Users\\hzheng057\\Desktop\\Code\\continue\\manual-testing-sandbox\\gtest\\DEF.py", "content": "class DataSetup:\n    @staticmethod\n    def create_sample_data():\n        return [\n            {'a': 1, 'b': 2},\n            {'a': 3, 'b': 4},\n        ]\n"}

{"path": "C:\\Users\\hzheng057\\Desktop\\Code\\continue\\manual-testing-sandbox\\gtest\\test_ABC.py", "content": "import unittest\nfrom ABC import SampleClass\nfrom DEF import DataSetup\n\nclass TestSampleClass(unittest.TestCase):\n    def setUp(self):\n        self.sample_data = DataSetup.create_sample_data()\n        self.obj = SampleClass()\n\n    def test_add(self):\n        for data in self.sample_data:\n            result = self.obj.add(data['a'], data['b'])\n            expected = data['a'] + data['b']\n            self.assertEqual(result, expected)\n\n    def test_subtract(self):\n        for data in self.sample_data:\n            result = self.obj.subtract(data['a'], data['b'])\n            expected = data['a'] - data['b']\n            self.assertEqual(result, expected)\n\nif __name__ == '__main__':\n    unittest.main()"}

I think using the JSON.parse statement here is to convert a single JSON string into a JSON object,
but here it get multiple JSON strings are concatenated together, so it cannot be parse .

These are the 3 parameters of the 3 tools put together, not the tool parameters of the tool currently being called.

The callArgs parameter comes from upstream logic in gui\src\redux\selectors\selectCurrentToolCall.ts.

Check the LLM response data for my question, I found that it respone is contains three separate write_file tool calls with different index value
 
GPT LLM Respones:

{
  "id": "chatcmpl-00c0402b-321c-4c64-be94-2d352c2cb5fc",
  "created": 1746791853,
  "model": "gpt-4o-mini",
  "object": "chat.completion.chunk",
  "system_fingerprint": "fp_7a53abb7a2",
  "choices": [
    {
      "index": 0,
      "delta": {
        "content": "Since",
        "role": "assistant",
        "tool_calls": [  
 //As you can see here, the tool_calls array returned by gpt contains three file "write_file"  tools, 
//but it should be called according to the index array.
          {
            "id": "call_bToMq64stuvANwE9FKdr8bx3",
            "type": "function",
            "index": 0,
            "function": {
              "arguments": "",
              "name": "write_file"
            }
          },
          {
            "id": "call_StU36XFirDNdk0QMLf9wYhwy",
            "type": "function",
            "index": 1,
            "function": {
              "arguments": "",
              "name": "write_file"
            }
          },
          {
            "id": "call_5BidQvY3VH4bGPMixvtsCxsp",
            "type": "function",
            "index": 2,
            "function": {
              "arguments": "",
              "name": "write_file"
            }
          }
        ]
      }
    }
  ]
}

Conclusion

 
The issue occurs because when the LLM returns instructions containing multiple tool calls, currentlly Continue plugin code parse them as a single tool params, I Think to fix it should be modified to execute the tools according to the index order specified by the LLM.

Metadata

Metadata

Labels

area:mcpRelates to Model Context Protocol (MCP)ide:jetbrainsRelates specifically to JetBrains extensionkind:bugIndicates an unexpected problem or unintended behavioros:windowsHappening specifically on Windows

Type

No type

Projects

Status

Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions