Skip to main content
Version: 8.3.0

GuanMCP Troubleshooting

This page includes only issues that can be resolved directly from a specific symptom. The configurations, fields, and error messages come from the current GuanMCP implementation.

Connection and session issues

Streamable HTTP returns 401

Set the request header to Authorization: Bearer <MCP service credential> and confirm the credential exactly matches MCP_ENTRYPOINT_TOKEN. Do not put BI_APP_TOKEN in the client request header.

Streamable HTTP returns 404 or an SSE content-type error

If Error POSTing to endpoint: Not Found is followed by Invalid content type, expected text/event-stream, change the MCP URL to the complete entry point:

https://<GuanMCP address>/mcp

Do not use the site root, /healthz, or /mcp/. If the external URL has a custom prefix, the gateway must rewrite it to the backend /mcp.

The service returns mcp_session_not_found

The server no longer has the old session sent by the client. Reconnect the MCP service or start a new conversation so the client initializes a new session.

Tool and local configuration issues

Local stdio does not start or tools are not visible

For PAT authentication, start with this minimum configuration:

{
"mcpServers": {
"guanbi": {
"command": "npx",
"args": ["-y", "@guandata/guanbi-mcp-server@latest"],
"env": {
"MCP_TRANSPORT": "stdio",
"BI_BASE_URL": "https://bi.example.com",
"BI_PUBLIC_PATH": "",
"BI_PAT": "<your PAT>"
}
}
}
}

Save the configuration, reload or restart the MCP client, and confirm:

  • Node.js is version 20 or later and the client process can run npx.
  • BI_BASE_URL contains only the BI site root. Put any subpath in BI_PUBLIC_PATH.
  • stdio configuration does not contain a remote url, HTTP headers, or MCP_HTTP_* variables.

Run the following command to confirm that the package starts:

npx -y @guandata/guanbi-mcp-server@latest --version

Data query and consumption issues

Pagination and large results from query_card_data

query_card_data returns 100 rows by default and up to 1,000 rows per page, subject to a 4 MiB response budget. Continue with the returned page fields:

Returned fieldAction
page.has_more=falsePagination is complete.
page.has_more=true with page.next_offsetSet offset to next_offset in the next request.
diagnostic.partial_reason=response_bytesThe page reached the response budget. Continue with next_offset.
diagnostic.partial_reason=backend_limitAdd filters to narrow the scope and restart from offset=0.

Change only offset between pages. Keep all other query parameters unchanged. For large result sets, narrow the scope with filters, select required fields with columns, and process one page at a time. Use Guandata BI export for complete detail exports.

Paginated results contain � or ���

The client or an intermediary decoded byte chunks independently instead of preserving UTF-8 decoder state. Fix the client so the decoder retains state across chunks:

const decoder = new TextDecoder("utf-8", { fatal: true });
let text = "";

for await (const chunk of responseBody) {
text += decoder.decode(chunk, { stream: true });
}
text += decoder.decode();

Characters already replaced with � cannot be recovered. Discard that page and request it again after fixing decoding. Lowering limit only changes chunk boundaries and is not a substitute for the fix.

execute_sql_query is unavailable or reports an invalid table name

execute_sql_query requires Guandata BI 8.2.0 or later and Advanced SQL Query enabled for the domain under Administration > Advanced Settings. If the tool is absent, call get_bi_capabilities and check executeSqlQuery.

Use the dataset and field names returned by get_dataset_detail. Enclose Chinese names, spaces, and other special characters in backticks. In inputs, provide only dataset IDs referenced by the SQL; do not use a dataset ID, field ID, or input0 as a table name.

SELECT `City`, SUM(`Sales`) AS `Total Sales`
FROM `Sales Detail Dataset`
WHERE `City` = 'Hangzhou'
GROUP BY `City`

If TABLE_OR_VIEW_NOT_FOUND is returned and diagnostic.tableBindings[].sqlReference contains a value, keep inputs unchanged and replace the SQL FROM or JOIN reference with that value. A single-dataset Spark query may return __THIS__.

The number of returned rows is controlled by GuanMCP BI_MAX_ROWS; normally you do not need to add LIMIT.