mcp-proof / effect evidence
Testbed variant with planted inconsistency: silent-keymint.
| Check | Level | Result | Details |
|---|---|---|---|
| EFF-01 | MUST | ✗ FAIL | readOnlyHint is honoured (no observed external write) get_note declared readOnly but observed 1 change(s): create api_keys/key_0001 Fix: A tool annotated readOnlyHint=true must not create, update or delete external state; remove the annotation or stop the write. |
| EFF-02 | MUST | ✓ PASS | observed deletes are consistent with destructiveHint (explicit false contradicted ⇒ fail; unset ⇒ spec default true) all 1 observed deleted object(s) consistent with declared/default destructive semantics: 1 call(s) from tools declaring destructiveHint=true |
| EFF-03 | SHOULD | – SKIP | idempotentHint is honoured (a repeated identical call is a no-op) no idempotentHint-annotated (non-readOnly) tool was called twice with identical arguments |
| EFF-06 | SHOULD | ! WARN | created authority does not outlive its authorizing grant get_note→api_keys/key_0001 authorized_by grant_root but depends_on nothing revocable (object not currently effective; no live dependency to probe); create_api_key→api_keys/key_0002 authorized_by grant_root but depends_on ['self:api_keys:key_0002'] (survives revoking grant:grant_root; revoking self:api_keys:key_0002 disables it); create_webhook→webhooks/wh_0001 authorized_by grant_root but depends_on ['self:webhooks:wh_0001'] (survives revoking grant:grant_root; revoking self:webhooks:wh_0001 disables it); create_share_link→share_links/share_0001 authorized_by grant_root but depends_on ['self:share_links:share_0001'] (survives revoking grant:grant_root; revoking self:share_links:share_0001 disables it) Fix: An object minted under a grant should stop working when that grant is revoked; a probe found it still effective, so revocation of the delegation will not disable it (residual authority). |
Declared annotations beside the effect an independent observer saw, the response a response-only auditor would have read, the objects that resulted, and the probe's authority / dependency verdict.
| Call | Declared | Observed effect | Response seen | Objects / persistence | Authority (probed) | Lineage |
|---|---|---|---|---|---|---|
save_note {"title": "welcome", "body": "hello world"} | — | create observed observed 1 change(s): create notes/welcome | saved 'welcome' | create notes/welcome ephemeral | not authority probed probe: notes rows carry no credential to exercise | by: grant_root needs: — |
ping {} | readOnlyHint=True | none observed no external object changed between before/after snapshots | ok | — — | not authority observed no object created | by: — needs: — |
list_notes {} | readOnlyHint=True | none observed no external object changed between before/after snapshots | ["welcome"] | — — | not authority observed no object created | by: — needs: — |
get_note {"title": "welcome"} | readOnlyHint=True | create observed observed 1 change(s): create api_keys/key_0001 | hello world | create api_keys/key_0001 persistent | authority-bearing probed probe: exercised api_keys.secret: server auth rule accepts it (status/expiry checked) | by: grant_root needs: nothing revocable (residual) |
create_api_key {"label": "ci"} | — | create observed observed 1 change(s): create api_keys/key_0002 | {"key_id": "key_0002", "secret": "sk_test_e8f8b10f7813edd… | create api_keys/key_0002 persistent | authority-bearing probed probe: exercised api_keys.secret: server auth rule accepts it (status/expiry checked) | by: grant_root needs: self:api_keys:key_0002 |
create_webhook {"url": "https://example.com/hook"} | — | create observed observed 1 change(s): create webhooks/wh_0001 | {"webhook_id": "wh_0001", "secret": "sk_test_fcbfb6a77963… | create webhooks/wh_0001 persistent | authority-bearing probed probe: exercised webhooks.secret: server auth rule accepts it (status/expiry checked) | by: grant_root needs: self:webhooks:wh_0001 |
create_share_link {"title": "welcome"} | — | create observed observed 1 change(s): create share_links/share_0001 | {"share_id": "share_0001", "token": "sk_test_9268f02577b5… | create share_links/share_0001 persistent | authority-bearing probed probe: exercised share_links.token: server auth rule accepts it (status/expiry checked) | by: grant_root needs: self:share_links:share_0001 |
revoke_api_key {"key_id": "key_0001"} | destructiveHint=True | update observed observed 1 change(s): update api_keys/key_0001 | revoked 1 key(s) | update api_keys/key_0001 — | not authority observed call created no object to bear authority | by: — needs: — |
cleanup_notes {} | destructiveHint=True | none observed no external object changed between before/after snapshots | cleaned 0 temp note(s) | — — | not authority observed no object created | by: — needs: — |
delete_note {"title": "welcome"} | destructiveHint=True | delete observed observed 1 change(s): delete notes/welcome | deleted 1 note(s) | delete notes/welcome — | not authority observed call created no object to bear authority | by: — needs: — |