Serverless functions. Servers shouldn't be your problem.

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.

handler.py
def handler(event):
    name = event["query"].get("name", "world")
    return {
        "statusCode": 200,
        "body": {"message": f"Hello, {name}!"},
    }
GET fn-hello.orkestr.run/?name=visitor

What's different

The things that come up the moment you deploy something real.

EU data residency

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.

Errors that tell you what crashed

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.

Test from the dashboard

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.

Ship serverless MCP servers for Mistral, Claude, Cursor.

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 Codeberg
wrapper
Stateless function speaking MCP on the inbound side, your scraper's REST contract on the outbound side. Validates the Bearer token, routes by `method`, returns wrapped responses. ~50 lines.

When two functions earn their keep

A 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.

Compatible with any MCP client (stateless transport)
fn-mcp-wrapper / handler.py
# 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)},
        ]})
POST { "method": "tools/list" }

When something breaks at 2am.

Public callers see an opaque error. The dashboard shows you exactly what crashed, with the captured traceback.

What the public caller sees
HTTP/2 500 · application/json · server: orkestr
{
  "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.

What you see in the dashboard
Recent platform errors (1)
function_crashed
Function exited before becoming ready
a few seconds ago · 412ms · req 8f2a4e1b
Traceback (most recent call last):
  File "/app/handler.py", line 4, in <module>
    MOLLIE_KEY = os.environ["MOLLIE_API_KEY"]
                 ~~~~~~~~~~^^^^^^^^^^^^^^^^^^
KeyError: 'MOLLIE_API_KEY'

No per-invocation billing. Ever.

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.

PlanFunctionsvCPUMemoryIdle timeout
Free10.5256 MB30 min
Pro101512 MB60 min
Team5021 GBAlways warm

Common questions

Which languages are supported?
Python 3.10, 3.11, 3.12, 3.13 and Node.js 18, 20, 22, 24. Pick a runtime when you create the function. pip and npm dependencies are supported with build-layer caching, so subsequent deploys with the same dependencies are fast.
How does cold start work?
Functions scale to zero when idle. The first request after that wakes the container. We start it, wait for the port to open, then proxy your request through and return the upstream response. Typical cold start is 1-5 seconds depending on dependencies. Free tier sleeps after 30 minutes of no traffic, Pro after 60 minutes, Team never (always-warm).
When should I use Functions vs a full app?
Functions are right for webhooks, scheduled jobs, small APIs, anything where you do not want a long-running server. If your code is a handler that takes an event and returns a response, use Functions. If you have a Next.js / Django / Express app with multiple routes, deploy it as a project and let API routes ride inside the same container - same compute, no extra billing surface.
Where do my functions run?
EU only. Data centers in Falkenstein (Germany) and Helsinki (Finland). No US cloud, no edge POPs in non-EU regions. If you need GDPR-clean infrastructure for a German enterprise customer, this matters. If you need lowest-possible latency in São Paulo, we are not your platform yet.
How does pricing work?
Flat plan pricing, no per-invocation charge. Free includes 1 function (0.5 vCPU / 256 MB). Pro at €9.99/mo includes 10 functions (1 vCPU / 512 MB). Team at €29.99/mo includes 50 functions (2 vCPU / 1 GB). You pay the same whether your function handles 10 or 10 million requests this month.
Can I run MCP servers on Functions?
Yes - that's the two-function pattern shown above. One function does the actual work (REST endpoint), one wraps it in MCP / JSON-RPC for LLM clients. Both deploy as ordinary Python or Node functions, no special runtime. The transport is stateless request/response; works with Mistral Studio, Claude Desktop, Cursor, ChatGPT desktop, and any MCP-compatible client. Streamable-HTTP and SSE clients that require server-initiated notifications are not supported by this transport pattern.
Can I bring custom domains?
Yes on Pro and Team. Each function gets a fn-{name}.orkestr.run subdomain by default; you can attach your own domain on paid plans.

Deploy a function in 30 seconds.

Free tier, no credit card. Sign up, paste a handler, get an HTTPS URL.

Get started free