> For the complete documentation index, see [llms.txt](https://docs.datasentinel.io/manual/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.datasentinel.io/manual/ai-connector/troubleshooting/read-the-mcp-log.md).

# Find the cause in mcp.log

When a sign-in or a tool call fails, read mcp.log on the platform host first. It names the cause in one line, where the assistant only shows a generic error.

**Applies to:** a self-hosted Datasentinel MCP server (the `datasentinel_mcp` service), when an assistant fails to sign in or a tool call fails.

## Why start with the log

Assistants show little of what went wrong. A sign-in fails with *HTTP 500* or *Internal Server Error*. A tool call fails with *cannot connect* or a vague error. The assistant only sees the HTTP answer, never its cause.

The MCP server knows the cause, and logs it. Every sign-in step, every token and every tool call writes a line in `/datasentinel/log/mcp.log`, on the platform host. In most cases, one line tells you what to fix.

## Read the log

Run these commands on the platform host. To see the last errors and warnings:

```bash
grep -E ' - (ERROR|WARNING) - ' /datasentinel/log/mcp.log | tail -20
```

To watch the log while you reproduce the problem:

```bash
tail -f /datasentinel/log/mcp.log
```

Start `tail -f`, then sign in again or call the tool again from the assistant. The lines appear as the assistant works.

Each line has the same layout:

```
2026-10-05 15:05:07 - mcp - ERROR - session=- - oauth store write failed: ...
```

The `session` field is the MCP session id, or `-` before a session exists, for example during the sign-in. The message comes last.

## What the lines tell you

### The service settings

At every start, the server logs its settings, one `environment` line per variable:

```
environment DS_MCP_PUBLIC_URL='https://datasentinel.example.com'
environment DS_MCP_OAUTH_DIR=not set (default)
```

Read them after you change a setting. They show the value the server really uses. `not set (default)` and `empty (default)` mean the built-in default. A setting you changed but that still shows the default was not applied: check the drop-in with `systemctl cat datasentinel_mcp` and restart the service.

The next line, `oauth store ready`, confirms that the server can open its sign-in database.

### Sign-in failures

| Line in `mcp.log`                                                         | Cause                                                                                                                                | What to do                                                                                                                    |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- |
| `oauth store write failed: the filesystem of ... is full`                 | The disk of the sign-in database is full. The assistant shows *Dynamic Client Registration rejected (HTTP 500)* or another HTTP 500. | Free disk space on that filesystem. Then sign in again.                                                                       |
| `oauth store ... failed: cannot write ...`                                | The sign-in database belongs to another user, or the filesystem is read-only.                                                        | Give the directory and the file back to the service user.                                                                     |
| `oauth store ... failed: ... is locked by another process`                | A script keeps the sign-in database open.                                                                                            | Close the script.                                                                                                             |
| `oauth store ... failed: ... is corrupted`                                | The sign-in database is damaged.                                                                                                     | Follow the steps in the line. Every user signs in again afterwards.                                                           |
| `oauth login refused for '...': invalid credentials`                      | Wrong login or password.                                                                                                             | Use the Grafana login and password.                                                                                           |
| `credentials accepted by Grafana but '...' is not a Datasentinel user`    | The Grafana account has no Datasentinel user.                                                                                        | Create the user in Datasentinel.                                                                                              |
| `the licence has no MCP add-on`                                           | The licence does not include the AI Connector.                                                                                       | Contact Datasentinel to add it.                                                                                               |
| `oauth login page refused: sign-in link unknown, expired or already used` | The sign-in link was used twice, or opened too late.                                                                                 | Start the sign-in again from the assistant. See [Sign-in problems](/manual/ai-connector/troubleshooting/sign-in-problems.md). |
| `oauth refresh-token replay for ...`                                      | An old refresh token was sent again. The server revoked the user's tokens on that client.                                            | Sign in again. See [Sign-in problems](/manual/ai-connector/troubleshooting/sign-in-problems.md).                              |

A sign-in that fails before any of these lines appears usually never reached the server. Check the name it was sent to: see [Sign-in fails on an unknown host name](/manual/ai-connector/troubleshooting/sign-in-unknown-host.md).

A sign-in that works writes these lines, in order:

```
oauth client registered: <client id> ('Claude Code')
oauth login page shown for client <client id> ('Claude Code'): ...
oauth login accepted for user@example.com (login 'user') on client <client id> ...
oauth tokens issued for user@example.com on client <client id> (code exchange): ...
session opened for user@example.com (client <client id>, kind session)
```

The last line that appears shows how far the sign-in got.

### Rejected tokens

`bearer rejected on /mcp:` is followed by the reason:

* `expired token for '...'`: the assistant sent an expired token. It should refresh it on its own. If it loops, sign in again.
* `invalid signature or claims for '...'`: the token was issued by another platform, or before a key change. Sign in again.
* `not a JWT`: the assistant sent something that is not a Datasentinel token. Check the header or the token you configured.

`long-lived token refused for ...: id ... revoked, expired or unknown` means that a long-lived token, configured by an administrator, was revoked or has expired. Ask the administrator for a new one.

### Tool failures

Each tool call writes a `status=start` line, then `status=end` or `status=error`:

```
tool=get_current_sessions status=error duration=0.244s error=Datasentinel request to /agent/_get failed (HTTP 500): ...
```

The `error` field holds the cause, and a stack trace follows the line. A few frequent causes:

* `Max retries exceeded ... Connection refused` on `/agent/...`: the agent that monitors the instance does not answer. Check the agent, or the dispatcher for agentless instances.
* `CERTIFICATE_VERIFY_FAILED` with `Hostname mismatch`: see [TLS hostname mismatch on API calls](/manual/ai-connector/troubleshooting/tls-hostname-mismatch.md).
* `response truncated to fit`: a warning, not an error. The answer was too large and was shortened. Narrow the time range or the instance list.

## Follow one session

When several users work at once, follow one session. The `session opened` line maps a session id to a user:

```bash
grep 'session opened' /datasentinel/log/mcp.log | tail -5
grep 'session=<session id>' /datasentinel/log/mcp.log
```

The second command lists every tool call of that session, with its duration and its result.

## The service and its journal

The MCP server runs as a systemd service, `datasentinel_mcp`. What the service prints goes to the systemd journal, not to `mcp.log`, so the two sources complement each other:

| Source                            | What it holds                                                                                                                                                                                     |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/datasentinel/log/mcp.log`       | Every sign-in step, token and tool call, one line each. It names the cause.                                                                                                                       |
| The journal of `datasentinel_mcp` | The starts and stops of the service, the reason of a failed start, the HTTP access log of the sign-in routes, and the full stack traces of HTTP 500 answers. It shows where the failure happened. |

Check the state of the service first:

```bash
sudo systemctl status datasentinel_mcp
```

`active (running)` means the server is up, and the `since` date tells you when it last started. The command also prints the last lines of the journal. Any other state (`failed`, `activating (auto-restart)`, `inactive`) means the server is not serving requests: read the journal to see why.

Display the journal:

```bash
sudo journalctl -u datasentinel_mcp -n 50                     # the last 50 lines
sudo journalctl -u datasentinel_mcp -f                        # follow while you reproduce the problem
sudo journalctl -u datasentinel_mcp --since "10 minutes ago"  # a time window
sudo journalctl -u datasentinel_mcp -p err                    # errors only
```

To save an extract in a file, for example to send it with a support request:

```bash
sudo journalctl -u datasentinel_mcp --since "1 hour ago" --no-pager > /tmp/datasentinel_mcp_journal.txt
```

Read the journal in these cases:

* **The service does not start, or restarts in a loop.** `mcp.log` may stay empty, and the journal holds the error of the start script or of the Python process.
* **The assistant gets an HTTP 500.** The `mcp.log` line names the cause, and the journal has the full stack trace at the same time of day.
* **A sign-in stops halfway.** The access log shows which routes the assistant called (`/register`, `/token` and the others), with the HTTP status of each answer.

After a change of setting, restart the service, then read its settings again in `mcp.log` (see [The service settings](#the-service-settings)):

```bash
sudo systemctl restart datasentinel_mcp
```

The unit, its settings and the drop-in mechanism are described in [MCP Server Setup](/manual/ai-connector/server-setup/mcp-server-setup.md#how-it-is-started).

## When the log shows nothing

If `mcp.log` has no line at all for your attempt, the request did not reach the MCP server. Check, in order:

* **The service.** `systemctl status datasentinel_mcp` must show it running. If it does not start, the reason is in the journal: see [The service and its journal](#the-service-and-its-journal).
* **nginx.** The request may stop at nginx, or reach Grafana instead. Run `/datasentinel/soft/datasentinel_backend/scripts/mcp_check.sh`. It tests every route through nginx.
* **The network.** A cloud assistant may not reach the platform at all. See [MCP servers on a private network](/manual/ai-connector/troubleshooting/private-network-mcp-servers.md).

## Before you contact support

Send these with your request:

* the output of `mcp_check.sh`;
* the `mcp.log` lines around the failure, with their timestamps;
* the journal of the `datasentinel_mcp` service for the same period;
* the error the assistant showed, and the assistant's name and version.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.datasentinel.io/manual/ai-connector/troubleshooting/read-the-mcp-log.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
