abm-mcp
Provides read-only access to Apple Business Manager and Apple School Manager API, allowing listing and reading of devices, MDM servers, blueprints, configurations, apps, packages, users, user groups, organizational units, audit events, and AppleCare coverage.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@abm-mcplist devices assigned to MDM server 12345"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Apple Business Manager MCP server
A FastMCP server that exposes the Apple School & Business Manager API as MCP tools. It is strictly read-only — it lists and reads devices, MDM servers, blueprints, configurations, apps, packages, users, user groups, organizational units, audit events, AppleCare coverage, and assignment/activity status. It never creates, updates, deletes, or reassigns anything.
Read coverage of the Apple Business API is complete (34 tools). The write operations (assign/unassign devices; create/update/delete for blueprints, configurations, MDM servers; blueprint membership changes) are intentionally not implemented.
Works with both Apple Business Manager (business.api) and Apple School
Manager (school.api).
Tools
Read — devices, MDM services, activities (always available):
Tool | What it does |
| List all MDM servers in the org (id, name, type, timestamps). |
| Details for one MDM server by id. |
| Device ids/serials assigned to a given MDM server (bulk-friendly). |
| Devices enrolled via Automated Device Enrollment. |
| Full details for one device by serial number. |
| Which MDM server a device is assigned to (full info). |
| Assigned MDM server id (linkage only). |
| AppleCare coverage for one device. |
| Status of a device-management activity by id. |
| Devices enrolled in Apple device management services ( |
| Details for one MDM-enrolled device. |
Read — blueprints (always available):
Tool | What it does |
| List device blueprints in the org. |
| Details for one blueprint by id. |
| Org-device ids assigned to a blueprint. |
| App ids attached to a blueprint. |
| Configuration ids attached to a blueprint. |
| Package ids attached to a blueprint. |
| User-group ids attached to a blueprint. |
| User ids attached to a blueprint. |
Read — configurations, apps, packages (always available):
Tool | What it does |
| List MDM configurations in the org. |
| Details for one configuration by id. |
| List apps available in the org (Apps and Books / VPP). |
| Details for one app by id. |
| List packages in the org. |
| Details for one package by id. |
Read — users, user groups, organizational units, audit (always available):
Tool | What it does |
| List managed Apple Account users in the org. |
| Details for one user by id. |
| List user groups in the org. |
| Details for one user group by id. |
| User ids belonging to a user group. |
| List organizational units in the org. |
| Details for one organizational unit by id. |
| User ids belonging to an organizational unit. |
| Org audit events in a time window (start/end timestamps required). |
Related MCP server: appd-mcp
1. Create API credentials in ABM/ASM
Sign in to Apple Business (or School) Manager.
Click your name (bottom-left) → Preferences → API.
Click + to create an API account, give it a label, Create.
Click Generate Private Key — the
.pemdownloads once. Keep it safe; it cannot be re-downloaded (you can revoke and regenerate).Click Manage on the account to copy the Client ID and Key ID.
2. Install
cd abm-mcp
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt3. Configure credentials
The server reads four settings from environment variables:
ABM_CLIENT_ID=BUSINESSAPI.9703f56c-....
ABM_KEY_ID=d136aa66-0c3b-....
ABM_PRIVATE_KEY_PATH=/absolute/path/to/private-key.pem
ABM_SCOPE=business.api # or school.apiThere are two ways to supply them — pick one, you don't need both:
envblock in Claude Desktop's config — recommended when running inside the Claude Desktop app (see step 5, Option B). Claude Desktop injects these when it launches the server, so no.envfile is needed..envfile — used when you run the server yourself from a terminal (python server.py) or with the one-command installer (step 5, Option A). Copy the template and fill it in:cp .env.example .envThe server loads
.envautomatically (viapython-dotenv).
You can inline the key with ABM_PRIVATE_KEY_PEM instead of a path in either
case. Whichever file holds your credentials, keep it readable only by your own
user account.
Credential field details
Copy the three identifiers from the ABM/ASM API account's Manage screen using the copy icons (avoid retyping — the Client ID wraps across lines in the UI and is easy to mistype):
Setting | Where it comes from | Format / example |
| Manage screen → "Client ID" | Starts with |
| Manage screen → "Key ID" | A UUID, 36 chars, e.g. |
| The | Absolute path to a PKCS#8 EC P-256 key (see below) |
| Must match the client type |
|
The key must be an EC P-256 key (Apple's API signs with ES256). The curve is non-negotiable; the encoding is what needs attention.
Apple issues the key as SEC1 (-----BEGIN EC PRIVATE KEY-----) with explicit
EC parameters, and this does NOT load in Python's cryptography library — it
fails with an ASN.1 / "EC curves with explicit parameters" error. You must
convert the downloaded key once to a named-curve PKCS#8 key:
openssl pkcs8 -topk8 -nocrypt -in abm-api-private-key.pem -out private-key-pkcs8.pemThen point ABM_PRIVATE_KEY_PATH at private-key-pkcs8.pem (-----BEGIN PRIVATE KEY-----). The conversion re-encodes the same key material to the
named-curve form the library accepts, so the Key ID registered in ABM stays
valid. (A named-curve SEC1 key would also load fine — but Apple's specific
download uses explicit parameters, so conversion is required in practice.)
Lock down whatever holds the secret, and don't sync the folder anywhere public:
chmod 600 .env private-key-pkcs8.pemVerify credentials without Claude Desktop
test_token.py performs a live token request and prints a masked report
(field lengths, the decoded JWT claims, and Apple's exact response) so you can
confirm auth before wiring up the app:
python test_token.py # uses .env
# or pass inline:
ABM_CLIENT_ID='...' ABM_KEY_ID='...' \
ABM_PRIVATE_KEY_PATH='/abs/path/private-key-pkcs8.pem' ABM_SCOPE='business.api' \
python test_token.pyA ✅ SUCCESS line means the credentials and signing are correct.
Troubleshooting invalid_client
If Apple's token endpoint returns {"error":"invalid_client"}, check, in order:
JWT audience must include
/v2/. Theaudclaim has to behttps://account.apple.com/auth/oauth2/v2/tokeneven though the token request is POSTed to the non-v2URLhttps://account.apple.com/auth/oauth2/token. This is set inabm_client.py(TOKEN_AUDIENCE) and is the single most common cause.test_token.pywarns if it's missing.Client ID / Key ID match the key. Confirm all three come from the same API account's Manage screen, with no stray whitespace or truncation (watch the field lengths in
test_token.py).Scope matches the client type (
business.api↔BUSINESSAPI.).Key not revoked / freshly created — a brand-new key can take a few minutes to become active; a revoked key fails permanently.
4. Run (optional — to test standalone)
python server.py # stdio transport
# or
fastmcp run server.py:mcp # via the FastMCP CLI5. Use it in the Claude Desktop app
Claude Desktop launches the server itself over stdio, so you don't run it by hand — you just register it once.
Option A — one command (recommended)
Requires uv and fastmcp installed as CLI
tools (brew install uv and uv tool install fastmcp). This path uses the
.env file, so create it first (step 3). With your .env filled in:
./install-claude-desktop.shThis runs fastmcp install claude-desktop, which builds an isolated
environment for the server (installing requirements.txt), passes your .env
values through, and adds the entry to Claude Desktop's config automatically.
Fully quit and reopen Claude Desktop afterward.
Option B — edit the config by hand
Open Claude Desktop's config file:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
Add an entry under mcpServers, pointing command at the Python inside the
virtualenv you created in step 2 (so the dependencies are available):
{
"mcpServers": {
"apple-business-manager": {
"command": "/absolute/path/to/abm-mcp/.venv/bin/python",
"args": ["/absolute/path/to/abm-mcp/server.py"],
"env": {
"ABM_CLIENT_ID": "BUSINESSAPI.9703f56c-....",
"ABM_KEY_ID": "d136aa66-0c3b-....",
"ABM_PRIVATE_KEY_PATH": "/absolute/path/to/private-key.pem",
"ABM_SCOPE": "business.api"
}
}
}
}Use absolute paths for command, args, and the key path — Claude Desktop
does not run inside your project folder. On Windows, the interpreter is
.venv\Scripts\python.exe and paths use \\. With the env block filled in
here, you do not need a .env file.
It's JSON: comma-separate multiple servers under mcpServers and don't leave a
trailing comma. Save, then fully quit and reopen Claude Desktop.
Verify
In a new chat, open the tools menu (the tools/hammer icon in the message box) — you should see Apple Business Manager with its 8 tools. Try asking: "List the MDM servers in Apple Business Manager." If nothing appears, check Claude Desktop's MCP logs:
macOS:
~/Library/Logs/Claude/mcp*.log
How auth works
Apple uses a two-step OAuth flow (see Implementing OAuth for the AxM API):
The server signs a client assertion JWT (ES256, using your EC P-256 private key) with the standard claims (
iss/sub= Client ID,aud= Apple's token endpoint).It exchanges that assertion for a bearer token via the
client_credentialsgrant, then callshttps://api-business.apple.com/v1/...(orapi-school.apple.com).
The token lives ~1 hour and is cached and refreshed automatically.
abm_client.py holds all of this; server.py just wraps GET endpoints as
tools.
Test (offline)
python test_smoke.pyVerifies JWT signing/verification, scope→host resolution, and that all tools register — no live API calls.
Notes & limits
Strictly read-only. No write tools are implemented, so the server cannot assign/unassign devices or create/update/delete any resource.
AppleCare has no bulk endpoint — one serial per call — so avoid looping
get_device_applecare_coverageover a large fleet.Pagination follows JSON:API
links.nextcursors; use thelimitargument on list tools to cap results for big orgs.Behind a proxy, set
HTTPS_PROXY/NO_PROXYin the environment.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/o-sokhan/abm-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server