Nobody notices an MCP server going down. That is the whole problem, and it is why mcp server monitoring looks so different from monitoring a web service you own. There is no 500 in your logs and no failed deploy. There is an agent that keeps answering questions, confidently, from context that was accurate the last time anything managed to read it.
The failure is silent by construction. Your side did not error. You asked a server a question and it gave you a reasonable-looking answer that happened to be empty, or stale, or from a tool that no longer means what it meant last month.
What actually breaks
In practice, connected servers fail in a small number of ways, and only one of them looks like an outage.
| What happened | What your logs show | How you usually find out |
|---|---|---|
| Credential rotated or revoked | A 401 the client library retried and swallowed | An agent gives an answer with nothing in it |
| Scope withdrawn upstream | A successful call returning an empty list | Somebody asks why a document stopped appearing |
| Tool renamed in a server update | A tool-not-found error inside a tool result | Nothing, until you read a transcript |
| Host moved or DNS changed | Connection timeouts | Eventually, from the far end's own status page |
| Authorization lapsed with nothing to renew it | One refused refresh, then silence | A person tries the integration by hand |
Only the fourth row is a conventional outage, and it is the least common. The other four are cases where every individual component behaved correctly and the overall system stopped being true.
This is also why uptime monitoring of the server's URL is close to useless. The host is up. The transport is fine. What broke is the relationship between your configuration and what that server currently offers, and no ping can see it.
The check that is worth running
A useful health check for an MCP server does three things, in order.
First, it opens a real connection with the real credential, which is the only way to learn that the credential still works. Second, it lists the tools, which is how a rename or a withdrawn capability surfaces. Third, it compares that list against the specific tool and argument names your integration is configured to call.
That third step is the one most implementations skip, and it is the one that catches the quietest failure of the lot. A server that has renamed search_documents to documents_search is completely healthy from the outside and completely broken for you.
It is worth recording latency on every check, too. A connected system that still answers but has gone from 200 milliseconds to nine seconds is degrading in a way no boolean reports, and it will usually start timing out under load before anybody has noticed the trend.
The token expiry trap
Here is where most monitoring in this space goes wrong, and it goes wrong in a way that makes things worse rather than merely failing to help.
OAuth access tokens are short-lived by design. Under the Model Context Protocol authorization spec, an MCP client obtains an access token and a refresh token, and the access token commonly lives about an hour. When it expires, the client gets a 401, exchanges the refresh token, and carries on. Nobody is involved. Nothing is broken. The expiry timestamp you can see in your own database simply moves forward.
If you alert on that timestamp, you have built a system that emails somebody roughly every hour about a credential that was never at risk.
The failure mode of a noisy monitor is not that it is annoying. It is that the recipient builds a filter rule, and then the one message that mattered is filtered too. A monitor that cries wolf has not merely failed to help; it has disabled the channel it was using.
So the question is not "when does this token expire". It is "is there anything that can renew this, and if not, when does it run out". Those have very different answers.
The two deadlines worth predicting
An authorization with no refresh token. Some providers issue only an access token, with no refresh token at all. Nothing can exchange anything, so that expiry really is the deadline, and when it passes a person has to sign in again. This is the one case where the timestamp means exactly what it appears to mean.
A client registration with an end date. RFC 7591 dynamic client registration lets an authorization server put an expiry on the registration itself. Existing tokens often keep working for a while after it lapses, and only new authorizations fail. That delay is precisely what makes it worth saying in advance, because the symptom arrives long after the cause.
Everything else should stay quiet until something actually fails. That includes a pasted personal access token, which almost certainly does have an expiry date that nobody told you. You could ask an administrator to type that date into a form. They will not update it when they rotate the token six weeks later, and a confident warning about a credential that is already fine is worse than silence, because it teaches people that your warnings are wrong.
Thresholds, and why one failure is not enough
A single failed check is usually the network having a bad minute. DNS blips, a connection resets, a far-end deploy drops in-flight requests for eight seconds.
The useful split is to separate two events that most systems conflate:
- Mark it broken immediately. The dashboard should say a source is failing the moment it fails, because somebody looking at the dashboard is already investigating something.
- Tell a person on the second consecutive failure. The inbox has a much higher bar than the screen. Two failures a day apart is a real condition, not weather.
There is one exception, and it is worth carving out explicitly. A refused refresh is not transient. The client has already tried the refresh token and been told no, so waiting a day to confirm it only buys you a day of a broken integration. That one should go out at once, and it should carry a different message, because the fix is a person signing in rather than anybody waiting.
This is the same distinction that runs through MCP authentication patterns generally: what a credential proves, and what happens when it stops proving it, are separate questions with separate answers.
What happens to what you already retrieved
There is a question that monitoring alone cannot answer, and it decides how much the outage actually costs you.
If your layer between agents and systems of record is a cache, then during an outage it serves whatever it last stored, with no indication of age. The agent cannot tell the difference between a fact read this morning and one read in March.
If it is a memory layer with a freshness contract, each stored fact carries its own age and its own review window, so an answer built on something old says so. The outage becomes a degradation you can reason about rather than a silent switch to fiction.
That is a design decision made long before anything breaks, and monitoring is what makes it visible. Contextely takes the second approach: memory from a source that has stopped answering is still served and still labelled, and what stops is the refresh that keeps it honest. The detail is in the source health reference, and the reasoning behind which conditions send mail is on the monitoring page.
A short checklist
If you are building this yourself, or evaluating something that claims to do it:
- Does the check confirm your specific tools and argument names, or only that the host answers?
- Is latency recorded per check, so degradation is visible before it becomes an outage?
- Is a refused refresh reported differently from an unreachable host?
- Does credential expiry alerting distinguish between a token that renews itself and one that cannot?
- Is there a threshold before a person is emailed, and does a recovery close the loop?
- When a source is down, does already-stored context still carry its own age?
The first four decide whether the monitoring is telling you anything. The last two decide whether anybody is still reading it in three months.
Governance and monitoring turn out to be the same discipline pointed at different moments: what an agent is allowed to reach, and whether what it reached is still true. Neither one is much use without the other.
