Skip to content
Contextely
Academy7 min readBy The Contextely Team

MCP Server Monitoring: What Is Actually Worth an Alert

Most MCP monitoring alerts on token expiry that was never at risk. What actually fails quietly, and the narrow set of conditions worth an alert.

Three analog pressure gauges side by side on industrial pipework, standing in for mcp server monitoring across several connected servers at once

Photo: cottonbro studio on Pexels

Key takeaways

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:

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:

  1. Does the check confirm your specific tools and argument names, or only that the host answers?
  2. Is latency recorded per check, so degradation is visible before it becomes an outage?
  3. Is a refused refresh reported differently from an unreachable host?
  4. Does credential expiry alerting distinguish between a token that renews itself and one that cannot?
  5. Is there a threshold before a person is emailed, and does a recovery close the loop?
  6. 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.

Frequently asked questions

How do I monitor an MCP server?

Open a connection on a schedule, list the tools, and confirm that the specific tools and argument names your integration calls still exist under those names. A plain reachability ping is close to worthless here: an MCP server that answers but has renamed the tool you depend on is broken for you and healthy for a load balancer.

Should I alert on MCP OAuth token expiry?

Almost never. An access token typically lives about an hour and is exchanged automatically using the refresh token on the next rejected request, so its expiry timestamp moves forward without anybody doing anything. Alert instead when a refresh is actually refused, and predict expiry only where the stored authorization has no refresh token at all.

Why did my MCP server stop working without any error?

The three usual causes are a rotated or revoked credential, a scope withdrawn by an administrator on the far side, and a tool renamed in a server update. None of these produce an error in your own logs, because your side did not fail. You asked, and something reasonable came back that happened to be empty or different.

What happens to context already retrieved when a source goes down?

That depends entirely on the layer holding it. A cache serves whatever it has with no indication of age. A memory layer with a freshness contract keeps serving it and keeps labelling how old it is, so the reading agent can weigh it. The distinction matters most exactly when something is broken.

How often should an MCP health check run?

Daily is enough for the failures that actually matter, because a rotated credential or a renamed tool stays broken until a person fixes it. Running every minute mostly buys you a more precise timestamp on a problem whose repair time is measured in hours, and spends the far end's rate limit to get it.

Free for 500 retrievals a month, and self-hostable with no limits.