[GH-ISSUE #4579] [BUG]: MCP servers fail to load from anythingllm_mcp_servers.json in Docker (TypeError: Cannot convert undefined or null to object) #2911

Closed
opened 2026-02-22 18:31:47 -05:00 by yindo · 4 comments
Owner

Originally created by @danny0094 on GitHub (Oct 25, 2025).
Original GitHub issue: https://github.com/Mintplex-Labs/anything-llm/issues/4579

Originally assigned to: @shatfield4 on GitHub.

How are you running AnythingLLM?

Docker (local)

What happened?

Description
In AnythingLLM v1.9.0 (Docker build), the file
/app/server/storage/plugins/anythingllm_mcp_servers.json
is correctly detected by the backend, but the MCP Hypervisor fails to parse it and throws a TypeError when booting MCP servers.
As a result, no MCP servers are loaded or started.

Error Log:

[backend] info: [MCPHypervisor] MCP Config File: /app/server/storage/plugins/anythingllm_mcp_servers.json [backend] error: Error listing MCP servers: TypeError: Cannot convert undefined or null to object at get mcpServerConfigs [as mcpServerConfigs] (/app/server/utils/MCP/hypervisor/index.js:104:19) at MCPCompatibilityLayer.bootMCPServers (/app/server/utils/MCP/hypervisor/index.js:390:36) at MCPCompatibilityLayer.reloadMCPServers (/app/server/utils/MCP/hypervisor/index.js:138:16)

Expected Behavior
AnythingLLM should:
Properly parse the JSON config file,
Load each MCP server definition listed under mcpServers, and
Automatically boot those servers according to the configuration.
Actual Behavior
The file is detected and logged by the MCP Hypervisor.
The JSON is valid and accessible inside the container.
Still, the process crashes with a TypeError and no MCP servers are initialized.
Environment
AnythingLLM version: v1.9.0 (Docker)
Host OS: Ubuntu Server 22.04
Docker network: danny_ai-net
Mounted volume: /opt/anythingllm/storage:/app/server/storage
Container name: anythingllm

MCP Config Example

 {
  "mcpServers": {
    "sequentialthinking": {
      "displayName": "Sequential Thinking",
      "description": "Run the Sequential Thinking MCP Server as a tool",
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "--network",
        "danny_ai-net",
        "-p",
        "4001:3000",
        "--name",
        "mcp-sequentialthinking",
        "mcp/sequentialthinking",
        "--transport",
        "http"
      ],
      "autoStart": true,
      "timeout": 120000
    }
  }
}

The file has been verified with jq and is valid JSON.
Possible Cause
In /app/server/utils/MCP/hypervisor/index.js,
the mcpServerConfigs getter seems to receive undefined, likely due to an initialization or fallback issue when the plugin directory is empty or when the JSON parser doesn’t correctly handle the file’s structure inside Docker volumes.
Workaround
No stable workaround found.
The error persists even with a valid JSON file, correct volume mount, and proper permissions.
Additional Notes
MCP support was announced in v1.9.0 but may not be fully functional in the Docker build.
This issue prevents all MCP server configurations from loading in containerized setups.
Please confirm if the MCP parser initialization is missing or mis-referencing the storage path in Docker builds.

Are there known steps to reproduce?

Steps to Reproduce

  1. Run the official AnythingLLM Docker image (mintplexlabs/anythingllm:1.9.0)

  2. Mount a valid storage directory to /app/server/storage, e.g.:
    -v /opt/anythingllm/storage:/app/server/storage

  3. Inside that storage path, create the file:
    /app/server/storage/plugins/anythingllm_mcp_servers.json

  4. Add a valid MCP config such as:

{
  "mcpServers": {
    "sequentialthinking": {
      "displayName": "Sequential Thinking",
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "mcp/sequentialthinking"
      ]
    }
  }
}

  1. Restart the container:
    docker restart anythingllm

  2. Check the logs:
    docker logs -n 50 anythingllm | grep MCP

Result:
The backend throws

TypeError: Cannot convert undefined or null to object

Possible Cause / Fix Ideas
The getter mcpServerConfigs in
/app/server/utils/MCP/hypervisor/index.js

likely receives undefined because the MCP parser doesn’t handle an existing JSON object correctly when the plugin folder is empty or uninitialized.
Adding a simple null-check or fallback could fix the crash:

const configs = this._configs || {};
for (const key of Object.keys(configs)) { ... }

It’s also possible that this._configs is initialized after the JSON file is parsed, causing the first access to fail.
Confirming that storage/plugins is properly resolved in Docker (not overwritten at runtime) might also help.

Originally created by @danny0094 on GitHub (Oct 25, 2025). Original GitHub issue: https://github.com/Mintplex-Labs/anything-llm/issues/4579 Originally assigned to: @shatfield4 on GitHub. ### How are you running AnythingLLM? Docker (local) ### What happened? Description In AnythingLLM v1.9.0 (Docker build), the file /app/server/storage/plugins/anythingllm_mcp_servers.json is correctly detected by the backend, but the MCP Hypervisor fails to parse it and throws a TypeError when booting MCP servers. As a result, no MCP servers are loaded or started. Error Log: `[backend] info: [MCPHypervisor] MCP Config File: /app/server/storage/plugins/anythingllm_mcp_servers.json [backend] error: Error listing MCP servers: TypeError: Cannot convert undefined or null to object at get mcpServerConfigs [as mcpServerConfigs] (/app/server/utils/MCP/hypervisor/index.js:104:19) at MCPCompatibilityLayer.bootMCPServers (/app/server/utils/MCP/hypervisor/index.js:390:36) at MCPCompatibilityLayer.reloadMCPServers (/app/server/utils/MCP/hypervisor/index.js:138:16)` Expected Behavior AnythingLLM should: Properly parse the JSON config file, Load each MCP server definition listed under mcpServers, and Automatically boot those servers according to the configuration. Actual Behavior The file is detected and logged by the MCP Hypervisor. The JSON is valid and accessible inside the container. Still, the process crashes with a TypeError and no MCP servers are initialized. Environment AnythingLLM version: v1.9.0 (Docker) Host OS: Ubuntu Server 22.04 Docker network: danny_ai-net Mounted volume: /opt/anythingllm/storage:/app/server/storage Container name: anythingllm MCP Config Example ``` { "mcpServers": { "sequentialthinking": { "displayName": "Sequential Thinking", "description": "Run the Sequential Thinking MCP Server as a tool", "command": "docker", "args": [ "run", "--rm", "-i", "--network", "danny_ai-net", "-p", "4001:3000", "--name", "mcp-sequentialthinking", "mcp/sequentialthinking", "--transport", "http" ], "autoStart": true, "timeout": 120000 } } } ``` The file has been verified with jq and is valid JSON. Possible Cause In /app/server/utils/MCP/hypervisor/index.js, the mcpServerConfigs getter seems to receive undefined, likely due to an initialization or fallback issue when the plugin directory is empty or when the JSON parser doesn’t correctly handle the file’s structure inside Docker volumes. Workaround No stable workaround found. The error persists even with a valid JSON file, correct volume mount, and proper permissions. Additional Notes MCP support was announced in v1.9.0 but may not be fully functional in the Docker build. This issue prevents all MCP server configurations from loading in containerized setups. Please confirm if the MCP parser initialization is missing or mis-referencing the storage path in Docker `builds.` ### Are there known steps to reproduce? Steps to Reproduce 1. Run the official AnythingLLM Docker image (mintplexlabs/anythingllm:1.9.0) 2. Mount a valid storage directory to /app/server/storage, e.g.: `-v /opt/anythingllm/storage:/app/server/storage` 3. Inside that storage path, create the file: `/app/server/storage/plugins/anythingllm_mcp_servers.json` 4. Add a valid MCP config such as: ``` { "mcpServers": { "sequentialthinking": { "displayName": "Sequential Thinking", "command": "docker", "args": [ "run", "--rm", "-i", "mcp/sequentialthinking" ] } } } ``` 5. Restart the container: `docker restart anythingllm` 6. Check the logs: `docker logs -n 50 anythingllm | grep MCP` Result: The backend throws `TypeError: Cannot convert undefined or null to object` Possible Cause / Fix Ideas The getter mcpServerConfigs in `/app/server/utils/MCP/hypervisor/index.js` likely receives undefined because the MCP parser doesn’t handle an existing JSON object correctly when the plugin folder is empty or uninitialized. Adding a simple null-check or fallback could fix the crash: ``` const configs = this._configs || {}; for (const key of Object.keys(configs)) { ... } ``` It’s also possible that this._configs is initialized after the JSON file is parsed, causing the first access to fail. Confirming that storage/plugins is properly resolved in Docker (not overwritten at runtime) might also help.
yindo added the possible buginvestigating labels 2026-02-22 18:31:47 -05:00
yindo closed this issue 2026-02-22 18:31:48 -05:00
Author
Owner

@danny0094 commented on GitHub (Oct 27, 2025):

Additional Observations
Both files exist and contain identical JSON content:

/app/server/storage/mcp_servers.json  
/app/server/storage/plugins/anythingllm_mcp_servers.json

Despite that, the Hypervisor logs always show:
[MCPHypervisor] Successfully started 0 MCP servers: []

The container runs under the non-root user anythingllm.
File permissions were checked and confirmed — also tested with docker exec -u root with no difference.
When the same JSON file is placed under /app/server/storage/mcp_servers.json,
the MCP servers show up correctly in the UI, which means the issue only affects the Hypervisor path.
Wrapping the JSON array in an object like

{ "mcpServers": [ ... ] }

changes the error from
Cannot convert undefined or null to object
to
Cannot read properties of undefined (reading 'anythingllm'),
indicating that bootMCPServers() is expecting an object with keys (e.g. anythingllm) instead of an array.
It seems the Docker build’s Hypervisor (running as anythingllm user) fails to parse the MCP config as intended,
while the legacy JSON path still works fine.
The problem appears isolated to MCPCompatibilityLayer.bootMCPServers() in the Docker runtime.

@danny0094 commented on GitHub (Oct 27, 2025): Additional Observations Both files exist and contain identical JSON content: ``` /app/server/storage/mcp_servers.json /app/server/storage/plugins/anythingllm_mcp_servers.json ``` Despite that, the Hypervisor logs always show: `[MCPHypervisor] Successfully started 0 MCP servers: []` The container runs under the non-root user anythingllm. File permissions were checked and confirmed — also tested with docker exec -u root with no difference. When the same JSON file is placed under /app/server/storage/mcp_servers.json, the MCP servers show up correctly in the UI, which means the issue only affects the Hypervisor path. Wrapping the JSON array in an object like `{ "mcpServers": [ ... ] }` changes the error from Cannot convert undefined or null to object to Cannot read properties of undefined (reading 'anythingllm'), indicating that bootMCPServers() is expecting an object with keys (e.g. anythingllm) instead of an array. It seems the Docker build’s Hypervisor (running as anythingllm user) fails to parse the MCP config as intended, while the legacy JSON path still works fine. The problem appears isolated to MCPCompatibilityLayer.bootMCPServers() in the Docker runtime.
Author
Owner

@danny0094 commented on GitHub (Oct 28, 2025):

Additional test with a customized HTTP bridge

To further narrow down the problem, a FastAPI-based HTTP bridge was implemented between AnythingLLM and a simple MCP server.
The goal was to determine whether the TypeError was caused by malformed JSON responses or by the Docker build's internal MCP parser.

Bridge-Code (mcp-http-bridge.py):

proc = subprocess.Popen(
    ["uvx", "mcp-server-time"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    text=True
)

payload = json.dumps({
    "jsonrpc": "2.0",
    "id": 1,
    "method": method,
    "params": params
})

out, _ = proc.communicate(payload)
try:
    return json.loads(out)
except json.JSONDecodeError:
    return {"error": "Invalid JSON response from mcp-server-time", "raw_output": out}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=4001)


Test-Setup:
mcp-http-bridge (FastAPI) läuft auf Port 4001
mcp-time (Express) läuft auf Port 4000
Both containers are in the same network (danny_ai-net)
MCP-Konfiguration in AnythingLLM:


[
{
"name": "MCP-Bridge",
"description": "HTTP Bridge for local MCP communication.",
"url": "http://mcp-http-bridge:4001",
"status": "active",
"type": "streamable",
"commands": []
},
{
"name": "MCP-Time",
"description": "A simple time and date server via HTTP bridge.",
"url": "http://mcp-time:4000",
"status": "active",
"type": "streamable",
"commands": []
}
]



Observations:
curl http://mcp-http-bridge:4001/manifest.json → valid JSON response
curl http://mcp-http-bridge:4001/run → correct result with timestamp
No JSONDecodeError entries in the bridge console
AnythingLLM still logs:

[MCPHypervisor] MCP Config File: /app/server/storage/plugins/anythingllm_mcp_servers.json
[MCPHypervisor] Pruning 0 MCP servers...
[MCPHypervisor] Error force reloading MCP servers: TypeError: Cannot convert undefined or null to object


Result:
Even with validated bridge responses and correct JSON, the internal _mcpServers value remains undefined in the AnythingLLM Docker build.
This clearly indicates that the error lies within the MCP hypervisor, presumably in MCPCompatibilityLayer.bootMCPServers() or in the mcpServerConfigs getter.
Conclusion:
The bridge proves that JSON communication and network setup are working.
The error is independent of external tools or the data structure.


If desired, I can provide a complete reproducible Docker setup (Compose + Bridge + Time Server) as a ZIP or Git.
@danny0094 commented on GitHub (Oct 28, 2025): Additional test with a customized HTTP bridge To further narrow down the problem, a FastAPI-based HTTP bridge was implemented between AnythingLLM and a simple MCP server. The goal was to determine whether the TypeError was caused by malformed JSON responses or by the Docker build's internal MCP parser. **Bridge-Code (mcp-http-bridge.py):** ```python proc = subprocess.Popen( ["uvx", "mcp-server-time"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True ) payload = json.dumps({ "jsonrpc": "2.0", "id": 1, "method": method, "params": params }) out, _ = proc.communicate(payload) try: return json.loads(out) except json.JSONDecodeError: return {"error": "Invalid JSON response from mcp-server-time", "raw_output": out} if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=4001) Test-Setup: mcp-http-bridge (FastAPI) läuft auf Port 4001 mcp-time (Express) läuft auf Port 4000 Both containers are in the same network (danny_ai-net) MCP-Konfiguration in AnythingLLM: ``` [ { "name": "MCP-Bridge", "description": "HTTP Bridge for local MCP communication.", "url": "http://mcp-http-bridge:4001", "status": "active", "type": "streamable", "commands": [] }, { "name": "MCP-Time", "description": "A simple time and date server via HTTP bridge.", "url": "http://mcp-time:4000", "status": "active", "type": "streamable", "commands": [] } ] ``` Observations: curl http://mcp-http-bridge:4001/manifest.json → valid JSON response curl http://mcp-http-bridge:4001/run → correct result with timestamp No JSONDecodeError entries in the bridge console AnythingLLM still logs: ``` [MCPHypervisor] MCP Config File: /app/server/storage/plugins/anythingllm_mcp_servers.json [MCPHypervisor] Pruning 0 MCP servers... [MCPHypervisor] Error force reloading MCP servers: TypeError: Cannot convert undefined or null to object ``` Result: Even with validated bridge responses and correct JSON, the internal _mcpServers value remains undefined in the AnythingLLM Docker build. This clearly indicates that the error lies within the MCP hypervisor, presumably in MCPCompatibilityLayer.bootMCPServers() or in the mcpServerConfigs getter. Conclusion: The bridge proves that JSON communication and network setup are working. The error is independent of external tools or the data structure. If desired, I can provide a complete reproducible Docker setup (Compose + Bridge + Time Server) as a ZIP or Git.
Author
Owner

@danny0094 commented on GitHub (Oct 29, 2025):

Additional hypothesis (pending verification)

After reviewing the MCP boot sequence and Docker startup behavior, I suspect a potential race condition in the AnythingLLM Docker build:

The MCP Hypervisor may attempt to read /app/server/storage/plugins/anythingllm_mcp_servers.json before the file contents are fully loaded or synchronized from the mounted volume.

In this scenario, the file exists but is still empty or uninitialized when bootMCPServers() calls the getter mcpServerConfigs, causing this._configs (or this._configs.mcpServers) to be undefined at runtime — resulting in the TypeError: Cannot convert undefined or null to object.
This would explain why the same JSON under /app/server/storage/mcp_servers.json loads successfully — that file is parsed later in the init sequence, after storage sync.
I’ll run a few additional tests to confirm this hypothesis (e.g., delaying the bootMCPServers() call or logging _configs initialization timing) when I have some free time.
Just wanted to document this possible cause for the dev team in the meantime.

@danny0094 commented on GitHub (Oct 29, 2025): Additional hypothesis (pending verification) After reviewing the MCP boot sequence and Docker startup behavior, I suspect a potential race condition in the AnythingLLM Docker build: `The MCP Hypervisor may attempt to read /app/server/storage/plugins/anythingllm_mcp_servers.json before the file contents are fully loaded or synchronized from the mounted volume.` In this scenario, the file exists but is still empty or uninitialized when bootMCPServers() calls the getter mcpServerConfigs, causing this._configs (or this._configs.mcpServers) to be undefined at runtime — resulting in the TypeError: Cannot convert undefined or null to object. This would explain why the same JSON under /app/server/storage/mcp_servers.json loads successfully — that file is parsed later in the init sequence, after storage sync. I’ll run a few additional tests to confirm this hypothesis (e.g., delaying the bootMCPServers() call or logging _configs initialization timing) when I have some free time. Just wanted to document this possible cause for the dev team in the meantime.
Author
Owner

@shatfield4 commented on GitHub (Oct 29, 2025):

So after testing this in as many ways as possible, I've come to the conclusion that you are creating the anythingllm_mcp_servers.json file in an incorrect format before the initialization of this file is run inside the docker image. The only time I was able to get the error you are showing with [backend] error: Error listing MCP servers: TypeError: Cannot convert undefined or null to object is if I provide an invalid mcp config with just {} or invalid JSON in the config.

I also see you noted that you have both of these files:

/app/server/storage/mcp_servers.json
/app/server/storage/plugins/anythingllm_mcp_servers.json

but only this one should exist:

/app/server/storage/plugins/anythingllm_mcp_servers.json

When starting up the docker image fresh, if you visit the /settings/agents page it will run the initialization for that file for you and create all the correct file structures that we expect. I have tested this with your configs you provided and it works as it should.

The only thing that I ran into (which you will probably run into too) is that when running AnythingLLM via Docker container, we do not currently support mcp servers that are run inside of docker. You will most likely run into the spawn docker ENOENT error. This is because we cannot start and access docker containers from inside then AnythingLLM docker container at the moment.

See this comment and this comment for more info on how you can solve this.

Closing for now but if there is any more information you can provide then we'd be more than happy to reopen this issue.

@shatfield4 commented on GitHub (Oct 29, 2025): So after testing this in as many ways as possible, I've come to the conclusion that you are creating the `anythingllm_mcp_servers.json` file in an incorrect format before the initialization of this file is run inside the docker image. The only time I was able to get the error you are showing with `[backend] error: Error listing MCP servers: TypeError: Cannot convert undefined or null to object` is if I provide an invalid mcp config with just {} or invalid JSON in the config. I also see you noted that you have both of these files: `/app/server/storage/mcp_servers.json` `/app/server/storage/plugins/anythingllm_mcp_servers.json` but only this one should exist: `/app/server/storage/plugins/anythingllm_mcp_servers.json` When starting up the docker image fresh, if you visit the `/settings/agents` page it will run the initialization for that file for you and create all the correct file structures that we expect. I have tested this with your configs you provided and it works as it should. The only thing that I ran into (which you will probably run into too) is that when running AnythingLLM via Docker container, we do not currently support mcp servers that are run inside of docker. You will most likely run into the `spawn docker ENOENT` error. This is because we cannot start and access docker containers from inside then AnythingLLM docker container at the moment. See [this comment](https://github.com/Mintplex-Labs/anything-llm/issues/4085#issuecomment-3025931539) and [this comment](https://github.com/Mintplex-Labs/anything-llm/issues/4085#issuecomment-3025974348) for more info on how you can solve this. Closing for now but if there is any more information you can provide then we'd be more than happy to reopen this issue.
yindo changed title from [BUG]: MCP servers fail to load from anythingllm_mcp_servers.json in Docker (TypeError: Cannot convert undefined or null to object) to [GH-ISSUE #4579] [BUG]: MCP servers fail to load from anythingllm_mcp_servers.json in Docker (TypeError: Cannot convert undefined or null to object) 2026-06-05 14:49:14 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Mintplex-Labs/anything-llm#2911