Verify MCP Servers Yourself
Run the MCP connectivity checker on your own machine to verify which AI tool integrations are working, which are read-only, and which need credentials. Layer 1 requires no sign-in. Layer 2 is opt-in and uses your own READONLY credentials.
Prerequisites
- Docker (for Layer 1 on bare metal) or native tools (in Codespace: bash, jq, python3 >=3.11, uv, node on PATH)
- Go Task (
taskcommand available) - No cloud credentials needed for Layer 1
Layer 1: What Works (No Credentials)
Run the health check from your repo directory. It reports which servers are available and which need a sign-in.
adlc-framework (framework developers)
cd /path/to/adlc-framework
task -x mcp:doctor
Your multi-tenant project
cd /path/to/your-project
task -x mcp:doctor TENANT=<tenant>
Replace <tenant> with a tenant ID that is configured in your project. If you provide an unknown tenant ID, the script will print an error message showing the valid tenant options configured for your project.
Your project (non-tenant configuration)
cd /path/to/your-project
task -x mcp:doctor
Layer 2: Live Server Check (Opt-In with Your READONLY Sign-Ins)
Once Layer 1 passes, you can verify that servers actually connect using your own read-only credentials. This layer refuses write-capable profiles.
Before Layer 2: Sign In to Your Clouds
For AWS servers:
aws sso login --profile <your-READONLY-profile>
For Azure servers: If your project uses separate Azure login folders per tenant, sign in with:
AZURE_CONFIG_DIR=~/.azure-<tenant> az login --tenant <your-tenant-id>
Replace <tenant> with your tenant identifier and <your-tenant-id> with your Azure tenant ID.
For Claude Code (all layers): The claude CLI must be on your PATH.
Run Layer 2
For your multi-tenant project:
cd /path/to/your-project
task -x mcp:verify TENANT=<tenant>
Replace <tenant> with your tenant identifier.
For your non-tenant project:
cd /path/to/your-project
task -x mcp:verify
Expected Output: Layer 1 PASS Format
Layer 1 prints status lines in the following format. The exact server names and counts will vary depending on your project configuration.
| Line Type | Format | Meaning | What to Do |
|---|---|---|---|
CONFIG | CONFIG <file> servers=N sha256=<hash> | Declares the MCP configuration file being checked and how many servers it contains. The hash identifies the file version. | Note the config filename and server count. |
PASS check:... | PASS check:name - description | A framework check passed (e.g., Docker is running, config file is valid). | Continue; no action needed. |
WARN server:... | WARN server:name - reason (see _platform note) | A server is not available on your host platform (e.g., Linux-only server on macOS). Other servers are unaffected. | Skip this server; other servers in the output are still checked. |
PASS server:... | PASS server:name - tools/list ok | A credential-free server is reachable (no sign-in required). | Confirm this server is working. |
NEEDS-SIGNIN server:... | NEEDS-SIGNIN server:name - ENV1,ENV2,... | A server needs credentials to connect. The environment variables shown (e.g., AWS_PROFILE, GITHUB_PERSONAL_ACCESS_TOKEN) must be set before Layer 2. | Set the required credentials, then proceed to Layer 2. |
SUMMARY | SUMMARY layer=1 checks: PASS=X FAIL=Y ... verdict=VERIFIED | Final verdict of all checks. Exit code 0 (VERIFIED) means Layer 1 passed and you can proceed to Layer 2. | If verdict=VERIFIED, proceed to Layer 2. If verdict=FAILED, check the FAIL check: lines above for remediation. |
EVIDENCE | EVIDENCE /path/to/.../mcp-doctor-l1-<tenant>-<timestamp>.json | Path to the detailed JSON evidence file. Useful for debugging. | Optional: review the JSON file if troubleshooting is needed. |
Expected Output: Layer 1 FAIL (Docker Unreachable)
When Docker is not running and you have not set MCP_DOCTOR_RUNTIME=native:
FAIL check:prereq-runtime - docker unreachable (MCP_DOCTOR_RUNTIME=docker) - start Docker or set MCP_DOCTOR_RUNTIME=native
SUMMARY layer=1 checks: PASS=0 FAIL=1 SKIP=0 WARN=0 servers: PASS=0 FAIL=0 SKIP=0 NEEDS-SIGNIN=0 total=0 verdict=FAILED
Fix: Start Docker, or set the runtime to native:
MCP_DOCTOR_RUNTIME=native task -x mcp:doctor
Expected Output: Layer 2 PASS Format
Layer 2 runs after your READONLY credentials are signed in. It prints the same Layer 1 checks, plus additional identity and liveness verification. The exact server names and counts will vary depending on your project configuration and credentials.
| Line Type | Format | Meaning | What to Do |
|---|---|---|---|
PASS check:layer1-gate ... | PASS check:layer1-gate - no check-level FAIL | Layer 1 checks all passed; proceeding to Layer 2 identity verification. | Continue; this is expected in Layer 2. |
PASS check:prereq-claude ... | PASS check:prereq-claude - claude on PATH | The claude CLI is installed and available. | Continue; required for Layer 2 server connection tests. |
PASS server:azure ... | PASS server:azure - tenant=<tenant> roles=Reader | Your signed-in Azure identity matches the tenant and has Reader role (read-only). | Continue; your Azure credentials are valid and safe. |
PASS check:readonly-identity ... | PASS check:readonly-identity - 0 guarded server(s) needs-signin | All guarded servers (AWS, Azure) have valid READONLY credentials. | Continue; servers will now be tested for liveness. |
PASS server:... - tools/list ok, claude init connected | PASS server:name - tools/list ok, claude init connected | The server is reachable via both the test harness and the Claude CLI. | Confirm the server is working end-to-end. |
FAIL server:... | FAIL server:name - liveness=CONNECTED handshake=FAIL | The server connects but the Claude handshake failed. Check credentials or server configuration. | Review the server's environment variables and retry Layer 2. |
SUMMARY | SUMMARY layer=2 checks: PASS=X FAIL=Y ... verdict=VERIFIED | Final verdict. Exit code 0 (VERIFIED) means all servers are reachable with your credentials. | If verdict=VERIFIED, Layer 2 is complete. If verdict=FAILED, fix the failing server and retry. |
EVIDENCE | EVIDENCE /path/to/.../mcp-verify-l2-<tenant>-<timestamp>.json | Path to the detailed Layer 2 evidence file. | Optional: review for debugging. |
Exit Codes
| Code | Meaning | Action |
|---|---|---|
0 | VERIFIED — checks passed, servers match config | Credential-free servers are reachable. Proceed to Layer 2 if desired. |
1 | FAILED — one or more checks failed | See the FAIL line for the reason. Fix and retry. |
2 | Usage error — bad arguments or missing framework | Check the error message and correct the command. |
3 | NOT VERIFIED — no failures, but no servers tested | All servers need sign-ins. Proceed to Layer 2 or provide credentials. |
Troubleshooting
Layer 1 WARN (Platform Not Supported)
A server is marked WARN (not FAIL) if it does not support your host platform:
WARN server:awslabs-iac - linux/amd64 only; install fails on this host (see _platform note)
Fix: This server is unavailable on your platform. Other servers in the list are unaffected.
Layer 2: Tenant Settings File Syntax Error
When running task -x mcp:verify TENANT=<tenant>, the task loads your tenant's settings file and checks its syntax:
ERROR: tenants/<tenant>/.env.settings failed shell-syntax check (bash -n)
Fix: Your tenant settings file has a shell syntax error. The error message shows the line where the problem is. Correct the syntax, then re-run the task.
Layer 2: READONLY Identity Refused
Layer 2 refuses to start servers if you are signed in with a write-capable identity or if the tenant does not match:
FAIL check:readonly-identity - AWS_PROFILE is not a ReadOnly role
or
FAIL check:readonly-identity - signed-in Azure tenant does not match <tenant>
or
FAIL check:readonly-identity - NOT READONLY-CONFIRMED (Contributor)
Fix: For AWS, sign in with a READONLY profile:
aws sso login --profile <your-READONLY-profile>
For Azure, ensure your account has the Reader role (or a read-only role such as Reader, Billing Reader, or Security Reader). Sign into the correct tenant that matches the tenant you are verifying.
Docker Image Pull Fails
If you see an image pull error, check your internet connection and Docker registry access, then retry. The doctor caches downloaded packages in Docker named volumes.