litmus

Grade MCP servers A to F with the open behavioral litmus. npm: full toolset; hosted: lookups only.

Should I use this

Quality & Safety

A
Description quality
93%
Schema completeness
97%
Naming quality
93%
Poisoning risk
100%
Permission match
100%
Protocol compliance
100%

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~1,468Tokens (tool definitions)
~4.9 KBTypical response size
Moderate attention impact (1.15% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "litmus": {
      "command": "npx",
      "args": [
        "@polygraphso/litmus"
      ]
    }
  }
}

Runnable packages

npm@polygraphso/litmus0.36.0stdio

Remote endpoints

https://polygraph.so/api/mcpstreamable-http

What it can do

Tool inventory

Tools (3)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟢check_server(server_ref)

Read a server's published behavioral grade (A-F) from polygraph.so in under a second; no execution. The pre-flight check before recommending or installing an MCP server. On a miss it returns not_available (unevaluated: neither safe nor unsafe) with next steps.

Input Schema

{
  "type": "object",
  "properties": {
    "server_ref": {
      "type": "string",
      "minLength": 1,
      "maxLength": 512,
      "description": "Registry-prefixed server ref: npm/<name>, npm/@scope/<name>, pypi/<name>, or github/<owner>/<repo>, with an optional @version. Example: npm/@modelcontextprotocol/server-filesystem"
    }
  },
  "required": [
    "server_ref"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}

Output Schema

{
  "type": "object",
  "properties": {
    "status": {
      "type": "string",
      "enum": [
        "graded",
        "not_available"
      ],
      "description": "Whether a published grade exists."
    },
    "server_ref": {
      "type": "string"
    },
    "grade": {
      "type": "string",
      "description": "A-F, present when status is graded."
    },
    "categories": {
      "type": "object",
      "properties": {
        "c01": {
          "type": "string"
        },
        "c02": {
          "type": "string"
        },
        "c03": {
          "type": "string"
        }
      },
      "required": [
        "c01",
        "c02",
        "c03"
      ],
      "additionalProperties": false,
      "description": "Per-category pass/fail, present when graded."
    },
    "current_version": {
      "type": [
        "string",
        "null"
      ]
    },
    "version_match": {
      "type": [
        "boolean",
        "null"
      ]
    },
    "report_url": {
      "type": "string"
    },
    "self_grade": {
      "type": "string",
      "description": "One-command reproduce/grade, present on a miss."
    }
  },
  "required": [
    "status",
    "server_ref"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
🟢list_servers(grade, limit, offset)

Servers with a published polygraph grade, sorted A-first then by ref. Returns up to `limit` rows starting at `offset` (default limit 25, capped at 100 per call); `grade` restricts to one letter. `summary` always covers the full graded corpus (a total plus a count per grade), regardless of `grade`, `limit`, or `offset`.

Input Schema

{
  "type": "object",
  "properties": {
    "grade": {
      "type": "string",
      "enum": [
        "A",
        "B",
        "C",
        "D",
        "F"
      ],
      "description": "Restrict to servers with this grade."
    },
    "limit": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "description": "Rows to return. Default 25, capped at 100 per call."
    },
    "offset": {
      "type": "integer",
      "minimum": 0,
      "description": "Rows to skip before taking `limit`, for paging past the first page."
    }
  },
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}

Output Schema

{
  "type": "object",
  "properties": {
    "total": {
      "type": "number",
      "description": "Rows matching `grade` (if given), before `limit`/`offset`. Equals summary.total when grade is omitted."
    },
    "servers": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "server_ref": {
            "type": "string"
          },
          "polygraph": {
            "type": "string"
          }
        },
        "required": [
          "server_ref",
          "polygraph"
        ],
        "additionalProperties": false
      }
    },
    "summary": {
      "type": "object",
      "properties": {
        "total": {
          "type": "number",
          "description": "Total graded servers across the whole corpus."
        },
        "byGrade": {
          "type": "object",
          "properties": {
            "A": {
              "type": "number"
            },
            "B": {
              "type": "number"
            },
            "C": {
              "type": "number"
            },
            "D": {
              "type": "number"
            },
            "F": {
              "type": "number"
            }
          },
          "required": [
            "A",
            "B",
            "C",
            "D",
            "F"
          ],
          "additionalProperties": false,
          "description": "Count of graded servers per letter, across the whole corpus."
        }
      },
      "required": [
        "total",
        "byGrade"
      ],
      "additionalProperties": false,
      "description": "Always covers the full graded corpus, independent of `grade`, `limit`, or `offset`."
    }
  },
  "required": [
    "total",
    "servers",
    "summary"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
🟢request_grade(server_ref)

Hosted grading is discontinued. This tool returns gone. Existing published grades remain available via check_server / list_servers. To grade a server yourself, run the open harness: npx -y -p @polygraphso/litmus polygraphso-litmus litmus <server_ref>.

Input Schema

{
  "type": "object",
  "properties": {
    "server_ref": {
      "type": "string",
      "minLength": 1,
      "maxLength": 512,
      "description": "Registry-prefixed server ref: npm/<name>, npm/@scope/<name>, pypi/<name>, or github/<owner>/<repo>, with an optional @version. Example: npm/@modelcontextprotocol/server-filesystem"
    }
  },
  "required": [
    "server_ref"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}

Output Schema

{
  "type": "object",
  "properties": {
    "status": {
      "type": "string",
      "const": "queued"
    },
    "server_ref": {
      "type": "string",
      "description": "The server ref that was recorded."
    },
    "created": {
      "type": "boolean",
      "description": "false if the server was already recorded."
    },
    "demand": {
      "type": "number",
      "description": "How many times this server has been requested."
    },
    "requestId": {
      "type": [
        "string",
        "null"
      ],
      "description": "The recorded request's id."
    },
    "statusUrl": {
      "type": [
        "string",
        "null"
      ],
      "description": "Poll for grading progress (unpaid, grading, graded, failed); check_server also reflects the published result."
    },
    "payment": {
      "type": "object",
      "properties": {
        "required": {
          "type": "boolean",
          "description": "false when the fee is already paid or authorized."
        },
        "usdPrice": {
          "type": "number",
          "description": "The one-time fee, in USD."
        },
        "payUrl": {
          "type": [
            "string",
            "null"
          ],
          "description": "Human/browser checkout for this request, paid in $POLYGRAPH."
        },
        "x402Url": {
          "type": "string",
          "description": "The agent payment endpoint. POST the same request body here; a bare POST returns a 402 with the exact payment requirements, and a retry with an X-PAYMENT header pays it."
        },
        "network": {
          "type": "string",
          "description": "CAIP-2 chain id the x402 payment settles on: eip155:8453 (Base mainnet)."
        },
        "asset": {
          "type": "string",
          "description": "The token the x402 rail expects: USDC."
        }
      },
      "required": [
        "required",
        "usdPrice",
        "payUrl",
        "x402Url",
        "network",
        "asset"
      ],
      "additionalProperties": false,
      "description": "How grading is paid for. The web checkout settles up front in $POLYGRAPH; the x402 rail takes an authorization that is charged only once a grade lands, and a run the harness cannot complete voids it, so nothing is charged. The fee buys the run, never the grade."
    }
  },
  "required": [
    "status",
    "server_ref",
    "created",
    "demand",
    "requestId",
    "statusUrl",
    "payment"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded3 tools
verifiedversion not recorded3 tools