Yichus / Reference / API MCP tools

api_permissions

Compare declared Yichus/Service route permissions to inferred CRUD from handler effects. A missing or mismatched permission is separate from row access and caller authentication: api_access_check checks resource policies; the server engine enforces route identity and roles.

Kind: Permissions. Origin: Yichus/Mcp::catalog.

CLI: yichus service permissions — declared against inferred permissions, the CLI over files.

Parameters

Example

This response was produced by calling this tool with the displayed request when these docs were generated. Analysis examples use the owner-scoped notes specimen; scaffold examples supply a resource specification.

Request

{
  "sources": [
    {
      "fileName": "notes-api.bosatsu",
      "source": "package Demo/Service/NotesApi\n\n# Owner-scoped notes API. One row per caller, keyed by Principal.user_id.\n# `yichus api verify` / api_access_check prove the scoping from Matchless IR.\n\nfrom Yichus/IO import IO, flat_map\nfrom Yichus/Access import Principal, AccessRule, AccessSpec, OwnerScoped\nfrom Yichus/Data import Db, Table, table, db_read, db_write, db_delete\nfrom Yichus/Service import handler, route, service_def, ReadPerm, WritePerm, DeletePerm\n\nexport (notes_api, access_rules, Note())\nexposes (Yichus/Access, Yichus/Service)\n\nstruct Note(title: String)\n\naccess_rules = AccessSpec([\n  AccessRule(\"notes\", OwnerScoped),\n])\n\ndef notes_table(db: Db) -> Table[List[Note]]:\n  table(db, \"notes\")\n\ndef list_notes(db: Db, p: Principal) -> IO[List[Note]]:\n  Principal(uid, _) = p\n  db_read(notes_table(db), uid)\n\ndef put_notes(db: Db, p: Principal, items: List[Note]) -> IO[List[Note]]:\n  Principal(uid, _) = p\n  db_write(notes_table(db), uid, items)\n\ndef add_note(db: Db, p: Principal, item: Note) -> IO[List[Note]]:\n  Principal(uid, _) = p\n  items <- flat_map(db_read(notes_table(db), uid))\n  db_write(notes_table(db), uid, [item, *items])\n\ndef clear_notes(db: Db, p: Principal) -> IO[Unit]:\n  Principal(uid, _) = p\n  db_delete(notes_table(db), uid)\n\nnotes_api = service_def(\n  \"notes\",\n  [\n    route(\"/notes\", handler(\"list_notes\", list_notes), [ReadPerm(\"notes\")]),\n    route(\"/notes/put\", handler(\"put_notes\", put_notes), [WritePerm(\"notes\")]),\n    route(\"/notes/add\", handler(\"add_note\", add_note), [ReadPerm(\"notes\"), WritePerm(\"notes\")]),\n    route(\"/notes/clear\", handler(\"clear_notes\", clear_notes), [DeletePerm(\"notes\")]),\n  ]\n)\n"
    }
  ]
}

Response

{
  "ok": true,
  "tool": "api_permissions",
  "routes": [
    {
      "path": "/notes",
      "handler": "list_notes",
      "authority": "authenticated",
      "requiredRoles": [],
      "permissions": [
        "Read(notes)"
      ]
    },
    {
      "path": "/notes/put",
      "handler": "put_notes",
      "authority": "authenticated",
      "requiredRoles": [],
      "permissions": [
        "Write(notes)"
      ]
    },
    {
      "path": "/notes/add",
      "handler": "add_note",
      "authority": "authenticated",
      "requiredRoles": [],
      "permissions": [
        "Read(notes)",
        "Write(notes)"
      ]
    },
    {
      "path": "/notes/clear",
      "handler": "clear_notes",
      "authority": "authenticated",
      "requiredRoles": [],
      "permissions": [
        "Delete(notes)"
      ]
    }
  ],
  "findings": [
    {
      "path": "/notes",
      "handler": "list_notes",
      "unresolvedResources": false,
      "kind": "match",
      "declared": [
        "Read(notes)"
      ],
      "inferred": [
        "Read(notes)"
      ]
    },
    {
      "path": "/notes/put",
      "handler": "put_notes",
      "unresolvedResources": false,
      "kind": "match",
      "declared": [
        "Write(notes)"
      ],
      "inferred": [
        "Write(notes)"
      ]
    },
    {
      "path": "/notes/add",
      "handler": "add_note",
      "unresolvedResources": false,
      "kind": "match",
      "declared": [
        "Read(notes)",
        "Write(notes)"
      ],
      "inferred": [
        "Read(notes)",
        "Write(notes)"
      ]
    },
    {
      "path": "/notes/clear",
      "handler": "clear_notes",
      "unresolvedResources": false,
      "kind": "match",
      "declared": [
        "Delete(notes)"
      ],
      "inferred": [
        "Delete(notes)"
      ]
    }
  ]
}

Run tools in the browser: api-mcp.html?webmcp=1.

Read the result according to this tool’s scope: static checks, bounded execution checks, and descriptive diagrams answer different questions. A successful call is not a general approval of the program. The safety and permissions guide compares the checks and provides editable ownership, guard, and role examples.