Skip to content

api crashes when an mcp returns an image #10101

@L0ria

Description

@L0ria

LocalAI version:

localai/localai:latest-gpu-nvidia-cuda-13 (v4.3.1)

Environment, CPU architecture, OS, and Version:

Linux ai 6.18.2-1-default #1 SMP PREEMPT_DYNAMIC Fri Dec 19 10:15:01 UTC 2025 (9447271) x86_64 x86_64 x86_64 GNU/Linux

Describe the bug

After adding an osm mcps server (https://github.com/NERVsystems/osmmcp) as http server for an agent and asking the agent for an map of europe, the agent uses the mcp server, but the api-1 container crashes as soon as the mcp server replies.

To Reproduce

  4f0d7019962b   osmmcp:latest                      "/usr/local/bin/osmm…"   17 minutes ago   Up 8 minutes (healthy)   0.0.0.0:7082->7082/tcp, [::]:7082->7082/tcp, 0.0.0.0:9091->9091/tcp, [::]:9091->9091/tcp   osmmcp-service
  • Add and http mcp server to the agent, with the url http://:7082/mcp
  • Ask the agent for a map of europe
    => api-1 container crashes

Expected behavior

The api-1 does not crash, and the agent returns an image of a map of europa

Logs

api-1 | May 31 02:42:47 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:47 DEBUG Sending chunk chunk="
api-1 | May 31 02:42:47 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:47 DEBUG Sending chunk chunk="{"created":1780195355,"object":"chat.completion.chunk","id":"04a5d307-426e-45e8-b1de-077f8358543f","model":"Qwen3.5-4B-Uncensored-HauhauCS-Aggressive-Q4_K_M","choices":[{"index":0,"finish_reason":null,"delta":{"content":null,"reasoning":"."}}]}" caller={caller.file="/build/core/http/endpoints/openai/chat.go" caller.L=394 }
api-1 | May 31 02:42:47 DEBUG GRPC stderr id="Qwen3.5-4B-Uncensored-HauhauCS-Aggressive-Q4_K_M-127.0.0.1:45057" line="0.11.638.809 I reasoning-budget: deactivated (natural end)" caller={caller.file="/build/pkg/model/process.go" caller.L=187 }
api-1 | May 31 02:42:47 DEBUG Sending chunk chunk="{"created":1780195355,"object":"chat.completion.chunk","id":"04a5d307-426e-45e8-b1de-077f8358543f","model":"Qwen3.5-4B-Uncensored-HauhauCS-Aggressive-Q4_K_M","choices":[{"index":0,"finish_reason":null,"delta":{"content":null,"reasoning":"\n"}}]}" caller={caller.file="/build/core/http/endpoints/openai/chat.go" caller.L=394 }
api-1 | May 31 02:42:47 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:47 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:47 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:47 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:47 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:47 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:47 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:47 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:47 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:47 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:47 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:47 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:47 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:47 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:47 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:47 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:47 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:47 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:47 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:47 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:48 DEBUG HTTP request method="GET" path="/api/operations" status=200 caller={caller.file="/build/core/http/app.go" caller.L=203 }
api-1 | May 31 02:42:48 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:48 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:48 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:48 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:48 DEBUG GRPC stderr id="Qwen3.5-4B-Uncensored-HauhauCS-Aggressive-Q4_K_M-127.0.0.1:45057" line="0.12.448.650 I slot print_timing: id 0 | task 0 | prompt eval time = 1119.23 ms / 4007 tokens ( 0.28 ms per token, 3580.12 tokens per second)" caller={caller.file="/build/pkg/model/process.go" caller.L=187 }
api-1 | May 31 02:42:48 DEBUG GRPC stderr id="Qwen3.5-4B-Uncensored-HauhauCS-Aggressive-Q4_K_M-127.0.0.1:45057" line="0.12.448.651 I slot print_timing: id 0 | task 0 | eval time = 3896.42 ms / 275 tokens ( 14.17 ms per token, 70.58 tokens per second)" caller={caller.file="/build/pkg/model/process.go" caller.L=187 }
api-1 | May 31 02:42:48 DEBUG GRPC stderr id="Qwen3.5-4B-Uncensored-HauhauCS-Aggressive-Q4_K_M-127.0.0.1:45057" line="0.12.448.652 I slot print_timing: id 0 | task 0 | total time = 5015.66 ms / 4282 tokens" caller={caller.file="/build/pkg/model/process.go" caller.L=187 }
api-1 | May 31 02:42:48 DEBUG GRPC stderr id="Qwen3.5-4B-Uncensored-HauhauCS-Aggressive-Q4_K_M-127.0.0.1:45057" line="0.12.448.652 I slot print_timing: id 0 | task 0 | graphs reused = 273" caller={caller.file="/build/pkg/model/process.go" caller.L=187 }
api-1 | May 31 02:42:48 DEBUG GRPC stderr id="Qwen3.5-4B-Uncensored-HauhauCS-Aggressive-Q4_K_M-127.0.0.1:45057" line="0.12.448.842 I slot release: id 0 | task 0 | stop processing: n_tokens = 4281, truncated = 0" caller={caller.file="/build/pkg/model/process.go" caller.L=187 }
api-1 | May 31 02:42:48 DEBUG GRPC stderr id="Qwen3.5-4B-Uncensored-HauhauCS-Aggressive-Q4_K_M-127.0.0.1:45057" line="0.12.448.845 I srv update_slots: all slots are idle" caller={caller.file="/build/pkg/model/process.go" caller.L=187 }
api-1 | May 31 02:42:48 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:48 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:48 DEBUG LLM result result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=256 }
api-1 | May 31 02:42:48 DEBUG LLM result(processed) result="" caller={caller.file="/build/pkg/functions/parse.go" caller.L=264 }
api-1 | May 31 02:42:48 DEBUG [ChatDeltas] streaming completed, accumulated deltas from C++ autoparser total_deltas=217 caller={caller.file="/build/core/backend/llm.go" caller.L=257 }
api-1 | May 31 02:42:48 DEBUG [ChatDeltas] received deltas from backend total_deltas=217 content_chunks=0 reasoning_chunks=206 tool_call_chunks=11 caller={caller.file="/build/pkg/functions/chat_deltas.go" caller.L=31 }
api-1 | May 31 02:42:48 DEBUG [ChatDeltas] extracted tool call index=0 name="get_map_image" id="OYiEdEcoz4aVXGXzgWOLrrVD3jS1O5zB" args_length=43 caller={caller.file="/build/pkg/functions/chat_deltas.go" caller.L=74 }
api-1 | May 31 02:42:48 DEBUG [ChatDeltas] using C++ autoparser tool calls, skipping Go-side parsing count=1 caller={caller.file="/build/pkg/functions/chat_deltas.go" caller.L=87 }
api-1 | May 31 02:42:48 DEBUG [ChatDeltas] Using pre-parsed tool calls from C++ autoparser count=1 caller={caller.file="/build/core/http/endpoints/openai/chat_stream_workers.go" caller.L=332 }
api-1 | May 31 02:42:48 DEBUG [ChatDeltas] final tool call decision tool_calls=1 text_content="" caller={caller.file="/build/core/http/endpoints/openai/chat_stream_workers.go" caller.L=346 }
api-1 | May 31 02:42:48 DEBUG Sending chunk chunk="{"created":1780195355,"object":"chat.completion.chunk","id":"04a5d307-426e-45e8-b1de-077f8358543f","model":"Qwen3.5-4B-Uncensored-HauhauCS-Aggressive-Q4_K_M","choices":[{"index":0,"finish_reason":null,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"OYiEdEcoz4aVXGXzgWOLrrVD3jS1O5zB","type":"function","function":{"name":"get_map_image","arguments":""}}]}}]}" caller={caller.file="/build/core/http/endpoints/openai/chat.go" caller.L=394 }
api-1 | May 31 02:42:48 DEBUG Sending chunk chunk="{"created":1780195355,"object":"chat.completion.chunk","id":"04a5d307-426e-45e8-b1de-077f8358543f","model":"Qwen3.5-4B-Uncensored-HauhauCS-Aggressive-Q4_K_M","choices":[{"index":0,"finish_reason":null,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"OYiEdEcoz4aVXGXzgWOLrrVD3jS1O5zB","type":"function","function":{"arguments":"{\"latitude\":50.5,\"longitude\":15.5,\"zoom\":5}"}}]}}]}" caller={caller.file="/build/core/http/endpoints/openai/chat.go" caller.L=394 }
api-1 | May 31 02:42:48 DEBUG No choices in the response, skipping caller={caller.file="/build/core/http/endpoints/openai/chat.go" caller.L=370 }
api-1 | May 31 02:42:48 DEBUG No choices in the response, skipping caller={caller.file="/build/core/http/endpoints/openai/chat.go" caller.L=370 }
api-1 | May 31 02:42:48 DEBUG Stream ended caller={caller.file="/build/core/http/endpoints/openai/chat.go" caller.L=576 }
api-1 | May 31 02:42:48 INFO HTTP request method="POST" path="/chat/completions" status=200 caller={caller.file="/build/core/http/app.go" caller.L=205 }
api-1 | May 31 02:42:48 DEBUG [decisionWithStreaming] processed message="" reasoning="The user is asking for a map of Europe. Looking at the available tools, I can see there's a get_map_image function that can retrieve and display an OpenStreetMap image for analysis. However, this function requires specific latitude and longitude coordinates to get a map image, and it also requires a zoom level.\n\nTo get a map of Europe, I need to:\n1. First figure out what the approximate center coordinates of Europe are\n2. Determine an appropriate zoom level that would show a good view of Europe\n\nEurope's approximate center is around:\n- Latitude: 50°N (approximately 50.5)\n- Longitude: 15°E (approximately 15.5)\n\nFor a zoom level that would show Europe well, I should use a reasonable zoom level. Europe is quite large, so a zoom level around 4-6 would show the continent reasonably well. Let me use zoom level 5 which should give a good overview.\n\nLet me call the get_map_image function with these coordinates.\n" caller={caller.file="/root/go/pkg/mod/github.com/mudler/cogito@v0.9.5-0.20260315222927-63abdec7189b/tools.go" caller.L=324 }
api-1 | May 31 02:42:48 DEBUG [decisionWithStreaming] tools selected message="" toolChoices=1 caller={caller.file="/root/go/pkg/mod/github.com/mudler/cogito@v0.9.5-0.20260315222927-63abdec7189b/tools.go" caller.L=352 }
api-1 | May 31 02:42:48 DEBUG [pickTool] Tools selected count=1 caller={caller.file="/root/go/pkg/mod/github.com/mudler/cogito@v0.9.5-0.20260315222927-63abdec7189b/tools.go" caller.L=571 }
api-1 | May 31 02:42:48 DEBUG Cogito reasoning callback status="The user is asking for a map of Europe. Looking at the available tools, I can see there's a get_map_image function that can retrieve and display an OpenStreetMap image for analysis. However, this function requires specific latitude and longitude coordinates to get a map image, and it also requires a zoom level.\n\nTo get a map of Europe, I need to:\n1. First figure out what the approximate center coordinates of Europe are\n2. Determine an appropriate zoom level that would show a good view of Europe\n\nEurope's approximate center is around:\n- Latitude: 50°N (approximately 50.5)\n- Longitude: 15°E (approximately 15.5)\n\nFor a zoom level that would show Europe well, I should use a reasonable zoom level. Europe is quite large, so a zoom level around 4-6 would show the continent reasonably well. Let me use zoom level 5 which should give a good overview.\n\nLet me call the get_map_image function with these coordinates.\n" caller={caller.file="/root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260508125235-37810d918a87/core/agent/agent.go" caller.L=1061 }
api-1 | May 31 02:42:48 INFO Agent is thinking agent="map_agent" reasoning="The user is asking for a map of Europe. Looking at the available tools, I can see there's a get_map_image function that can retrieve and display an OpenStreetMap image for analysis. However, this function requires specific latitude and longitude coordinates to get a map image, and it also requires a zoom level.\n\nTo get a map of Europe, I need to:\n1. First figure out what the approximate center coordinates of Europe are\n2. Determine an appropriate zoom level that would show a good view of Europe\n\nEurope's approximate center is around:\n- Latitude: 50°N (approximately 50.5)\n- Longitude: 15°E (approximately 15.5)\n\nFor a zoom level that would show Europe well, I should use a reasonable zoom level. Europe is quite large, so a zoom level around 4-6 would show the continent reasonably well. Let me use zoom level 5 which should give a good overview.\n\nLet me call the get_map_image function with these coordinates.\n" action= params={} caller={caller.file="/root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260508125235-37810d918a87/core/state/pool.go" caller.L=430 }
api-1 | May 31 02:42:48 DEBUG [toolSelection] Tool selected name="get_map_image" caller={caller.file="/root/go/pkg/mod/github.com/mudler/cogito@v0.9.5-0.20260315222927-63abdec7189b/tools.go" caller.L=908 }
api-1 | May 31 02:42:48 DEBUG [toolSelection] Tools selected count=1 reasoning="The user is asking for a map of Europe. Looking at the available tools, I can see there's a get_map_image function that can retrieve and display an OpenStreetMap image for analysis. However, this function requires specific latitude and longitude coordinates to get a map image, and it also requires a zoom level.\n\nTo get a map of Europe, I need to:\n1. First figure out what the approximate center coordinates of Europe are\n2. Determine an appropriate zoom level that would show a good view of Europe\n\nEurope's approximate center is around:\n- Latitude: 50°N (approximately 50.5)\n- Longitude: 15°E (approximately 15.5)\n\nFor a zoom level that would show Europe well, I should use a reasonable zoom level. Europe is quite large, so a zoom level around 4-6 would show the continent reasonably well. Let me use zoom level 5 which should give a good overview.\n\nLet me call the get_map_image function with these coordinates.\n" caller={caller.file="/root/go/pkg/mod/github.com/mudler/cogito@v0.9.5-0.20260315222927-63abdec7189b/tools.go" caller.L=911 }
api-1 | May 31 02:42:48 DEBUG Picked tools with args count=1 caller={caller.file="/root/go/pkg/mod/github.com/mudler/cogito@v0.9.5-0.20260315222927-63abdec7189b/tools.go" caller.L=1331 }
api-1 | May 31 02:42:48 DEBUG Tool call back tool_call=&{get_map_image map[latitude:50.5 longitude:15.5 zoom:5] d7fbd148-7f86-400f-9069-fce4dbb0dd26 } caller={caller.file="/root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260508125235-37810d918a87/core/agent/agent.go" caller.L=1147 }
api-1 | May 31 02:42:48 DEBUG Action found action=&{0xaabb1ae4960 {object map[latitude:map[description:The latitude coordinate type:number] longitude:map[description:The longitude coordinate type:number] zoom:map[default:14 description:Zoom level (1-19, higher values show more detail) type:number]] [latitude longitude]} get_map_image Retrieve and display an OpenStreetMap image for analysis} caller={caller.file="/root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260508125235-37810d918a87/core/agent/agent.go" caller.L=1152 }
api-1 | May 31 02:42:48 INFO Agent is thinking agent="map_agent" reasoning="" action=get_map_image params={"latitude":50.5,"longitude":15.5,"zoom":5} caller={caller.file="/root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260508125235-37810d918a87/core/state/pool.go" caller.L=430 }
api-1 | panic: interface conversion: mcp.Content is *mcp.ImageContent, not *mcp.TextContent
api-1 |
api-1 | goroutine 189 [running]:
api-1 | github.com/mudler/cogito.(*mcpTool).Execute(0xaabb10fd030, 0xaabb21b1950)
api-1 | /root/go/pkg/mod/github.com/mudler/cogito@v0.9.5-0.20260315222927-63abdec7189b/mcp.go:52 +0x2c9
api-1 | github.com/mudler/cogito.ExecuteTools({0x62a06b8, 0xaabb1ae4690}, {{0xaabb2fc0f00, 0x2, 0x2}, 0x0, 0xaabb12eb450, {0x0, 0x0, 0x0}}, ...)
api-1 | /root/go/pkg/mod/github.com/mudler/cogito@v0.9.5-0.20260315222927-63abdec7189b/tools.go:1552 +0x3179
api-1 | github.com/mudler/LocalAGI/core/agent.(*Agent).consumeJob(0xaabb1ef6280, 0xaabb1956780, {0x42ffb10, 0x4})
api-1 | /root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260508125235-37810d918a87/core/agent/agent.go:1368 +0x2258
api-1 | github.com/mudler/LocalAGI/core/agent.(*Agent).run(0xaabb1ef6280, 0xaabb11ab1f0)
api-1 | /root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260508125235-37810d918a87/core/agent/agent.go:1543 +0xfd
api-1 | github.com/mudler/LocalAGI/core/agent.(*Agent).Run.func1()
api-1 | /root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260508125235-37810d918a87/core/agent/agent.go:1521 +0x3a
api-1 | created by github.com/mudler/LocalAGI/core/agent.(*Agent).Run in goroutine 160
api-1 | /root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260508125235-37810d918a87/core/agent/agent.go:1520 +0x1db
docker | time="2026-05-31T02:42:48.374404911Z" level=info msg="received task-delete event from containerd" container=0981b3fab9f68c0c878d7c70f19841462a2c34b7ab5c3026da2aab8702be86c2 module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"
docker | time="2026-05-31T02:42:48.374514690Z" level=info msg="shim disconnected" id=0981b3fab9f68c0c878d7c70f19841462a2c34b7ab5c3026da2aab8702be86c2 namespace=moby
docker | time="2026-05-31T02:42:48.374532400Z" level=info msg="cleaning up after shim disconnected" id=0981b3fab9f68c0c878d7c70f19841462a2c34b7ab5c3026da2aab8702be86c2 namespace=moby
docker | time="2026-05-31T02:42:48.374536350Z" level=info msg="cleaning up dead shim" id=0981b3fab9f68c0c878d7c70f19841462a2c34b7ab5c3026da2aab8702be86c2 namespace=moby
docker | time="2026-05-31T02:42:48.478114170Z" level=info msg="shim disconnected" id=8528188361bb0f424b43651b3a4f3439cf15eb7f4681e6b0caaa7765ee744683 namespace=moby
docker | time="2026-05-31T02:42:48.478113230Z" level=info msg="received task-delete event from containerd" container=8528188361bb0f424b43651b3a4f3439cf15eb7f4681e6b0caaa7765ee744683 module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"
docker | time="2026-05-31T02:42:48.478133540Z" level=info msg="cleaning up after shim disconnected" id=8528188361bb0f424b43651b3a4f3439cf15eb7f4681e6b0caaa7765ee744683 namespace=moby
docker | time="2026-05-31T02:42:48.478139580Z" level=info msg="cleaning up dead shim" id=8528188361bb0f424b43651b3a4f3439cf15eb7f4681e6b0caaa7765ee744683 namespace=moby

Additional context

The issue can be reproduced as well with using the NASA mcp server as stdio server, (https://github.com/ProgramComputer/NASA-MCP-server) when requesting images through that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions