Docs
Documentation
Connect an agent over MCP or call tools from your code. One API key and one credit balance cover every tool, and your first 100 credits are free.
Quickstart
1. Create an API key
Sign in to the console with GitHub and create a key. Keys start with
Get an API keymcpb_and work for MCP and the REST API. The samples read it fromMCPBYTES_API_KEY.2. Connect your agent
Add the MCPBytes server to Claude Code, or to any MCP client (see MCP). Then ask your agent to use a tool: for example, to split a 3D model into parts.
Claude Code# Sign in with GitHub when prompted claude mcp add --transport http mcpbytes \ https://api.mcpbytes.com/mcp # Or use an API key claude mcp add --transport http mcpbytes \ https://api.mcpbytes.com/mcp \ --header "Authorization: Bearer $MCPBYTES_API_KEY"3. Or call the REST API
Send a file to a tool and poll the job until its files are ready. To try a tool without writing code, use the console.
# The model file is the request body curl "https://api.mcpbytes.com/v1/tools/split_3d_model/jobs?filename=airplane.glb" \ -H "Authorization: Bearer $MCPBYTES_API_KEY" \ --data-binary @airplane.glb
Connect over MCP
The MCP server is at https://api.mcpbytes.com/mcp (Streamable HTTP). Clients that support OAuth sign in with GitHub; others send an API key as a bearer token.
Claude CodeOAuth or API key
The first form signs in through the browser when you run /mcp. In .mcp.json (project root), ${MCPBYTES_API_KEY} is read from the environment when Claude Code connects. Claude Code docs
claude mcp add --transport http mcpbytes \
https://api.mcpbytes.com/mcpCodex (CLI, IDE extension, ChatGPT desktop)OAuth or API key
Codex reads the key from the environment variable each time it connects. The same table can go in ~/.codex/config.toml by hand; codex mcp add has no --header flag. Codex docs
codex mcp add mcpbytes --url https://api.mcpbytes.com/mcp \
--bearer-token-env-var MCPBYTES_API_KEYCursorOAuth or API key
~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project). Remote servers take no "type". Without the header, the client signs you in with GitHub or an email link (OAuth). Cursor docs
{
"mcpServers": {
"mcpbytes": {
"url": "https://api.mcpbytes.com/mcp",
"headers": {
"Authorization": "Bearer ${env:MCPBYTES_API_KEY}"
}
}
}
}VS Code (GitHub Copilot)OAuth or API key
.vscode/mcp.json, or "MCP: Open User Configuration". The top-level key is "servers". VS Code asks for the key once and stores it securely. Without the header, the client signs you in with GitHub or an email link (OAuth). VS Code docs
{
"inputs": [
{
"type": "promptString",
"id": "mcpbytes-api-key",
"description": "MCPBytes API key (mcpb_...)",
"password": true
}
],
"servers": {
"mcpbytes": {
"type": "http",
"url": "https://api.mcpbytes.com/mcp",
"headers": {
"Authorization": "Bearer ${input:mcpbytes-api-key}"
}
}
}
}Gemini CLIOAuth or API key
~/.gemini/settings.json or .gemini/settings.json. The key is "httpUrl" ("url" means the older SSE transport). Without the header, the client signs you in with GitHub or an email link (OAuth). Then sign in with /mcp auth. Gemini CLI docs
{
"mcpServers": {
"mcpbytes": {
"httpUrl": "https://api.mcpbytes.com/mcp",
"headers": {
"Authorization": "Bearer ${MCPBYTES_API_KEY}"
}
}
}
}OpenCodeOAuth or API key
opencode.json or ~/.config/opencode/opencode.json. Variables are written {env:NAME}. "oauth": false makes a wrong key an error instead of a sign-in; remove it and the headers to sign in with OAuth. OpenCode docs
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"mcpbytes": {
"type": "remote",
"url": "https://api.mcpbytes.com/mcp",
"enabled": true,
"oauth": false,
"headers": {
"Authorization": "Bearer {env:MCPBYTES_API_KEY}"
}
}
}
}oh-my-pi (omp)OAuth or API key
.omp/mcp.json (project) or ~/.omp/agent/mcp.json (user). Without the header, the client signs you in with GitHub or an email link (OAuth). Then run /mcp reauth mcpbytes in a session. omp also picks up servers already set up for Claude Code, Cursor, VS Code, Gemini CLI and Codex. oh-my-pi docs
{
"mcpServers": {
"mcpbytes": {
"type": "http",
"url": "https://api.mcpbytes.com/mcp",
"headers": {
"Authorization": "Bearer ${MCPBYTES_API_KEY}"
}
}
}
}piAPI key only
pi has no MCP support, by design: its author recommends command-line tools described by a skill. Install the MCPBytes skill (it drives the REST API with a small script), or add MCP with the pi-mcp-adapter extension. pi docs
mkdir -p ~/.pi/agent/skills/mcpbytes
curl -fsSL https://mcpbytes.com/skills/mcpbytes/mcpbytes.tar.gz \
| tar -xz -C ~/.pi/agent/skills/mcpbytesDeepSeekAPI key only
DeepSeek's API does not run MCP servers itself: the agent you use DeepSeek models in does (Claude Code, OpenCode, oh-my-pi, Cline: use that agent's entry here). DeepSeek's own agent, DeepSeek Harness (dsh, a developer preview), takes this patch in ~/.dsh/cordis.patch.yml; it supports headers, not OAuth. DeepSeek docs
- insert:
- id: mcp-mcpbytes
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: mcpbytes
transport: streamable-http
url: https://api.mcpbytes.com/mcp
headers:
Authorization: !!js '`Bearer ${process.env.MCPBYTES_API_KEY}`'WindsurfOAuth or API key
~/.codeium/windsurf/mcp_config.json. Without the header, the client signs you in with GitHub or an email link (OAuth). Cascade allows 100 tools in total, so a single-family endpoint helps. Windsurf docs
{
"mcpServers": {
"mcpbytes": {
"serverUrl": "https://api.mcpbytes.com/mcp",
"headers": {
"Authorization": "Bearer ${env:MCPBYTES_API_KEY}"
}
}
}
}GooseOAuth or API key
~/.config/goose/config.yaml (Windows: %APPDATA%\Block\goose\config\config.yaml), or "goose configure" > Add Extension > Remote Extension (Streamable HTTP). The key is "uri". Without the header, the client signs you in with GitHub or an email link (OAuth). Goose docs
extensions:
mcpbytes:
type: streamable_http
name: mcpbytes
enabled: true
uri: "https://api.mcpbytes.com/mcp"
headers:
Authorization: "Bearer ${MCPBYTES_API_KEY}"
env_keys:
- MCPBYTES_API_KEY
timeout: 300ZedOAuth or API key
settings.json, or Settings > AI > MCP Servers > Add Server > Add Remote Server. Zed's settings cannot read environment variables, so sign in instead of storing a key: with no Authorization header, Zed starts the OAuth sign-in. Zed docs
{
"context_servers": {
"mcpbytes": {
"url": "https://api.mcpbytes.com/mcp"
}
}
}Claude (desktop and web) and ChatGPTOAuth only
These add remote servers as connectors and sign in with OAuth; there is no field for an API key. Claude: Customize > Connectors > Add custom connector. ChatGPT: turn on Developer mode in Settings, then create an app. Enter this URL: Claude docs
https://api.mcpbytes.com/mcpAny client that only starts local (stdio) serversOAuth or API key
mcp-remote runs locally and forwards to the endpoint. The header is written without a space and takes its value from "env", because some clients on Windows break arguments that contain spaces. Use it for Cline too. Without the --header arguments and "env", mcp-remote signs you in with OAuth. Any client that only starts local docs
{
"mcpServers": {
"mcpbytes": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.mcpbytes.com/mcp",
"--transport",
"http-only",
"--header",
"Authorization:${MCPBYTES_AUTH}"
],
"env": {
"MCPBYTES_AUTH": "Bearer <your key>"
}
}
}
}Every tool is one MCP tool that starts a job. For a local file, the agent calls create_upload, PUTs the file to the returned URL, then calls the tool with the upload_id. For a public https URL it calls the tool directly. The tool and get_job wait up to wait_seconds (at most 45) for the result, and read_job_file reads text outputs such as manifest.json in chunks.
- split_3d_model
- Starts a job that splits a 3D model into separate part meshes, each with a convex collider, plus manifest.json (bounds, contacts, symmetry, mass estimates). Give upload_id (from create_upload) or a public https url. Waits up to wait_seconds for the result. Costs 20 credits up to 50,000 faces, 50 credits up to 200,000 faces.
- extract_pdf
- Starts a job that extracts the text of a PDF, page by page, and returns the beginning of it; continue with read_job_file (text.txt). pages.json has per-page offsets and the document metadata. Scanned pages have no text (no OCR). Give upload_id (from create_upload) or a public https url. Waits up to wait_seconds for the result. Costs 1 credit per 25 pages (at least 1).
- inspect_3d_model
- Inspects a 3D model without segmentation or repair. Returns counts, bounds, units, resources and topology checks in inspection.json, with summary.txt inline. Compares stored topology with exactly coincident vertices merged per mesh. Supports .glb .gltf .obj .ply .stl .off .blend. Give upload_id or a public https url. Waits up to wait_seconds for the result. Costs 10 credits up to 50,000 faces, 25 credits up to 200,000 faces.
- create_upload
- Returns a one-hour URL to PUT a local file to; then call the tool with the upload_id.
- get_job
- Status and results of a job; waits up to wait_seconds for it to finish.
- list_jobs
- Your most recent jobs, newest first.
- read_job_file
- Reads a text output (.txt .json .md .csv) of a succeeded job in chunks.
To give an agent a shorter tool list, connect to one family of tools instead: https://api.mcpbytes.com/mcp/3d, https://api.mcpbytes.com/mcp/pdf. Each has its tools plus the shared ones; every tool's page shows the setup for its endpoint.
Agent skill
The MCPBytes skill teaches an agent the whole workflow: uploads, waiting for jobs, reading results in chunks, each tool's options and errors. With MCP connected it uses the MCP tools; without MCP (pi, for example) it drives the REST API through a small Python script and MCPBYTES_API_KEY. Most agents (Codex, Gemini CLI, Copilot, Cursor, OpenCode, pi and more) read it from ~/.agents/skills/; the skill page has every agent's folder, Claude Code's included.
mkdir -p ~/.agents/skills/mcpbytes
curl -fsSL https://mcpbytes.com/skills/mcpbytes/mcpbytes.tar.gz \
| tar -xz -C ~/.agents/skills/mcpbytesREST API
The base URL is https://api.mcpbytes.com/v1. Authenticate every request with your API key as a bearer token.
# Every request authenticates with an API key
curl https://api.mcpbytes.com/v1/me \
-H "Authorization: Bearer $MCPBYTES_API_KEY"- GET
/v1/meYour account, plan limits and usage
- GET
/v1/toolsThe tools you can run, with their options and your limits
- POST
/v1/uploadsCreate a one-hour URL to PUT a file to
- POST
/v1/tools/{tool}/jobsStart a job: the file as the body with ?filename=, or JSON with upload_id or url
- GET
/v1/jobsList your jobs, newest first (?tool= for one tool's)
- GET
/v1/jobs/{id}A job's status, result and fresh download URLs
- GET
/v1/jobs/{id}/files/{name}Read a text output (.txt .json .md .csv) in chunks
- DELETE
/v1/jobs/{id}Cancel a queued job, or delete a finished job and its files
The full contract, with every field and response, is in the OpenAPI description. API keys are managed in the console.
Jobs & files
Every run is a job. Creating one returns 202 with the job; poll GET /v1/jobs/{id} until its status is final.
- queued
- Accepted, waiting to start.
- running
- Being processed.
- succeeded
- Done: result.files has the download URLs.
- failed
- Stopped with an error: see error.code, error.message and error.hint.
- canceled
- Canceled with DELETE while it was queued.
- expired
- Never started; try again.
Sending a file
Send the file itself as the request body with ?filename= (options go in the query string, as in the quickstart), use an upload URL, or give a public https URL. The JSON forms take options in an options object.
# 1. Create an upload URL (valid for one hour)
curl https://api.mcpbytes.com/v1/uploads \
-H "Authorization: Bearer $MCPBYTES_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filename": "airplane.glb"}'
# 2. PUT the file to the "url" from the response
curl -X PUT --data-binary @airplane.glb "$UPLOAD_URL"
# 3. Start the job with the "upload_id"
curl https://api.mcpbytes.com/v1/tools/split_3d_model/jobs \
-H "Authorization: Bearer $MCPBYTES_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"upload_id\": \"$UPLOAD_ID\"}"To retry safely, send an Idempotency-Key header: a repeated key returns the original job with 200 instead of starting a new one.
Results and downloads
A succeeded job lists its files in result.files, each with a download url. URLs are valid for up to 24 hours; fetch the job again for fresh ones. Results are deleted after 24 hours, or sooner with DELETE /v1/jobs/{id}. Text outputs (.txt .json .md .csv) can also be read in chunks, without downloading them: GET /v1/jobs/{id}/files/{name}?offset=&limit= returns text and the next_offset to continue from, until eof.
- manifest.json
- Every part: file, bounds, contacts, symmetry, collider, mass and inertia estimates.
- segmented.glb
- All parts in one file, color-coded, for a quick visual check.
- meshes/part_NNN.glb
- Each part's original geometry, materials and textures.
- collision/part_NNN.glb
- A convex collider per part, in the same coordinates.
- metadata/face_to_part.bin
- The part id of every original triangle, for hit tests on the intact model.
- <model>_parts.zip
- All of the above in one archive, for a single download (left out, with a note, above 100 MB).
Parts are numbered by decreasing surface area, so part_000 is the largest. With format set to obj or ply, meshes and colliders use that extension. All files share one coordinate system: place every part and collider at the model's root transform to rebuild it.
- text.txt
- Every extracted page: a --- Page N --- line, the page's text, a blank line. UTF-8.
- pages.json
- The page count, the document's metadata, and for every extracted page its byte offset and length in text.txt.
Read text.txt in chunks with GET /v1/jobs/{id}/files/text.txt?offset=&limit= (or read_job_file over MCP): pass next_offset as the next offset until eof. A page's offset in pages.json takes you straight to it.
- summary.txt
- Readable counts, dimensions, topology checks and up to ten warnings.
- inspection.json
- Versioned report with per-instance geometry, units, resources and warnings.
Read either file with read_job_file or download it from result.files. Stored and merged topology are reported separately, without cross-instance welding. Watertightness is not a printability or self-intersection test. Reports over 10 MiB omit detailed arrays and set details_truncated.
Credits & prices
Jobs are paid with prepaid credits, and one balance pays for every tool. A new account starts with 100 free credits. GET /v1/me returns your balance (credits), GET /v1/tools every tool's price (pricing), and GET /v1/billing where your credits went.
A job's price follows the size of its input, so it is charged when the file has been opened and measured, before the work starts. The job then shows credits_charged. Starting a job needs the tool's smallest price in the balance (402 insufficient_credits otherwise). A job that fails costs nothing: its charge goes back, and credits_charged reads 0.
3D Mesh Segmentation
- Up to 50,000 faces
- 20 credits
- Up to 200,000 faces
- 50 credits
PDF Text
- Per 25 pages
- 1 credit
Model Inspection
- Up to 50,000 faces
- 10 credits
- Up to 200,000 faces
- 25 credits
Limits & errors
Every account has the same limits. GET /v1/me returns yours and your current usage.
- Model size
- Up to 200,000 faces
- PDF size
- Up to 500 pages and 20 MB
- Inspection geometry
- Up to 200,000 faces per model
- At a time
- 1 job
- Uploads
- Up to 50 MB
- Results
- Kept for 24 hours
Errors return JSON: {"error": {"code": "…", "message": "…"}}. Codes are stable; messages may change. Over MCP, the same code and message come back as a tool error.
- 400
invalid_request, invalid_json, url_not_allowedThe request is invalid; the message says what to fix.- 401
unauthorizedMissing, invalid or revoked API key.- 402
insufficient_creditsThe balance is below the tool's smallest price. The message says what the job costs and what you have.- 404
not_found, upload_not_foundNo such job, tool or file, or the upload was never PUT (uploads expire after one hour).- 409
job_running, idempotency_conflictA running job cannot be canceled. An Idempotency-Key belongs to the tool it was first used with.- 411
length_requiredUploads need a Content-Length header (curl --data-binary sets it).- 413
too_largeThe file is larger than your upload limit.- 422
fetch_failedThe public URL could not be downloaded.- 429
quota_exceeded, too_many_active_jobs, rate_limitedA limit was reached (one job at a time; the daily caps only stop abuse). Wait for the Retry-After header.- 503
busyThe service is at capacity. Wait for the Retry-After header.
A failed job is still returned with 200; its error says why. Common codes:
- unsupported_format
- The tool does not take this file type.
- insufficient_credits
- The job costs more than the balance, which is known once the input has been measured. Nothing was charged.
- timeout
- The job did not finish within its time limit.
- out_of_memory
- The file needs more memory than a job has.
- invalid_mesh
- The file is corrupt or has no usable triangle geometry.
- unsupported_feature
- A valid file uses an unsupported feature, such as Draco compression.
- limit_exceeded
- The model has more faces than your plan allows.
- segmentation_failed
- No usable parts were found.
- invalid_pdf
- The file is not a PDF, or it is too damaged to open.
- encrypted_pdf
- The PDF is password-protected. Remove the password and try again.
- invalid_mesh
- Invalid geometry, missing geometry data, or no triangle meshes.
- unsupported_feature
- Compressed geometry or unsupported external Blender data; export a self-contained GLB.
- limit_exceeded
- The model exceeds the face limit.
Tool reference
3D Model Mesh Segmentation
Tool pageSplit a 3D model into separate part meshes, with colliders and physics metadata.
- MCP tool
- split_3d_model
- REST
- POST /v1/tools/split_3d_model/jobs
- Price
- From 20 credits
- Input formats
- .glb .gltf .obj .ply .stl .off .blend
- Part formats
- GLB (default), OBJ or PLY
- Detail
- low, medium (default) or high
- Outputs
- Part meshes, convex colliders, segmented.glb, manifest.json, face_to_part.bin, and all of them as one .zip
- Metadata
- Bounds, contacts, symmetry, mass and inertia estimates
Options- detail
low | medium | highHow finely to split: low = major assemblies, high = sub-parts. Default medium.- format
glb | obj | plyPart file format. Default glb.- max_parts
1–64Safety ceiling on the part count, which is chosen automatically. Capped at 32.- min_part_faces
integerMerge parts with fewer faces. Default 0.- min_part_area
0–1Merge parts below this fraction of the surface area. Default depends on detail.- preprocess
auto | on | offConnectivity cleanup of the working mesh. Default auto.- segmented
true | falseAlso write segmented.glb, all parts color-coded. Default true.- density
numberMass per cubic model unit, for mass estimates. Default 100.
PDF Text Extraction
Tool pageExtract the text of a PDF, page by page, in chunks an agent can read.
- MCP tool
- extract_pdf
- REST
- POST /v1/tools/extract_pdf/jobs
- Price
- 1 credit per 25 pages
- Input format
- .pdf (not password-protected)
- Pages
- Up to 500 per job; continue with start_page
- Outputs
- text.txt with page markers, pages.json with page offsets and metadata
- Reading
- First bytes inline over MCP; the rest in chunks of up to 100,000 bytes
- Scanned pages
- No OCR: pages without a text layer come back empty
Options- start_page
integer ≥ 1First page to extract. Default 1.- max_pages
integer ≥ 1Extract at most this many pages. Capped at 500. Fewer pages cost fewer credits.
3D Model Inspection
Tool pageCheck geometry, dimensions, materials and topology before splitting a model.
- MCP tool
- inspect_3d_model
- REST
- POST /v1/tools/inspect_3d_model/jobs
- Price
- From 10 credits
- Formats
- .glb .gltf .obj .ply .stl .off .blend
- Outputs
- inspection.json and summary.txt
- Dimensions
- World-space bounds; units unknown when unspecified
- Topology
- Components, boundary edges, non-manifold edges, degenerate faces and watertightness
- Blender
- Evaluated meshes; pack resources into the file
Options