Count how many of an MCP server's tools need attention
Returns counts of an MCP server’s tools that need attention. new is the number of tools the server offers that aren’t imported here, including every tool you deliberately declined, so it isn’t a problem indicator. newSinceReview is the subset of those that the server added since you last synced it. Clients should surface this count. It is 0 for a server that has never been synced. changed is the number of imported tools that have drifted, and missing is the number of imported tools that the server no longer offers. These two counts need attention. The counts are computed on each call, with no scheduler or background job, so each call makes one live round trip to your MCP server. An unreachable server returns 200 with unreachable: true instead of a transport error. If the server was reached but refused the request (HTTP 401 or 403), the response also includes authFailed: true, so a client can report that the server refused the request instead of that it couldn’t be reached.
curl --request GET \
--url https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift \
--header 'X-API-Key: <api-key>'import requests
url = "https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"authFailed": false,
"changed": 1,
"missing": 0,
"new": 3,
"newSinceReview": 1,
"unreachable": false
}{
"detail": "request body validation failed",
"errors": [
{
"field": "<string>",
"message": "<string>"
}
],
"instance": "/v1/{resource}",
"status": 400,
"title": "Bad Request",
"traceId": "api--a4d2f126-bec4-4544-a049-7c0cf08524ed",
"type": "about:blank"
}{
"detail": "access denied: insufficient permissions",
"instance": "/v1/{resource}/{id}",
"status": 403,
"title": "Forbidden",
"traceId": "api--a4d2f126-bec4-4544-a049-7c0cf08524ed",
"type": "about:blank"
}{
"detail": "the requested resource does not exist",
"instance": "/v1/{resource}/{id}",
"status": 404,
"title": "Not Found",
"traceId": "api--a4d2f126-bec4-4544-a049-7c0cf08524ed",
"type": "about:blank"
}{
"detail": "internal server error",
"instance": "/v1/{resource}",
"status": 500,
"title": "Internal Server Error",
"traceId": "api--a4d2f126-bec4-4544-a049-7c0cf08524ed",
"type": "about:blank"
}Authorizations
[Production] API key for production authentication
Path Parameters
The unique identifier for the mcp server.
Response
OK
AuthFailed narrows an unreachable to the case where the server answered
and refused the request (HTTP 401/403), which is a credential or
authType problem rather than a network one. Never set without
unreachable.
false
Changed is imported but the server's description or schema has drifted.
1
Missing is imported but no longer offered; the row will fail at call time.
0
New is offered and not imported yet.
3
NewSinceReview is offered, not imported, and absent from the catalogue recorded at the last sync — i.e. the server added it after the customer last looked. A SUBSET of New.
Badge on this, never on New: New includes every tool the customer deliberately declined, so badging it warns forever about a healthy server.
1
Unreachable says the counts are not answers because the server could not be reached. A state rather than a 502, because a client fans this out one call per server and renders badges progressively.
Also set when the server WAS reached and refused us — see AuthFailed. The counts are equally meaningless either way, so a client that reads only this field stays correct.
false
curl --request GET \
--url https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift \
--header 'X-API-Key: <api-key>'import requests
url = "https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-trial.cognigy.ai/v1/mcp-servers/{id}/drift")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"authFailed": false,
"changed": 1,
"missing": 0,
"new": 3,
"newSinceReview": 1,
"unreachable": false
}{
"detail": "request body validation failed",
"errors": [
{
"field": "<string>",
"message": "<string>"
}
],
"instance": "/v1/{resource}",
"status": 400,
"title": "Bad Request",
"traceId": "api--a4d2f126-bec4-4544-a049-7c0cf08524ed",
"type": "about:blank"
}{
"detail": "access denied: insufficient permissions",
"instance": "/v1/{resource}/{id}",
"status": 403,
"title": "Forbidden",
"traceId": "api--a4d2f126-bec4-4544-a049-7c0cf08524ed",
"type": "about:blank"
}{
"detail": "the requested resource does not exist",
"instance": "/v1/{resource}/{id}",
"status": 404,
"title": "Not Found",
"traceId": "api--a4d2f126-bec4-4544-a049-7c0cf08524ed",
"type": "about:blank"
}{
"detail": "internal server error",
"instance": "/v1/{resource}",
"status": 500,
"title": "Internal Server Error",
"traceId": "api--a4d2f126-bec4-4544-a049-7c0cf08524ed",
"type": "about:blank"
}