Spaces - a demo that is on the web
A running demo with a GPU, no server and no bill - and a tool for your own agent on the side.
Milestone A public URL a stranger can open without logging in, your Gradio app behind it on free hardware - and the MCP endpoint of that same Space answers.
This is the chapter the course exists for.
A Space is a Git repo that does not merely contain files but runs. You push
an app.py into it, the Hub builds a container from it, starts it and gives it
an address. After that, anyone with a browser can use your application. No
domain, no reverse proxy, no certificate, no server. With a GPU if you want. No
bill.
If anything about Hugging Face is meant to surprise you, it is this.
The four kinds
| SDK | What for |
|---|---|
| Gradio | ML demos in Python. Builds the interface from your function signature. The default case. |
| Streamlit | data applications in Python, more layout control, more code. |
| Docker | your own image, free choice of port. Everything the other three cannot do. |
| Static | plain HTML/JS. No server, no Python. |
We take Gradio, for a reason that only becomes visible at the end of this chapter: a Gradio Space is not just an interface.
Step 1 - Create the repo
hf repo create my-first-demo --repo-type space --space-sdk gradioThe command creates an empty Space repo in your namespace and tells you the URL. The Space is on the web from that moment - still showing an error page, because it contains no application.
Now fetch it locally:
git clone https://huggingface.co/spaces/yourusername/my-first-demo
cd my-first-demoStep 2 - The application
Two files, no more.
requirements.txt:
gradio
transformers
torch
app.py:
import gradio as gr
from transformers import pipeline
pipe = pipeline(
"text-classification",
model="distilbert-base-uncased-finetuned-sst-2-english",
model_kwargs={"use_safetensors": True},
)
def sentiment(text: str) -> dict:
"""Estimates the sentiment of an English sentence."""
result = pipe(text)[0]
return {result["label"]: float(result["score"])}
demo = gr.Interface(
fn=sentiment,
inputs=gr.Textbox(label="Sentence", lines=3),
outputs=gr.Label(label="Sentiment"),
title="Sentiment in one line",
description="A small model estimates whether a sentence sounds positive or negative.",
examples=[
["The delivery arrived three weeks late."],
["Thank you, everything worked perfectly."],
],
)
if __name__ == "__main__":
demo.launch()
Thirty lines, half of them labels. That is exactly Gradio's offer: the interface grows out of your function's signature, not out of a template.
Trying it locally first pays off - otherwise the Space builds with your mistake in it:
pip install -r requirements.txt
python app.py
# → runs on http://127.0.0.1:7860Step 3 - Push it and watch
git add app.py requirements.txt
git commit -m "First version: sentiment classification"
git pushNow open the Space page in your browser. Top right it says Building. Under Logs you can watch the container come into being: packages are installed, the model is fetched on first start. The first time this takes a few minutes, after that noticeably less.
Then it says Running, and your application is reachable at
https://huggingface.co/spaces/yourusername/my-first-demo
By anyone. Without a login. Send the address to somebody who does not have an HF account - that is the test.
Step 4 - The hardware, and what "free" means
The Space settings list the tiers under Hardware. Two of them cost nothing (as of August 2026):
CPU Basic is the default: 2 vCPU, 16 GB RAM, permanently free. That is what your demo is running on right now. For small classification models, embeddings, data applications and anything that does not generate, it goes surprisingly far.
ZeroGPU is the interesting one: a real GPU that does not belong to you but is assigned to you - for the seconds in which your function computes. It is free for Gradio Spaces, with a quota that is smaller for the free account than for the paid one.
You switch it in the settings; in code you mark the function that needs the GPU:
import spaces
@spaces.GPU
def generate(prompt: str) -> str:
...
Everything above that - your own T4, L4, A10G, A100 - is billed by the hour, starting at roughly $0.40 per hour and open-ended upwards (as of August 2026). That is the line at which a demo becomes an operating cost.
Step 5 - Secrets
If your Space needs an API key, that key does not belong in the repo. The Space settings have Variables and secrets: variables are visible, secrets are not. Both end up as environment variables in the container.
import os
token = os.environ["HF_TOKEN"] # stored as a secret, not in the code
A Space repo is a public Git repo with a history. A token committed once stays in that history even if you remove it in the next commit - at that point the only remedy is to revoke it.
Step 6 - The part almost nobody knows
Your demo is not only an interface. Gradio automatically provides an HTTP API for every application - at the very bottom of the page there is a "Use via API" link with ready-made call examples.
And since Gradio ships it, the same Space can also answer as an MCP server. One line:
if __name__ == "__main__":
demo.launch(mcp_server=True)
After that your Space additionally has an MCP endpoint, usually at
https://yourusername-my-first-demo.hf.space/gradio_api/mcp/sse
Your function's docstring becomes the tool description, the Gradio input types
become the schema. That is why there is a docstring at the top of app.py - it
is not documentation for humans, it is the description a model reads.
That tips the meaning of the chapter: a Space is not only a demo for people but a tool for your agent. How an agent copes with many such tools without its context exploding is explained by the building block Tiny Agents - and the course of the same name builds it from scratch.
The milestone
Three things, all verifiable:
- A public URL somebody without an HF account can open in a browser and that does something meaningful there.
- The Space runs on a tier that costs nothing - the settings say CPU Basic or ZeroGPU.
- Calling the MCP endpoint returns an answer instead of a 404:
curl -N https://yourusername-my-first-demo.hf.space/gradio_api/mcp/ssePoint 1 you can send to people. Point 3 you can plug into an agent.