Documentation
Foundry exposes GPU notebooks to agents. Prefer the MCP connector when your client supports remote MCP; use the REST Agent API for scripts and custom integrations.
Base URL: https://foundry-mocha-ten.vercel.app
Getting started
- Create an account and verify your email.
- Open Settings → API keys and create a key. Copy the secret once — it starts with
fdry_sk_. - Connect via MCP (Settings → MCP has the connector URL), or call
/api/v1with the Bearer key.
MCP connector
MCP (Model Context Protocol) is a standard way for an agent client to discover and call tools on a remote server. Foundry hosts a remote MCP endpoint: your client opens a session to Foundry, authenticates with your API key, then lists tools such as create notebook, upload file, and start training. The agent never needs to hand-write HTTP paths for common jobs — it calls named tools and receives JSON results.
How the connection works
- Connector URL— a single HTTPS endpoint that speaks MCP over HTTP. Foundry's URL is:
https://foundry-mocha-ten.vercel.app/api/mcp/mcp - Auth header — every request includes
Authorization: Bearer fdry_sk_…. The server verifies the key against your account (hashed at rest). Invalid keys get no tools. - Session — the client initializes MCP, reads
serverInfo.name = foundry, then lists tools. Each tool has a name, description, and JSON schema for arguments. - Tool calls — when the agent decides to train, it invokes a tool (for example
create_notebook). Foundry runs the same backend logic as the dashboard and REST API, then returns structured text/JSON in the tool result. - Same account as the UI — notebooks created over MCP appear under Dashboard → Notebooks for that API key's user. Status and logs stay in sync.
Configure your client
In any MCP-capable client that supports a remote URL + custom headers, add a server entry like this (replace the key). You can also copy a ready-made config from Settings → MCP.
{
"mcpServers": {
"foundry": {
"url": "https://foundry-mocha-ten.vercel.app/api/mcp/mcp",
"headers": {
"Authorization": "Bearer fdry_sk_…"
}
}
}
}- Use the full path
/api/mcp/mcp(not just/api/mcp). - Do not commit plaintext keys to git.
- If tools do not appear, reconnect the server and confirm the key still exists in Settings.
Auth for remote connectors
Clients that only send a URL (no custom headers) use Foundry's OAuth sign-in: they discover /.well-known/oauth-authorization-server, register a client, then open the consent page. You paste your fdry_sk_… key once; Foundry returns an access token the connector stores. Clients that support custom headers can still send Authorization: Bearer fdry_sk_… directly.
MCP tools
Tools map 1:1 onto notebook operations. Arguments are validated; failures return an error field in the result payload.
| Tool | What it does |
|---|---|
| list_notebooks | List notebooks for the authenticated account (id, title, status, gpu). |
| create_notebook | Create a notebook from a template (llm-lora, whisper, …) and GPU (cpu, T4, L4, A10G). |
| get_notebook | Fetch one notebook: cells, trainConfig, events, status. |
| set_note | Attach a dataset / training note (stored in trainConfig.datasetNote). |
| list_files | List files already in the notebook workspace (names, sizes, path). |
| upload_file | Upload a dataset file. Pass filename + content as utf8 text or base64. Max ~8 MB per call via MCP. |
| start_training | Run the full train recipe on Modal GPUs (config → load → train → eval → export). |
| get_status | Poll status: idle | running | ready | failed (plus timestamps). |
| get_logs | Fetch recent run / training log lines for debugging. |
upload_file details
Remote MCP cannot send multipart form data the way browsers do. Instead, pass the file body as a string:
encoding: "utf8"(default) — paste JSONL/CSV/TXT content directly intocontent.encoding: "base64"— for binary or large-safe transfers; Foundry decodes to bytes on disk.- After upload,
trainConfig.filesanddatasetPathupdate so training cells see the files. - For very large datasets over REST, use multipart
POST /api/v1/notebooks/:id/files(up to ~200 MB per file).
MCP training loop
This is the recommended agent loop. Notebook runs do not spend account credits.
create_notebook— picktemplate_id(usuallyllm-lora) and a GPU.upload_file— sendtrain.jsonl(or similar) with utf8 content. Optionally callset_noteto describe the data.start_training— kicks off Modal. This can take a while; the tool waits for the run orchestration to finish or error.get_status/get_logs— confirmreadyor diagnosefailed.
Agent checklist (MCP):
1. create_notebook { title, template_id: "llm-lora", gpu: "T4" }
2. upload_file { notebook_id, filename: "train.jsonl", content: "…", encoding: "utf8" }
3. set_note { notebook_id, note: "Support FAQ pairs" } # optional
4. start_training { notebook_id }
5. get_status / get_logs until ready or failed
Connector: https://foundry-mocha-ten.vercel.app/api/mcp/mcp
Auth: Authorization: Bearer fdry_sk_…For AI agents
If MCP is unavailable, drive Foundry with the REST Agent API. Give the agent these facts:
- Host:
https://foundry-mocha-ten.vercel.app - Auth:
Authorization: Bearer fdry_sk_… - JSON for most calls; multipart form for file uploads (
files=@path). - Loop: create → upload → train → poll status/logs. Notebooks do not debit credits.
Agent system brief
You have access to the Foundry Agent API.
Base URL: https://foundry-mocha-ten.vercel.app
Auth: Authorization: Bearer $FOUNDRY_API_KEY
(Key looks like fdry_sk_… — never print the full secret.)
Prefer MCP tools when connected. Otherwise:
1. POST /api/v1/notebooks { "title":"…", "templateId":"llm-lora", "gpu":"T4" }
2. POST /api/v1/notebooks/{id}/files multipart field "files" with dataset
3. PATCH /api/v1/notebooks/{id} optional trainConfig (epochs, datasetNote, …)
4. POST /api/v1/notebooks/{id}/train {}
5. Poll GET /api/v1/notebooks/{id}/status and /logs until status is ready or failed
Templates: llm-lora | whisper | handwriting | video | voice | robotics
GPUs: cpu | T4 | L4 | A10G
Notebook cell runs and training do not spend account credits.Authentication
Every /api/v1/* and MCP request needs a Bearer token. Keys are hashed at rest; the plaintext secret is shown once at creation.
curl "https://foundry-mocha-ten.vercel.app/api/v1/notebooks" \
-H "Authorization: Bearer $FOUNDRY_API_KEY"- Prefix:
fdry_sk_ - Max 5 active keys per account
- Manage keys in Dashboard → Settings
- Revoke or delete a key immediately if it leaks
Scopes
Keys can be limited to specific actions. New keys default to all scopes. MCP uses the same key; keep full notebook scopes enabled for training agents.
| Scope | Allows |
|---|---|
| notebooks:read | List notebooks, get status, read logs |
| notebooks:write | Create, update, delete notebooks |
| notebooks:files | Upload / list / delete dataset files |
| notebooks:run | Run cells (single or all) |
| notebooks:train | Start the train recipe on Modal |
Missing scope → 403 with code: "forbidden". Bad or missing key → 401 unauthorized.
REST end-to-end
export FOUNDRY_API_KEY=fdry_sk_…
export HOST=https://foundry-mocha-ten.vercel.app
# 1) Create
curl -s -X POST "$HOST/api/v1/notebooks" \
-H "Authorization: Bearer $FOUNDRY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"Agent train","templateId":"llm-lora","gpu":"T4"}'
# 2) Upload dataset (JSONL recommended)
curl -s -X POST "$HOST/api/v1/notebooks/NOTEBOOK_ID/files" \
-H "Authorization: Bearer $FOUNDRY_API_KEY" \
-F "files=@./train.jsonl"
# 3) Optional config tweak
curl -s -X PATCH "$HOST/api/v1/notebooks/NOTEBOOK_ID" \
-H "Authorization: Bearer $FOUNDRY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"trainConfig":{"epochs":3,"datasetNote":"Support chat pairs"}}'
# 4) Train on Modal
curl -s -X POST "$HOST/api/v1/notebooks/NOTEBOOK_ID/train" \
-H "Authorization: Bearer $FOUNDRY_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
# 5) Poll
curl -s "$HOST/api/v1/notebooks/NOTEBOOK_ID/status" \
-H "Authorization: Bearer $FOUNDRY_API_KEY"
curl -s "$HOST/api/v1/notebooks/NOTEBOOK_ID/logs" \
-H "Authorization: Bearer $FOUNDRY_API_KEY"Endpoints
All paths are under /api/v1. Responses are JSON unless noted.
/api/v1/notebooksList your notebooks and remaining credits.
Scope: notebooks:read
curl "$HOST/api/v1/notebooks" -H "Authorization: Bearer $FOUNDRY_API_KEY"/api/v1/notebooksCreate a notebook. Optional: title, description, gpu, templateId, trainConfig, cells.
Scope: notebooks:write
curl -X POST "$HOST/api/v1/notebooks" \
-H "Authorization: Bearer $FOUNDRY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"My LoRA","templateId":"llm-lora","gpu":"T4"}'/api/v1/notebooks/:idFetch full notebook: cells, trainConfig, events.
Scope: notebooks:read
/api/v1/notebooks/:idUpdate title, description, gpu, cells, or trainConfig. Updating trainConfig refreshes the FOUNDRY_CONFIG cell.
Scope: notebooks:write
/api/v1/notebooks/:idDelete a notebook.
Scope: notebooks:write
/api/v1/notebooks/:id/filesUpload dataset files. Multipart form field name: files (repeat for multiple). Max ~200 MB each.
Scope: notebooks:files
curl -X POST "$HOST/api/v1/notebooks/ID/files" \
-H "Authorization: Bearer $FOUNDRY_API_KEY" \
-F "files=@./train.jsonl"/api/v1/notebooks/:id/filesList uploaded files and workspace path.
Scope: notebooks:files
/api/v1/notebooks/:id/filesRemove a file. Body: { "name": "train.jsonl" }.
Scope: notebooks:files
/api/v1/notebooks/:id/trainApply optional config, then run the full recipe on Modal (config → load → train → eval → export).
Scope: notebooks:train
curl -X POST "$HOST/api/v1/notebooks/ID/train" \
-H "Authorization: Bearer $FOUNDRY_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'/api/v1/notebooks/:id/runRun cells. Body actions: { "action":"run_all" } | { "action":"run_cell","cellId":"…" } | { "action":"add_cell","kind":"code" }.
Scope: notebooks:run
/api/v1/notebooks/:id/statusLightweight poll: status, running, failed, lastRunAt, Modal readiness.
Scope: notebooks:read
/api/v1/notebooks/:id/logsLive events + cell outputs/errors. Optional ?since=ISO8601 to fetch only newer lines.
Scope: notebooks:read
Templates
Pass templateId on create:
llm-lora— Chat / instruction LoRAwhisper— Speech recognitionhandwriting— Handwriting / visionvideo— Short video adaptersvoice— Voice clonerobotics— Imitation learning
Errors
{
"error": "Invalid or missing API key",
"code": "unauthorized"
}401 unauthorized— missing/invalid Bearer key403 forbidden— key lacks required scope404— notebook not found for this account400— validation / Modal not configured / run failure message inerror
Dataset format
Prefer JSONL: one example per line. Short, clean pairs beat giant dumps.
{"messages":[
{"role":"user","content":"Do you deliver Sundays?"},
{"role":"assistant","content":"Yes — Nairobi only, 10am–4pm."}
]}
{"messages":[
{"role":"user","content":"Shipping time to Mombasa?"},
{"role":"assistant","content":"2–3 business days with standard courier."}
]}After upload, open the notebook in the dashboard or keep driving it via MCP / the Agent API.
Credits
Notebooks are free. Creating notebooks, uploading datasets, running cells, and training on Modal do not debit your account credits. Credits may still apply to other Foundry products (for example hosted AIs). See Pricing and Billing.
Ready to connect an agent?
Create an API key, add the MCP connector URL from Settings, and let the agent create notebooks and upload datasets for you.