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
1-minute demo

From handler to live URL

Paste code, pick a runtime, deploy. Get a public HTTPS endpoint instantly.

orkestr - function demo

What will you ship first?

A handler is enough for more than you'd think.

webhooks

Payment & git webhooks

Catch Mollie, Stripe or GitHub events, verify the signature, update your database. The URL is stable, TLS is handled, and retries hit a warm VM.

bots

Slack & Discord bots

A slash command is one POST handler: parse, act, reply. No server idling between messages, and warm responses land well inside Slack's timeout.

agents

MCP tools for agents

Give Claude, Cursor or Mistral a tool that actually does something. One handler is a full MCP server - the pattern is right below.

apis

Tiny APIs

That one endpoint your frontend needs - a currency conversion, a geo lookup, a signed upload URL. Too small for a repo, perfect for a handler.

forms

Form backends

Contact forms on static sites need somewhere to POST. Validate, forward to your inbox or CRM, return 200. Done before your coffee cools.

glue

Glue between services

Fetch from one API, reshape, push to another. Your logic in real code - versioned, testable, and not priced per task by an automation SaaS.

What's different

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

A micro-VM per function

Every function runs in its own micro-VM with hardware-level isolation, not in a shared container runtime. A pool of pre-booted VMs sits in front, so cold starts land in about half a second and warm requests in the low hundreds of milliseconds.

EU data residency

Your function runs in Germany, Finland or France. 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.

Logs that outlive the instance

Scale-to-zero usually means the logs die with the instance. Here every run is captured as a durable stream - when a function winds down, its logs stay in the dashboard, retained per plan.

Auth in one toggle

Every function is public or key-protected, your choice per function. The platform enforces the key before your handler runs, so auth never lands in your code - or in your git history.

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 handler below is a complete MCP server - and it's deployed, so you can invoke it right here.

Browse all MCP servers on Codeberg

One function is a full MCP server

An MCP server is just an HTTP endpoint that answers two JSON-RPC methods: tools/list (what can you do?) and tools/call (do it). That fits in one handler.

If you've written a cloud function before, this is the same shape: an event in, a JSON response out. Paste it, get a URL, and every MCP client can use it as a tool.

Compatible with any MCP client (stateless transport)
fn-mcp-demo / handler.py
# A complete MCP server. Hand the URL to Mistral,
# Claude or Cursor as a tool - no SDK, no session state.
TOOL = {
    "name": "scrape",
    "description": "Fetch a URL and return cleaned text.",
    "inputSchema": {"type": "object", "properties": {
        "url": {"type": "string"},
    }},
}

def handler(event):
    req = json.loads(event["body"] or "{}")

    if req["method"] == "tools/list":
        return rpc(req["id"], {"tools": [TOOL]})

    if req["method"] == "tools/call":
        text = scrape(req["params"]["arguments"]["url"])
        return rpc(req["id"], {"content": [
            {"type": "text", "text": text},
        ]})
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.

See what each plan includes →

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. Each function runs in its own micro-VM, and we keep a pool of pre-booted VMs ready - a cold invoke binds your code into a waiting VM instead of booting one, so nothing boots on the request path. Typical cold start is about half a second; warm requests answer in the low hundreds of milliseconds. Free tier sleeps after 30 minutes of no traffic, Pro after 60 minutes, Enterprise 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), Helsinki (Finland) and Roubaix (France). 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 €15/seat/mo includes 10 functions (1 vCPU / 512 MB); Enterprise lifts the limits with custom function compute. You pay the same whether your function handles 10 or 10 million requests this month.
Can I run MCP servers on Functions?
Yes - the handler shown above is a complete MCP server. It answers tools/list and tools/call as JSON-RPC over HTTP and deploys as an ordinary Python or Node function, 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 put an API key on a function?
Yes. Every function has an auth toggle: public, or API-key required. Callers authenticate with an Authorization: Bearer header (or x-orkestr-api-key); the key lives in the function's config, not in your handler code, and the platform enforces it before your handler runs. Flip the toggle and redeploy - for functions on the micro-VM engine that's a sub-second config write, not a rebuild.
Can I bring custom domains?
Yes on Pro. Each function gets a fn-{name}.orkestr.run subdomain by default; you can attach your own domain on the Pro plan.

Deploy a function in 30 seconds.

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

Get started free