Cloudflare MCP portal logs: telling Sume read and paid calls apart

Portal logs record tool activity and Logpush exports it. Which Sume tool names mean spend, so a SIEM rule can flag them without reading arguments.

5 min readSume
All posts

If a Cloudflare MCP portal logs tool activity and Logpush exports it, the cheapest useful Sume alert keys on the tool name, because Sume's paid creates have fixed names. Flag generate_image, generate_video, music_create, tts_create, stt_create, image_upscale_create, rmbg_create, video_upscale_create, kling-motion-control_create, and the avatar creates, and treat jobs_list, jobs_status, jobs_wait, jobs_result, and the catalog reads as quiet.

Cloudflare says Access logs tool, prompt, and resource activity for the portal and that Logpush exports portal activity to external storage or a SIEM (read 2026-10-03) in its GA changelog. That page does not list the log fields, so check your own export before relying on any field other than what you see in it. The tool names come from MCP tools and gates.

A name-based rule set

Sume documents which hosted tools require an idempotency_key (writes and paid) and which are read-only. Live tool ids use underscores; dotted aliases such as tools.list still resolve, so a rule should normalize both forms before matching.

Sume tool classes for a log rule, read 2026-10-03
ClassExamplesSuggested severity
Paid creategenerate_image, generate_video, music_create, tts_createHigh: can spend
Write, unbilledjobs_cancel, assets_create, crawl_siteMedium
Readjobs_status, jobs_wait, jobs_result, balance_get, usage_getLow
Discoverytools_list, tools_schema, mcp_healthInfo

What the log cannot tell you

A tool name tells you a paid call was attempted, not that it spent. Sume treats idempotency_key as dedup, not approval, so a replayed key is one job, not two. Spend is decided by wallet and admission, and a dry_run=true call is a preview that does not submit the job.

So pair the log rule with a read on the Sume side. usage_get and balance_get are read tools, and jobs_list shows what was actually created. Reconcile the alert against those before treating it as a spend event.

  • Alert on a paid tool name, then check jobs_list for the job that resulted.
  • Count alerts per session rather than per call, since one scripted fan-out makes many calls.
  • Never log OAuth tokens or API keys; Sume tells you to rotate a key that appears in logs.

A normalizer for the rule

This small function maps a logged name to a class, handling the dotted alias form. Tune the sets to your own list from tools_list.

PAID = {"generate_image", "generate_video", "music_create", "tts_create",
        "stt_create", "image_upscale_create", "rmbg_create",
        "video_upscale_create", "kling-motion-control_create"}
WRITE = {"jobs_cancel", "assets_create", "assets_upload_url",
         "assets_complete", "crawl_site"}

def classify(name: str) -> str:
    n = name.replace(".", "_")
    if n in PAID or n.startswith("avatar"):
        return "paid" if n.endswith("_create") or n in PAID else "read"
    if n in WRITE:
        return "write"
    return "read"

if __name__ == "__main__":
    for t in ("generate.image", "jobs_wait", "jobs_cancel", "avatars_create"):
        print(t, classify(t))

Note the avatar branch: avatars_list and avatars_search are reads, while avatars_create is paid, which is why the function checks the suffix. For a client-side counterpart that blocks the same names before they leave the machine, see the PreToolUse hook example.

Turning the rule into a weekly review

A name rule only earns its keep if someone looks at what it flags. A simple routine works: once a week, count paid-class calls by session, pick the three largest, and open the matching jobs in jobs_list. If the jobs match the work people say they did, you are done in ten minutes. If a session shows many calls and few jobs, that points to retries or refused calls, and the idempotency_key practice explains why a retry should not double-bill.

If a session shows jobs nobody remembers, the cause is usually a shared key or a long-lived agent. That is the point to move the person from a shared API key to their own OAuth grant, where the default is read-only and Write is opt-in. The log is evidence for that decision, not a verdict.

Keep the retention question separate: how long a SIEM holds portal logs is your policy, and nothing in Sume's docs depends on it. Sume job records are the source of truth for what was created.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume