An MI300X Over MCP: What the Matrix Cores Execute, and What They Don't A developer built a suite of twelve tag-scoped MCP tools to inventory and manage a single AMD Instinct MI300X GPU on AMD Developer Cloud, using the same server to read the card's native numeric format support directly off the hardware. The measurements, taken on 2026-09-16, show the virtualized MI300X VF exposes 304 CUs at 2100 MHz with 191.69 GiB of host-visible VRAM over PCIe Gen5 x16, and the resulting format table disagrees with AMD's published peaks in two places. Two initial readings from the tools were wrong and were corrected by parsing raw output rather than trusting status fields. This article provides a step by step inventory and measurement of a single AMD Instinct MI300X on an AMD Developer Cloud hosted GPU enabled system. A suite of Python MCP tools is built to simplify management of the droplet, and the same server is used to read the card's native numeric format support off the hardware. https://github.com/xbill9/amd-gputools https://github.com/xbill9/amd-gputools The workstation writing this has no AMD GPU and never will. The hardware is one MI300X droplet billed at $1.99 an hour, and everything that reaches it goes through twelve tag-scoped MCP tools for inventory, power, reboot, hardware scan, GPU state and remote execution. Two of the readings those tools returned were wrong the first time, and both were corrected by parsing output instead of trusting a status. The format table at the end disagrees with AMD's published peaks in two places, and the disagreement is the result rather than a footnote to it. devcloud.amd.com is DigitalOcean underneath — same v2 API, same droplet ids — and the token comes from the tag name , so an untagged droplet is invisible to it and a tagged one belonging to someone else is not. DIGITALOCEAN ACCESS TOKEN in the environment, or in a mode 0600 .env , or in ~/ocean.txt . The same order is used by the server and by ssh-droplet.sh . root . BatchMode=yes throughout, so a wrong key fails rather than waiting on a password prompt. httpx and python-dotenv in the system interpreter. No virtualenv — .mcp.json launches the server with a bare python3 . Everything in these three tables was read off the machine by hardware scan , rocminfo and lspci through the MCP server, on 2026-09-16. Host | CPU | INTEL R XEON R PLATINUM 8568Y+ | | Cores | 20 vCPU — 1 socket, 20 cores, 1 thread per core no SMT | | Cache | L1d 640 KiB 20 instances , L2 80 MiB 20 instances | | NUMA | 1 node | | RAM | 236 GB usable, 138 GB free, 90 GB in buff/cache | | Disk | 720 GB, 595 G free | | OS | Debian 13 trixie , kernel 6.12.94+deb13-amd64 | | Droplet | gpu-mi300x1-192gb-devcloud , region atl1 , id 601142018 | GPU | Device | AMD Instinct MI300X VF virtual function , 1002:74b5 at 83:00.0 | | Target | gfx942 , ISA amdgcn-amd-amdhsa--gfx942:sramecc+:xnack- | | Compute | 304 CUs , 4 SIMDs per CU, wavefront 64, max 32 waves per CU | | Clock | 2100 MHz max | | Workgroup | max 1024 threads, LDS GROUP segment 64 KB | | Cacheline | 128 B | | Link | PCIe Gen5 x16 — LnkSta: Speed 32GT/s, Width x16 | | BAR | Region 0 is 256 G prefetchable, so the whole framebuffer is host-visible | | VBIOS | 113-M3000108-103 , SKU M3000108 , SMC firmware 00.85.129.03 | | UUID | GPU-2896ede4ddd2a8b6 | GPU memory — the numbers that decide what fits: | Pool | Total | Used | |---|---|---| | VRAM | 205,822,885,888 B = 191.69 GiB | 180,717,051,904 B = 168.31 GiB 87%† | | VIS VRAM host-visible | 205,822,885,888 B = 191.69 GiB | 180,717,051,904 B = 168.31 GiB | | GTT system memory aperture | 126,676,250,624 B = 117.98 GiB | 21,327,872 B = 0.02 GiB | † 87 is what rocm-smi reports; the division gives 87.8%. The tool truncates, and this article quotes the tool. Two things worth reading off that table. VIS VRAM equals VRAM : this is a large-BAR configuration, the entire 191.69 GiB is CPU-mappable, and no part of the framebuffer is hidden behind the old 256 MB window. And rocminfo reports three GLOBAL pools — coarse grained, fine grained and extended fine grained — each at 200,998,912 KB, which is the same 191.69 GiB described three ways, not three separate allocations. The "VF" matters. This is a virtualized MI300X, not a bare card: firmware queries like ASD, PFP, MES and SOS answer "Not supported on the given system" , and amd-smi cannot see partitioning. MEC 32948 , RLC 65 , SDMA 24 , SMC and the RAS/XGMI TAs do report. get help is the tool that describes the others, and its real output is the shape of the whole server: 📡 amd-gputools — DigitalOcean control plane for this project's AMD MI300 droplets. Scoped to droplets tagged gemma ; SSH as root ; checkout at /opt/amd-gputools . - list droplets — List every droplet tagged for this project, with state and address. - droplet status — Show one tagged droplet in detail, by numeric id or by name. - start droplet — Power on a tagged droplet. No-op if it is already active. - stop droplet — Power off a tagged droplet. - reboot droplet — Reboot a tagged droplet. - action status — Poll a droplet action returned by start droplet or stop droplet. - ssh command — Print the ssh command for a tagged droplet, with its current address. - run on droplet — Run one shell command on a tagged droplet over SSH and return its output. - gpu status — Report the AMD GPUs on a tagged droplet, and say why if there are none. - hardware scan — Inventory a droplet: host, GPU, firmware, ROCm packages and installed tools. - list gpu sizes — List DigitalOcean GPU droplet sizes and their prices, cheapest first. - get help — List the tools this server exposes. No create or destroy tools, by design: both are dollar-per-hour decisions, so they stay a deliberate step in the DigitalOcean console. Powering a droplet off does not stop DigitalOcean billing it. Three design decisions are visible in that text. Every lookup is scoped by tag. The server resolves droplets through GET /v2/droplets?tag name=gemma , so a tool cannot name, reboot or power off a droplet nobody tagged for it. The token in use is an account token with full reach; the tag is what keeps a reboot from landing on someone else's box. There is no create and no destroy. Not an oversight. Creating an MI300X starts a meter and destroying one throws away state, and neither is a thing a model should be one tool call away from. The console is a fine place for a decision that costs dollars per hour. Powering off does not stop the billing. This is the misconception the server exists to correct, so it is written into the tool output rather than a README. DigitalOcean reserves the resources of a stopped droplet and charges the full rate; only destroying it stops the meter. stop droplet says so in its return value every time, and a test enforces that the word survives refactoring. list droplets takes no arguments. What comes back is the table, already tallied: | Droplet | ID | Size | Status | Public IP | Region | | --- | --- | --- | --- | --- | --- | | debian-gpu-mi300x1-192gb-devcloud-atl1 | 601142018 | gpu-mi300x1-192gb-devcloud | active | 165.245.134.217 | atl1 | 📡 1 droplet s tagged gemma : 1 active. The last line is the point. The tool counts; the model quotes. One droplet is trivially countable by eye, but the same code path handles twenty, and a model asked to count twenty rows is a coin flip. Every tool in this server that returns rows also returns the tally — list gpu sizes sorts and names the cheapest, hardware scan counts present and missing tools, gpu status counts cards. droplet status 601142018 drills in, and ends with the sentence that costs money: debian-gpu-mi300x1-192gb-devcloud-atl1 601142018 - status: active - size: gpu-mi300x1-192gb-devcloud — 20 vCPU, 240 GB RAM, 720 GB disk - region: atl1 - image: debian-13-x64 - public IPv4: 165.245.134.217 - tags: gemma - created: 2026-09-16T18:09:45Z ✅ Reachable as root@165.245.134.217 . Billing is running. Note what is not here: a hardcoded IP anywhere in the server. Every tool resolves the address per call. A rebuilt droplet gets a new one, and a cached address turns into an SSH timeout that reads like a dead GPU. hardware scan answers "what can this box actually run" in a single SSH round trip, instead of ten tool calls that each pay connection setup. It ships one shell script that prints <<