Paste a Python or Node handler. Get a public HTTPS URL. No Dockerfile, no repo, no per-invocation pricing. Scale to zero when idle, wake on the next request.
Free tier includes 1 function. No credit card.
def handler(event):
name = event["query"].get("name", "world")
return {
"statusCode": 200,
"body": {"message": f"Hello, {name}!"},
}
The things that come up the moment you deploy something real.
Your function runs in Germany or Finland. No data ever leaves the EU. We publish the full sub-processor list, GDPR DPA available on request.
When a function fails on cold start, the dashboard shows you the captured stderr inline, next to the failing request. No grepping through a log tail in another tab to find the import error.
Built-in test console. Pick a method, set headers and a body, hit invoke. See the response and the timing without pulling out curl. Live logs stream in another tab.
The Model Context Protocol turns any HTTP endpoint into a tool an LLM agent can call. The architecture below shows a scraper we run, split into a public MCP wrapper and a private REST worker so credentials stay isolated.
Browse all MCP servers on CodebergA single function is plenty for most MCP servers - the LLM client hits one endpoint that parses JSON-RPC, runs the tool, returns. The split into two earns its keep when the work belongs to a separate service other internal apps already hit, or when you want the public MCP surface to never see the upstream credentials.
In this pattern each function gets its own secret. The wrapper holds only its MCP Bearer token; the worker holds the upstream credentials. Rotating one boundary doesn't require touching the other.
# Speaks MCP / JSON-RPC 2.0 over HTTP.
# Drop into an LLM client (Mistral, Claude, Cursor) as a tool.
TOOL = {
"name": "scrape",
"description": "Scrape URLs and return cleaned text + metadata.",
"inputSchema": {"type": "object", "properties": {
"url": {"type": "string"},
}},
}
def handler(event):
body = json.loads(event["body"] or "{}")
method = body.get("method")
if method == "tools/list":
return _ok(body["id"], {"tools": [TOOL]})
if method == "tools/call":
result = call_scraper(body["params"]["arguments"])
return _ok(body["id"], {"content": [
{"type": "text", "text": json.dumps(result)},
]})
Public callers see an opaque error. The dashboard shows you exactly what crashed, with the captured traceback.
{
"error": "function_crashed",
"message": "Function exited before becoming ready",
"function": "fn-mollie-webhook",
"request_id": "8f2a4e1b-7c93-4d5e-a6f1-...",
"diagnostics": {
"stage": "cold_start",
"duration_ms": 412,
"exit_code": 1
}
}No file paths, library versions or traceback. Safe to expose on a public function URL.
Traceback (most recent call last):
File "/app/handler.py", line 4, in <module>
MOLLIE_KEY = os.environ["MOLLIE_API_KEY"]
~~~~~~~~~~^^^^^^^^^^^^^^^^^^
KeyError: 'MOLLIE_API_KEY'Flat plan price. Whether your functions handle a thousand or a hundred million requests this month, the bill is the same. Each tier gets faster cold starts and more memory.
| Plan | Functions | vCPU | Memory | Idle timeout |
|---|---|---|---|---|
| Free | 1 | 0.5 | 256 MB | 30 min |
| Pro | 10 | 1 | 512 MB | 60 min |
| Team | 50 | 2 | 1 GB | Always warm |
Free tier, no credit card. Sign up, paste a handler, get an HTTPS URL.
Get started free