Box Admin Analytics MCP

io.github.shigechikaPublished by GitHub account shigechikav0.12.0Updated Nov 3, 2026

MCP server for Box admin-log analytics — external-sharing visibility, read-only

Overview

AI-generated overview

Read-only Box admin-log analytics server that surfaces external file sharing and access from a Box admin's viewpoint.

What you can do
  • Check server health, auth mode and whether the admin_logs scope is granted
  • Read raw enterprise admin_logs events and aggregate external downloads and previews, optionally filtered by accessor login
  • Enumerate external collaborators, open shared links and rank internal owners by external exposure
  • List one folder's items with uploader and links, and optionally read extracted text from files in allowlisted folders
  • Look up a single Box account by exact login and produce a combined daily brief
When to use it
For Box admins or security teams who want an assistant to spot external sharing and outside access across the enterprise, trace what a specific external account downloaded, or answer help-desk questions about a folder's attachments or an account's status.
Requirements
Runs locally as a Python package (pip or uv) over stdio. Needs a Box platform app with Client ID and secret in BOX_CLIENT_ID and BOX_CLIENT_SECRET, plus BOX_ALLOWED_DOMAINS; CCG mode also needs BOX_ENTERPRISE_ID. OAuth mode requires a one-time browser authorization and a token cache file. The app needs the Manage enterprise properties scope, plus Read all files and folders and Manage users for the enumeration and lookup tools.
Before you install
Requires Box admin credentials and a client secret; keep them out of committed config files. It reads enterprise-wide event logs, folder contents and user directory data, so it exposes who shares and accesses what. The optional read_file tool returns file text and is only enabled for folders named in BOXADM_READ_FOLDER_IDS. Treat findings as a risk ranking, not alerts, and run it as authorized monitoring with defined viewers and retention.

Installation

In SourceWeft

  1. Open Box Admin Analytics MCP in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

boxadm-mcp

English | 日本語

MCP (Model Context Protocol) server that surfaces external file flow from a Box admin's point of view. It reads Box's enterprise event log (admin_logs) to highlight "who shares a lot with the outside" and "which files get accessed from outside" — an early-warning signal for leakage, not a general-purpose file browser.

Documentation: https://shigechika.github.io/boxadm-mcp/

Read-only: it never revokes shares, deletes files, or otherwise mutates anything — it only surfaces risk. This is a different tool from a general-purpose Box file MCP (the official Box MCP, or the claude.ai Box connector): those operate on a user's own files and cannot see enterprise events, which is exactly what this server is for.

Named after the admin-console viewpoint (boxadm = Box admin), sibling of gwsadm-mcp.

Features

ToolCategoryDescription
health_check—version + auth_mode + Box auth + admin_logs scope probe + configured domain allowlist. Reports needs-login when not yet authenticated (OAuth mode)
recent_admin_eventsDiagnosticRaw recent enterprise events (for checking event types/fields). Supports manual pagination via stream_position
external_access_eventsAccess (events, enterprise-wide)Aggregates external DOWNLOAD/PREVIEW within a window: top external accessors, top externally-accessed files, share-link count. Pass created_by_logins for DLP tracing of a specific account
external_collaboratorsExposure (enumeration)Lists external collaborators (outside-org login or external invite email)
public_shared_linksExposure (enumeration)Lists items shared with an open (anyone-with-the-link) share link
top_external_sharersExposure (enumeration)Ranks internal owners by external exposure (external collabs + public links)
list_folder_itemsOne folder (ls)Names, upload time, size, who uploaded, and a direct link per item, plus the folder's owner and path. Filter by uploader or upload-time window. Reads no file content
read_fileOne file (cat), opt-inThe text Box extracted from one file in a folder named by BOXADM_READ_FOLDER_IDS: spreadsheets as tab-separated cells, documents and PDFs as text. Not registered unless that variable is set; images and archives return metadata only
get_userAccount state (lookup)One account by its exact login: status, role, enterprise, quota, timestamps. Answers "is this account disabled?" without an admin console
daily_briefCombinedMorning summary combining access (events) and exposure (enumeration)

Auth model

Two modes, selected via BOX_AUTH_MODE:

  • oauth — OAuth 2.0 (user auth). An admin authorizes once in a browser; the refresh token keeps it running unattended after that.
  • ccg — Client Credentials Grant (server-to-server). Simpler to run unattended if your Box tenant has an available server-authentication app slot.

admin_logs (enterprise events) is readable in either mode, provided the authorizing/impersonated user is an admin and the app has the Manage enterprise properties scope.

OAuth setup (one-time, by a Box admin)

  1. Developer Console → Create Platform App → Custom App → User Authentication (OAuth 2.0)
  2. Redirect URI: http://localhost:8787/callback
  3. Application Scopes: check Manage enterprise properties (required for admin_logs). Add Read all files and folders too if you also want collaboration/share-link enumeration, and Manage users if you want the get_user lookup (each scope change requires re-consent via boxadm-mcp auth)
  4. Enable the app in the Admin Console (unpublished apps are disabled by default under most tenant policies)
  5. Note the Client ID / Client Secret
  6. First login: set BOX_AUTH_MODE=oauth etc., then run boxadm-mcp auth → authorize in the browser → a token cache is written to ~/.config/boxadm-mcp/token.json (chmod 600)

Setup

bash
# uvuv pip install boxadm-mcp
# pippip install boxadm-mcp

Or from source:

bash
git clone https://github.com/shigechika/boxadm-mcp.gitcd boxadm-mcp
# uvuv sync
# pippip install -e .

Configuration

VariableRequiredDescription
BOX_AUTH_MODEoauth / ccg (default ccg). Any other value falls back to ccg; health_check reports the mode in effect, so a typo shows up there as ccg rather than as what was typed
BOX_CLIENT_ID✓App Client ID
BOX_CLIENT_SECRET✓App Client Secret
BOX_ENTERPRISE_IDccg modeEnterprise ID (CCG subject; not needed for oauth)
BOX_OAUTH_REDIRECT_URIoauth redirect. Default http://localhost:8787/callback
BOX_TOKEN_CACHEoauth token cache path. Default ~/.config/boxadm-mcp/token.json
BOX_API_BASEDefault https://api.box.com
BOX_SCAN_CONCURRENCYParallel per-folder lookups in the enumeration scan. Default 8, clamped 1–32
BOX_SCAN_DEADLINESoft wall-clock budget (seconds) for one enumeration scan. Default 45; 0/negative disables it. When hit, the scan returns a disclosed partial (capped=true) instead of running until the tool call times out
BOX_HTTP_TIMEOUTPer-request HTTP timeout (seconds). Default 30. Lower it (with BOX_SCAN_DEADLINE) so one slow endpoint can't stretch the final in-flight scan batch past a gateway timeout
BOXADM_READ_FOLDER_IDSFolders whose files read_file may read (comma-separated folder ids; 0 is refused). Unset: read_file is not registered. One bad entry turns it off and makes health_check degraded
BOX_ALLOWED_DOMAINS✓Internal email domains (comma-separated). No default — every address counts as external until you set this

Keep secrets out of .mcp.json (e.g. in a local env file sourced before launch); .mcp.json itself can reference ${BOX_CLIENT_ID}-style variables and be safely committed.

Scope and limits

  • Access tools (external_access_events, and the access half of daily_brief) read the enterprise-wide events stream. Hitting max_events sets capped: true (oldest-first scan).
  • Exposure (enumeration) tools only see folders visible to the co-admin account (not a guaranteed 100% of the enterprise), plus max_folders/max_depth limits (surfaced via capped). Requires the Read all files and folders scope.
  • The scan fans its per-folder lookups out concurrently (BOX_SCAN_CONCURRENCY), since Box has no enterprise-wide collaboration listing — this widens how many folders finish inside a tool-call timeout, but coverage is still bounded by the caps. The read path retries 429 (honoring Retry-After) and transient 5xx with jittered backoff, so a passing throttle recovers instead of degrading coverage; a folder dropped by a per-folder API error that outlasts those retries (e.g. a persistent 403) is counted in fetch_errors: coverage is complete only when capped is false and fetch_errors is 0.
  • Enumeration tools share a short-TTL scan memo across calls; public_shared_links skips collaboration calls entirely (optimization).
  • get_user reads the enterprise user directory instead — one request, no paging, and structurally not an enumerator (it answers about the login you pass and nothing else). Its capped flag discloses a truncated search, so a found: false from a truncated result reads as inconclusive rather than negative.

DLP tracing (reverse-lookup by accessor)

To answer "what did this external account download": pass created_by_logins (comma-separated logins) to external_access_events. It keeps only that accessor's events and returns per-file detail (matched_events: item id/name, owner, size in bytes+GB, timestamp, event_type, whether it was via a share link).

external_access_events(since_hours=26, created_by_logins="[email protected]")
  • Since the accessor could appear anywhere in the window, a filtered call auto-extends the scan cap to up to 50,000 events (oldest-first) — but only matching events are kept, so memory stays bounded.
  • In this mode the response carries events_matched (match count) instead of events_scanned (no running total is kept; use capped to judge coverage). capped: true means the window wasn't fully scanned — raise max_events.
  • Box's admin_logs API has no created_by query parameter, so this is a client-side filter (fetch_admin_events(created_by_logins=...)).

One folder's contents (list_folder_items)

An ls, not a cat. Written for a help desk answering a submitted enquiry whose attachments land in a Box folder: instead of a human going to find that folder, the answer names the attachments and links straight to them. File content is never read, and no shared link is ever created — an existing one is reported because it is an exposure finding, not a convenience.

Who uploaded an item is not where you would look for it. For an upload made through a File Request, Box records no user at all: created_by and modified_by both read "Anonymous User", and owned_by is the application's own service account — identical on every row. The only field carrying the submitter is uploader_display_name, and despite its name the value observed in practice was an email address. It is therefore matched as an opaque string (exact, case-insensitive) and never parsed or validated as an address. For a file uploaded by a signed-in user the reverse holds, so created_by is the fallback.

Ordering and time bounds are computed here rather than by Box:

  • Box documents sort as the second sort attribute — items order by type first, so a subfolder precedes every file regardless of date. Measured against a real folder, sort=date also matched neither created_at nor modified_at order, so it cannot honestly be presented as "newest".
  • since / until are compared as instants, not text. Box stamps items in its own UTC offset while a caller asks in theirs, so a lexicographic comparison is wrong by that difference at every date boundary and silent about it. Both bounds must carry an offset; a bare date is refused rather than guessed.

limit bounds what is RETURNED, not what is searched — a full page is fetched first, so an uploader's item is found even when it is not among the newest. Truncation is disclosed twice over, because they are different truths: returned vs matched is the caller's own limit, while capped means the folder holds more than one page and a miss is inconclusive rather than negative.

One file's text (read_file, opt-in)

The cat to list_folder_items' ls, for the same help desk: after listing an enquiry's attachments, read the one it is about. It is registered only when BOXADM_READ_FOLDER_IDS names one or more folders, and every call is refused unless Box reports the file's parent, or one of its ancestors, as one of those folders. The account behind this server can see far more than one use needs; this keeps the reader to the folders you named.

The text is Box's own extracted_text representation, so it needs only preview rights: nothing is downloaded or parsed here, and an account that may not download a file can still read it. Spreadsheets arrive as tab-separated cells, documents and PDFs as their text. A file Box has no text for (an image, an archive) returns its metadata with text: null; a file Box has not processed yet is waited for up to 20 seconds. The text is capped at max_chars (default 20000, at most 100000), with truncated saying whether it was cut.

The bearer token goes only to the configured API base and to Box's download hosts (https, a *.boxcloud.com name, a path under /api/2.0/), where Box serves the text: a representation URL is followed only when it points at one of these, and any further redirect goes without the Authorization header. One call is bounded at about 45 seconds, waiting and retries included, and the row it returns is the same one list_folder_items builds for the file. Treat the file name and the text as written by the uploader — evidence to quote, never instructions.

Per-account lookup (get_user)

Every other tool reads the event stream or walks folders, so an account with no recent activity cannot be asked about at all. get_user answers directly — "is this account disabled, and is its quota full?" — in one request:

get_user(login="[email protected]")

login is the account's full Box login (an email address), matched exactly and case-insensitively. That matching is the point, not an implementation detail: Box's underlying filter_term is a prefix search over display name and login, so the endpoint readily returns a colleague whose name starts with the same letters. Only an exact login match lands in user; everything else is counted in other_prefix_hits and never identified. A term that is not email-shaped is refused before the request is made — filter_term has no minimum length, so a one-character term would otherwise return a page of real accounts.

One drift it cannot find: the same person under a second login at another domain. filter_term prefix-matches the whole term, so [email protected] can never return [email protected]; that would need a search on the local part alone, which is the directory-wide prefix search this tool refuses by design.

FieldMeaning
foundThe only field that says whether the account exists. false is a normal answer, not an error
userThe account when found, else null: status, role, enterprise, space_used / space_amount, created_at, modified_at
other_prefix_hitsCount of further prefix matches. A count only: those are different accounts and are deliberately not identified
cappedThe search was truncated, so found: false is inconclusive rather than negative
search_hits, noteHow many entries came back, and a plain-language reading

[!NOTE] In oauth mode this endpoint's requirement is verified end-to-end: the app must hold the "Manage users" application scope. Without it /2.0/users answers 403 even when the authorising user is a co-admin who can manage users; with it, 200. Two caveats: the effective permission is still capped by the authorising user's own role, and a scope added in the Developer Console does not reach tokens minted from an existing refresh token — the app must be re-authorised interactively (boxadm-mcp auth) before the new scope takes effect. Under ccg the endpoint remains unverified. A permission failure returns likely_cause saying all of this rather than a bare HTTP status.

Usage

Claude Code (plugin)

This repository doubles as a single-plugin marketplace, so Claude Code can install the server for you:

/plugin marketplace add shigechika/boxadm-mcp/plugin install boxadm-mcp@boxadm-mcp

The plugin launches uvx boxadm-mcp and reads the same environment variables described in Configuration; export BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID (ccg mode), and BOX_ALLOWED_DOMAINS before starting Claude Code. The plugin ships with BOX_AUTH_MODE=ccg by default — switch to oauth only after running boxadm-mcp auth once yourself, since the plugin cannot provision that browser step or the resulting token cache file for you.

uvx must be on the PATH of the process that runs Claude Code — a login shell usually has it, but a GUI-launched app may not; install uv system-wide if the plugin fails to start.

Claude Code (manual)

Add to .mcp.json:

json
{  "mcpServers": {    "boxadm-mcp": {      "type": "stdio",      "command": "boxadm-mcp",      "env": {        "BOX_AUTH_MODE": "oauth",        "BOX_CLIENT_ID": "${BOX_CLIENT_ID:-}",        "BOX_CLIENT_SECRET": "${BOX_CLIENT_SECRET:-}",        "BOX_ALLOWED_DOMAINS": "example.com"      }    }  }}

Codex

bash
codex mcp add boxadm-mcp \  --env BOX_AUTH_MODE=oauth \  --env BOX_CLIENT_ID=your-client-id \  --env BOX_CLIENT_SECRET=your-client-secret \  --env BOX_ALLOWED_DOMAINS=example.com \  -- boxadm-mcp

Any other MCP client that launches stdio servers works the same way: give it boxadm-mcp as the command and set the BOX_* variables above in its environment.

CLI Options

bash
boxadm-mcp auth       # OAuth first-time login (opens a browser)boxadm-mcp --version  # Print version and exitboxadm-mcp            # Start MCP server (STDIO, default)

Development

bash
git clone https://github.com/shigechika/boxadm-mcp.gitcd boxadm-mcp
# uvuv sync --devuv run pytest -vuv run ruff check .
# pippython3 -m venv .venv.venv/bin/pip install -e . && .venv/bin/pip install pytest respx ruff.venv/bin/pytest -v.venv/bin/ruff check .

Tests never touch Box — respx mocks the CCG/OAuth token endpoint and the admin_logs/enumeration APIs.

Live smoke test

That isolation is the point of the unit tests, and also their limit: they cannot tell you that a tool has stopped returning real data. scripts/smoke_test.py runs every registered tool against the configured enterprise and fails on empty, malformed or error answers:

bash
# needs the same BOX_* environment variables as the serveruv run python scripts/smoke_test.pyuv run python scripts/smoke_test.py --only shared_links --traceback
  • Read-only. Every tool here reads; nothing in Box is changed. A future tool that writes must be listed as state-changing and skipped, and a test enforces that.
  • No payloads in the report. Tool names, statuses and row counts only; server-authored error text is redacted too, since Box errors quote the account or item they were asked about.
  • Bounded. These tools page the event stream and walk the folder tree, so each probe passes explicit small caps instead of the interactive defaults (5000 events, 150 folders) — enforced by a test that finds the bounding parameters from the source.
  • Nothing enterprise-specific in the specs. A test bans address shapes (login, URL, hostname, IPv4, IPv6) and the parameters that carry an account name, because this repository is public. Two literals identify nobody and are allowed: folder id 0, the root folder in every enterprise, and the made-up term get_user is probed with — an account that cannot exist, so the probe asserts the not-found path rather than naming a real person.
  • An empty answer passes: no public links and no external collaborators is the desired state, so probes assert the accounting envelope (count, folders_scanned, window_hours) rather than a row count.
  • CI enforces the cheap half: a tool registered without a probe spec fails the build (tests/test_smoke_probes.py), so adding a tool forces the question "how would we know it works?".
  • scripts/smoke_harness.py is the engine and holds no Box knowledge: it is kept identical across the servers that share it, so fix engine bugs once and sync the file rather than patching this copy.

Releasing

Releases are automated with release-please. Merging Conventional Commits (feat:, fix:, …) to main keeps a release PR open with the next version and changelog. Merging that PR tags vX.Y.Z and publishes a GitHub Release, whose release: published event triggers the release workflow to build and publish to PyPI and the MCP Registry. release-please owns the version in boxadm_mcp/__init__.py and server.json (do not bump them by hand).

[!IMPORTANT] The release-please workflow should be given a repository secret RELEASE_PLEASE_TOKEN (a PAT with contents: write + pull-requests: write). The default GITHUB_TOKEN cannot create the Release that triggers the downstream release workflow (GitHub blocks workflow runs triggered by GITHUB_TOKEN), so without the PAT nothing gets published. The workflow falls back to GITHUB_TOKEN when the secret is unset so PR CI keeps working on forks.

Governance

Because this surfaces what users share, run it as authorized information-security monitoring with a clear purpose, a defined set of viewers, and a retention policy. Most external sharing is legitimate (collaborators, vendors), so treat findings as a risk ranking, not an alert queue — build an allowlist of known-OK sharers over time.

License

MIT

Source: README.md at commit d681e13

Tools

9

health_check

Report server version, Box connectivity/auth, and configuration. Call this at session start (or after a tool-call timeout) to confirm the MCP is up, see which version is running, verify the Box enterprise token can be obtained (CCG) and that the ``admin_logs`` event scope is actually granted, and view the org domain allowlist used for external detection. Lightweight: one token request plus a single-row events probe — it does not scan history. Always returns the same keys: ``status`` (healthy / degraded / error), ``service``, ``version``, ``auth_mode`` (ccg / oauth — the mode in effect, so an unrecognised ``BOX_AUTH_MODE`` reads as ``ccg``, which is what the server falls back to), ``box_api_base``, ``enterprise_id``, ``auth`` (ok / error / missing-env / needs-login), ``events_accessible`` (bool), ``allowed_domains``, and ``read_file`` (not-configured / ok / misconfigured: whether the opt-in ``read_file`` tool is on, from ``BOXADM_READ_FOLDER_IDS``; misconfigured makes the status degraded). On a degraded or error result, ``detail`` carries the reason.

Takes no parameters.

recent_admin_events

Fetch recent enterprise ``admin_logs`` events (raw passthrough). Diagnostic/starter tool: returns Box events verbatim so the real event types and field shapes can be confirmed before analytics tools are layered on. For external-sharing work the event types of interest are typically COLLABORATION_INVITE / COLLAB_ADD_COLLABORATOR, SHARED_LINK_CREATED / ITEM_SHARED_CREATE, and DOWNLOAD / PREVIEW. Args: event_types: Comma-separated Box event_type filter (empty = all types). since_hours: Look-back window in hours (default 24). limit: Max events to return in this page (default 100). stream_position: Continue a previous page by passing back the ``next_stream_position`` from the prior call (empty = first page). Box caps a single page at 500, so manual paging is needed to walk a busy window — or use ``external_access_events`` which pages for you.

Parameterslimitevent_typessince_hoursstream_position

external_access_events

Surface external file access (DOWNLOAD / PREVIEW) from enterprise admin_logs. Enterprise-wide (events stream): over the window, flags each access whose actor (``created_by.login``) is outside the org domain allowlist — an external party, or an anonymous open-link visitor (no login) — and whether it came via a shared link. Aggregates to the top externally-accessed files and the top external accessors, so an admin can spot unusual outbound data pulls. Args: since_hours: Look-back window in hours (default 24). max_events: Cap on DOWNLOAD/PREVIEW events scanned (default 5000); the result's ``capped`` flag is true when more existed (never silently truncated). top: How many top files / accessors to return (default 20). created_by_logins: Comma-separated accessor logins to trace (empty = all). When set, switches to DLP-tracing mode (see below). Returns ``window_hours``, ``events_scanned``, ``capped``, ``external_access_count``, ``via_shared_link``, ``top_external_accessors`` (login + count + bytes), and ``top_externally_accessed_files`` (item id/name/ owner + external-access count). On failure returns ``{"error": ...}`` (incl. ``needs-login`` for an expired OAuth session). Notes: - ``via_shared_link`` counts ALL scanned accesses that went through a shared link (internal and external), not just external ones. - Events are scanned oldest-first from the window start. When ``capped`` is true the aggregates reflect only the scanned (earliest) slice, NOT the full window — raise ``max_events`` for a complete picture. - **DLP tracing** (``created_by_logins`` set): scans up to the wider of ``max_events`` and 50000 events (the accessor may sit anywhere in the window) but keeps only that accessor's events, so the answer to "which files did this account pull" is exact and bounded. The result reports ``events_match

Parameterstopmax_eventssince_hourscreated_by_logins

external_collaborators

List external collaborators on Box folders (current state, enumeration). Walks folders the authenticating co-admin user can see (default from the root "All Files") and reports collaborations whose collaborator is outside the org domain allowlist — accepted external users or pending external invites. Useful to review who outside the organization has standing access. Args: root_folder_id: Folder to start from ("0" = the user's root). A Box folder id: decimal digits only, as shown at the end of a Box folder URL. Anything else is refused with ``{"error": ...}`` before any request is made, rather than being reported as an empty result. max_folders: Cap on folders visited (default 150); ``capped`` discloses when coverage was cut short. max_depth: Folder recursion depth (default 1 = top-level folders only). Externally-owned folders (this org is only a guest, not the owner) are out of scope and skipped — we cannot govern their collaborations, and their "external collaborators" are just the owner's own org accounts. They are reported separately under ``skipped_externally_owned`` (never silently dropped) and do not consume the ``max_folders`` budget. Coverage note: limited to content the co-admin user can access (not provably 100% of the enterprise) and to the depth/folders caps. Returns ``folders_scanned``, ``capped``, ``fetch_errors`` (count of folders whose lookup hit an API error that outlasted the client's retries, e.g. a persistent 403 or a sustained throttle — coverage is complete only when ``capped`` is false AND ``fetch_errors`` is 0), ``count``, ``external_collaborators`` (folder, owner, collaborator, role, status, expires_at), and ``skipped_externally_owned`` (folder_id, folder_name, owner). On failure returns ``{"error": ...}``.

Parametersmax_depthmax_foldersroot_folder_id

top_external_sharers

Rank internal owners by their external exposure (enumeration). One traversal (same as external_collaborators / public_shared_links), then ranks internal file/folder owners by how much external exposure they hold: external collaborations + open shared links on content they own. Surfaces the people whose content is most exposed outside the organization. Args: root_folder_id / max_folders / max_depth: traversal bounds (see external_collaborators). top: How many owners to return (default 20). Coverage note: limited to the co-admin user's visible content and the caps. Returns ``folders_scanned``, ``capped``, ``fetch_errors`` (count of folders whose lookup hit an API error; coverage is complete only when ``capped`` is false AND ``fetch_errors`` is 0), and ``top_external_sharers`` (owner, external_collaborations, public_links, total). On failure ``{"error": ...}``.

Parameterstopmax_depthmax_foldersroot_folder_id

get_user

Look up ONE Box account by its exact login (the account's email address). Answers "what is this account's state?" — the question behind a ticket that says "my Box account is disabled". Every other tool here reads the event stream or walks folders, so an account with no recent events is invisible to them; this is one request against the user directory and the only tool that answers about an account directly. Use it when a specific account is named. It cannot list, search or enumerate accounts: it takes one login and answers about that login only. Args: login: The account's full Box login, i.e. its email address (``[email protected]``) — not a display name, not a user id. Matched EXACTLY, case-insensitively. A partial login does not match. This server is downstream of an identity provider, not the master. Read what comes back as "what Box currently believes", and compare it against the IdP's own record (which is authoritative for who the account is). A disagreement is the finding, and is usually drift on the Box side rather than a mistyped address: - ``enterprise`` absent/null — the account is no longer in the enterprise (it has become a free personal account), so enterprise SSO no longer applies to it even though the IdP still authenticates the person. Box classes such an account as *external* and returns it only on a COMPLETE login match, which is exactly what this tool asks for — so it is reachable here, and a partial login would silently lose it. - ``status`` other than ``active`` — the IdP authenticates, Box refuses. - ``is_platform_access_only`` true — an App User, which cannot sign in interactively at all. One drift this tool cannot find for you: the same person under a second login at another domain (an alias, or a duplicate left by a migration). ``filter_term`` prefix-matches the WHOLE term, so a search for ``alice@old

Parametersloginrequired

daily_brief

Morning DLP brief: external access (events) + external-sharing state (enumeration). One call that combines: - **access** (enterprise-wide, events): external DOWNLOAD/PREVIEW in the last ``since_hours``, with top external accessors and top externally-accessed files. - **exposure** (co-admin visible folders, enumeration): current external collaborations, open ("anyone with the link") shared links, and the owners most externally exposed. Reuses the cached folder scan, so calling this alongside the other enumeration tools doesn't re-walk. Args mirror the underlying tools; ``top`` defaults to 5 for a compact summary. Coverage/caps caveats are the same (``capped`` flags + enumeration limited to the co-admin's visible content). On failure returns ``{"error": ...}``.

Parameterstopmax_depthmax_eventsmax_folderssince_hours

list_folder_items

List ONE Box folder's contents, newest first, with who uploaded each item. An ``ls``, not a ``cat``: names, timestamps, sizes, uploader and a direct link per item. File CONTENT is not read and no shared link is ever created. Written for a help desk answering a submitted enquiry whose attachments land in a Box folder. Instead of a human going to find that folder, the answer can name the attachments and link straight to them. Args: folder_id: The folder's Box id — decimal digits, the number at the end of a Box folder URL. ``"0"`` is the caller's own root ("All Files"), the same convention the enumeration tools use. Anything else — a name, a label, a whole URL — is refused before any request is made. uploaded_by: Optional. Return only items uploaded by this person, matched EXACTLY and case-insensitively against ``uploaded_by`` below. Use it when the enquiry names its submitter. since: Optional lower bound on upload time (``created_at``), inclusive. until: Optional upper bound on upload time (``created_at``), inclusive. Both MUST carry a UTC offset (``2026-08-14T00:00:00+09:00``): a bare date names a different instant in every timezone, and this server has no basis for choosing one. Compared as instants, not as text. limit: How many rows to RETURN after filtering (default 100). It does not bound what is searched — a full page is always fetched first, so a match for ``uploaded_by`` is found even when it is not among the newest items. On ``uploaded_by``: Box populates ``uploader_display_name`` for an upload made through a File Request, where no Box user is involved — ``created_by`` and ``modified_by`` both read "Anonymous User" and the owner is the application's service account, so neither identifies anybody. For a file uploaded by a signed-in user the rev

Parameterslimitsinceuntilfolder_idrequireduploaded_by

Version history

5
  1. v0.12.0LatestOct 29, 2026
  2. v0.11.1Oct 26, 2026
  3. v0.11.0Oct 14, 2026
  4. v0.10.0Sep 29, 2026
  5. v0.9.1Sep 16, 2026

Score

90% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts
  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts