curl --request POST \
--url https://api.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://mcp.acme.com/mcp",
"authType": "bearer",
"credentials": "sk-live-9f3c2b7a",
"customHeaders": {
"x-acme-region": "br"
},
"serverId": "6683f1c2a4b19e0012ab34cd"
}
'import requests
url = "https://api.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate"
payload = {
"url": "https://mcp.acme.com/mcp",
"authType": "bearer",
"credentials": "sk-live-9f3c2b7a",
"customHeaders": { "x-acme-region": "br" },
"serverId": "6683f1c2a4b19e0012ab34cd"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
url: 'https://mcp.acme.com/mcp',
authType: 'bearer',
credentials: 'sk-live-9f3c2b7a',
customHeaders: {'x-acme-region': 'br'},
serverId: '6683f1c2a4b19e0012ab34cd'
})
};
fetch('https://api.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate', 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.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://mcp.acme.com/mcp',
'authType' => 'bearer',
'credentials' => 'sk-live-9f3c2b7a',
'customHeaders' => [
'x-acme-region' => 'br'
],
'serverId' => '6683f1c2a4b19e0012ab34cd'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate"
payload := strings.NewReader("{\n \"url\": \"https://mcp.acme.com/mcp\",\n \"authType\": \"bearer\",\n \"credentials\": \"sk-live-9f3c2b7a\",\n \"customHeaders\": {\n \"x-acme-region\": \"br\"\n },\n \"serverId\": \"6683f1c2a4b19e0012ab34cd\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://mcp.acme.com/mcp\",\n \"authType\": \"bearer\",\n \"credentials\": \"sk-live-9f3c2b7a\",\n \"customHeaders\": {\n \"x-acme-region\": \"br\"\n },\n \"serverId\": \"6683f1c2a4b19e0012ab34cd\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://mcp.acme.com/mcp\",\n \"authType\": \"bearer\",\n \"credentials\": \"sk-live-9f3c2b7a\",\n \"customHeaders\": {\n \"x-acme-region\": \"br\"\n },\n \"serverId\": \"6683f1c2a4b19e0012ab34cd\"\n}"
response = http.request(request)
puts response.read_body{
"valid": true,
"toolsCount": 7,
"reason": "UNREACHABLE",
"error": "Could not reach the MCP server"
}{
"error": "Forbidden: token holds no claim for the requested account"
}{
"error": "Forbidden: token holds no claim for the requested account"
}{
"error": "Forbidden: token holds no claim for the requested account"
}{
"error": "Forbidden: token holds no claim for the requested account"
}Probe an MCP server
Ask a server for its tool list, with the same call the agent runtime makes, and report what happened. Nothing is registered or changed. Use it before createMcpServer to check an endpoint and its credential, and afterwards with serverId to check whether a server you already registered is still answering.
curl --request POST \
--url https://api.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://mcp.acme.com/mcp",
"authType": "bearer",
"credentials": "sk-live-9f3c2b7a",
"customHeaders": {
"x-acme-region": "br"
},
"serverId": "6683f1c2a4b19e0012ab34cd"
}
'import requests
url = "https://api.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate"
payload = {
"url": "https://mcp.acme.com/mcp",
"authType": "bearer",
"credentials": "sk-live-9f3c2b7a",
"customHeaders": { "x-acme-region": "br" },
"serverId": "6683f1c2a4b19e0012ab34cd"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
url: 'https://mcp.acme.com/mcp',
authType: 'bearer',
credentials: 'sk-live-9f3c2b7a',
customHeaders: {'x-acme-region': 'br'},
serverId: '6683f1c2a4b19e0012ab34cd'
})
};
fetch('https://api.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate', 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.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://mcp.acme.com/mcp',
'authType' => 'bearer',
'credentials' => 'sk-live-9f3c2b7a',
'customHeaders' => [
'x-acme-region' => 'br'
],
'serverId' => '6683f1c2a4b19e0012ab34cd'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate"
payload := strings.NewReader("{\n \"url\": \"https://mcp.acme.com/mcp\",\n \"authType\": \"bearer\",\n \"credentials\": \"sk-live-9f3c2b7a\",\n \"customHeaders\": {\n \"x-acme-region\": \"br\"\n },\n \"serverId\": \"6683f1c2a4b19e0012ab34cd\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://mcp.acme.com/mcp\",\n \"authType\": \"bearer\",\n \"credentials\": \"sk-live-9f3c2b7a\",\n \"customHeaders\": {\n \"x-acme-region\": \"br\"\n },\n \"serverId\": \"6683f1c2a4b19e0012ab34cd\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloudhumans.com/claudia/v1/tenants/{tenant}/mcp-servers/validate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://mcp.acme.com/mcp\",\n \"authType\": \"bearer\",\n \"credentials\": \"sk-live-9f3c2b7a\",\n \"customHeaders\": {\n \"x-acme-region\": \"br\"\n },\n \"serverId\": \"6683f1c2a4b19e0012ab34cd\"\n}"
response = http.request(request)
puts response.read_body{
"valid": true,
"toolsCount": 7,
"reason": "UNREACHABLE",
"error": "Could not reach the MCP server"
}{
"error": "Forbidden: token holds no claim for the requested account"
}{
"error": "Forbidden: token holds no claim for the requested account"
}{
"error": "Forbidden: token holds no claim for the requested account"
}{
"error": "Forbidden: token holds no claim for the requested account"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Tenant whose MCP servers you are managing. Get it from the backoffice GET /auth/v1/me/claudia-projects, which answers with the tenant your credentials cover. A tenant your credentials do not cover is indistinguishable from one that does not exist.
Body
The MCP server to probe. Nothing is stored — the probe only reports whether the server answers.
The MCP endpoint to call, http or https. Probed exactly as written, with the same request the agent runtime makes, so a passing probe means the runtime will reach the same endpoint.
"https://mcp.acme.com/mcp"
How to authenticate the probe. forwarded_user and oauth are probed without any credential, because their identity only exists at agent call time — such a server may legitimately answer valid: false and still be worth saving.
none, bearer, apiKey, forwarded_user, oauth "bearer"
The secret to probe with, in full. Omit it together with serverId to re-probe an already registered server using its stored secret.
"sk-live-9f3c2b7a"
Extra headers to send on the probe. Always taken from this request, so a headers-only change can be probed before it is saved.
Show child attributes
Show child attributes
{ "x-acme-region": "br" }
An already registered server to reuse the stored secret from, as returned by listMcpServers. The stored secret is reused only while url and authType still match what is stored for it; change either and the probe runs with no credential, so you must supply one to get a truthful answer.
"6683f1c2a4b19e0012ab34cd"
Response
The probe ran. Read valid — a server that is down answers here, not as a failed request.
What the probe found. A server that is down or misbehaving is reported here as valid: false, not as a failed request.
Whether the server answered the tool listing successfully.
true
How many tools the server exposed. Absent when the probe did not succeed.
7
Why the probe failed. UNREACHABLE is network or timeout, AUTH_FAILED means the credential was rejected, RPC_ERROR means the server answered with an error, INVALID_RESPONSE means it answered something that is not MCP. Absent when valid.
UNREACHABLE, RPC_ERROR, INVALID_RESPONSE, AUTH_FAILED "UNREACHABLE"
A short description of the failure. Absent when valid.
"Could not reach the MCP server"