{
  "openapi": "3.1.1",
  "info": {
    "title": "Agent Permission Graph API",
    "version": "1.0.0",
    "summary": "See what your AI agent can reach: MCP servers, commands, files, network and secrets – with risks.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://agentpermissiongraph.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "See what your AI agent can reach: MCP servers, commands, files, network and secrets – with risks.",
        "description": "Paste an agent or MCP client configuration (Claude Desktop, Claude Code, Cursor, Windsurf, Cline, VS Code mcp.json, Zed) plus optional allow/deny rules and file roots. The tool draws a graph agent → servers → capabilities (commands executed, filesystem paths, network endpoints, secrets by name only) and flags risks: plaintext secrets, tokens on the command line, whole-disk or home-directory access, credential folders, unpinned packages, privileged containers, remote servers without auth or TLS, and auto-approve settings. Secret values are never shown.\n\nMethodology:\n- Recognised shapes: mcpServers (Claude Desktop, Claude Code, Cursor, Windsurf, Cline), servers (VS Code mcp.json), mcp.servers (VS Code settings), context_servers (Zed). JSONC comments and trailing commas are accepted. Per server: command/args/env/cwd (stdio) or url/serverUrl/httpUrl/headers (remote), disabled, autoApprove/alwaysAllow, trust.\n- Capabilities: the executed command (and the package/image for npx, uvx, pipx, bunx, docker), filesystem paths in arguments and docker volume mounts, URLs, and secrets – environment variables and headers whose NAME looks like a credential.\n- Secrets are identified by name (KEY, TOKEN, SECRET, PASSWORD…) and by well-known token formats (sk-, ghp_, github_pat_, xox*, AKIA, glpat-, AIza, JWTs, private keys, URL credentials). Values are never output: they are replaced by ***. References like ${input:…}, ${env:…}, $VAR and placeholders do not count as plaintext.\n- Findings: tokens in args (visible in the process list), plaintext secrets in config, wide roots (/, ~, $HOME, C:\\, /Users…), credential folders (~/.ssh, ~/.aws…), shells, unpinned packages/images, privileged containers or docker.sock, remote servers over HTTP or without auth headers, and auto-approve rules (incl. allow rules such as mcp__server__*).\n- The graph shows up to 60 nodes; extra capabilities per server are collapsed into a “+N more” node (full lists are in the result).",
        "tags": [
          "ai-infra"
        ],
        "x-mcp-tool": "agent_permission_graph",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentPermissionGraphInput"
              },
              "examples": {
                "example1": {
                  "summary": "Claude Desktop config with typical mistakes (dummy secrets)",
                  "value": {
                    "config": "{\n  \"mcpServers\": {\n    \"filesystem\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"@modelcontextprotocol/server-filesystem\",\n        \"/Users/alex\",\n        \"/Users/alex/Desktop\"\n      ]\n    },\n    \"github\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"@modelcontextprotocol/server-github@2025.4.8\"\n      ],\n      \"env\": {\n        \"GITHUB_PERSONAL_ACCESS_TOKEN\": \"ghp_EXAMPLEexampleEXAMPLEexample0000\"\n      }\n    },\n    \"postgres\": {\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\",\n        \"-i\",\n        \"--rm\",\n        \"-e\",\n        \"DATABASE_URL\",\n        \"mcp/postgres\",\n        \"--api-key\",\n        \"sk-EXAMPLE0000000000000000\"\n      ],\n      \"env\": {\n        \"DATABASE_URL\": \"${env:DATABASE_URL}\"\n      }\n    },\n    \"shell\": {\n      \"command\": \"bash\",\n      \"args\": [\n        \"-c\",\n        \"python3 ~/tools/shell_server.py\"\n      ],\n      \"autoApprove\": [\n        \"run_command\"\n      ]\n    },\n    \"docs\": {\n      \"type\": \"http\",\n      \"url\": \"https://mcp.example.com/mcp\"\n    }\n  }\n}",
                    "allowTools": [
                      "mcp__github__*"
                    ],
                    "roots": [
                      "/Users/alex/projects"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentPermissionGraphResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "AgentPermissionGraphInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "config": {
            "title": "Agent / MCP client configuration (JSON or JSONC)",
            "description": "Secret values are masked and never returned. You can replace them with dummy values before pasting.",
            "type": "string",
            "maxLength": 500000
          },
          "allowTools": {
            "title": "Allowed / auto-approved tool rules (optional)",
            "description": "One per line, e.g. mcp__github__create_issue, github.*, filesystem/*.",
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 100
          },
          "denyTools": {
            "title": "Denied tool rules (optional)",
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 100
          },
          "roots": {
            "title": "File roots exposed by the client (optional)",
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 20
          }
        },
        "required": [
          "config"
        ]
      },
      "AgentPermissionGraphResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "client",
              "servers",
              "findings",
              "graph"
            ],
            "properties": {
              "client": {
                "type": "string"
              },
              "servers": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "name",
                    "transport",
                    "disabled",
                    "command",
                    "runner",
                    "package",
                    "args",
                    "urls",
                    "paths",
                    "envNames",
                    "secretEnvNames",
                    "headerNames",
                    "autoApprove",
                    "risk"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "transport": {
                      "type": "string",
                      "enum": [
                        "stdio",
                        "http",
                        "sse",
                        "unknown"
                      ]
                    },
                    "disabled": {
                      "type": "boolean"
                    },
                    "command": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "runner": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "package": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "args": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Arguments with secret values replaced by ***."
                    },
                    "urls": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "paths": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "envNames": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Environment variable NAMES only."
                    },
                    "secretEnvNames": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "headerNames": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "autoApprove": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "risk": {
                      "type": "string",
                      "enum": [
                        "high",
                        "medium",
                        "low"
                      ]
                    }
                  }
                }
              },
              "findings": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "severity",
                    "server",
                    "finding"
                  ],
                  "properties": {
                    "severity": {
                      "type": "string",
                      "enum": [
                        "high",
                        "medium",
                        "low",
                        "info"
                      ]
                    },
                    "server": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "finding": {
                      "type": "string"
                    }
                  }
                }
              },
              "graph": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "nodes",
                  "edges"
                ],
                "properties": {
                  "nodes": {
                    "type": "integer"
                  },
                  "edges": {
                    "type": "integer"
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}