Open Fluyo

Privacy Policy

Last updated: 5 November 2026. Versión en español.

Fluyo is two different things with two different data behaviours, and this policy treats them separately because conflating them would be misleading:

 The editor — fluyo.spaceThe MCP server — mcp.fluyo.space
Does it receive your diagrams? No. They never leave the browser Yes. They travel over the network to the server
Does it store them? Only on your own machine (localStorage) No. Processed in memory, then discarded
When does it apply? Whenever you use the website Only if you connect the remote server to your AI assistant

If you only use the editor at fluyo.space and have never added the remote MCP connector, section B does not apply to you at all: the editor has not sent your diagrams to any server. The only thing that can take them off your machine is what you do with a file or a link.

Who is responsible

Fluyo is an open-source project maintained by itsnect (Claudio Jiménez Flores), based in Chile. It is not an incorporated company, sells nothing, has no customers and processes no payments.

Contact for any privacy matter: hello@fluyo.space. Further channels on the support page.

A. The editor at fluyo.space

The editor is a static file site. There is no application server, no database and no API of our own for the browser to call. Everything — drawing, animating, computing layout and encoding the GIF — happens on your machine, using your machine's processor.

Your diagrams

When you use the editor, they do not leave your browser. There is no backend for them to go to. When you click Save, the browser downloads a .fluyo.json file to your disk; when you click Open, it reads one from your disk. Neither involves a network request.

There is a third route: a URL of the form fluyo.space/#d=… carries the diagram inside the link itself, compressed and encoded. It is what the MCP server returns so you can see the animated diagram without saving any file.

That content does not travel in the HTTP request. It sits after the hash, and browsers do not send a URL fragment: not in the request, not in the Referer header. You can check this yourself — serve the project locally, open one of these links and look at the access log: the line shows the path and nothing of the fragment. What does reach the server is what comes before the hash: the path and, if present, the query, such as ?ejemplo= or ?lang=, which do not carry your document. The content only reaches a server if you send it there explicitly, for example by giving the link or the document to the MCP server.

What you should know: the diagram is encoded, not encrypted. Anyone who receives the link can read it. It also stays in your browser history — which syncs across your devices if you have that turned on — and anywhere else you pass the link along. Share it with the same judgement you would apply to the file.

Share a copy through a link

The Share action asks for confirmation and generates fluyo.space/s/#d=… with a complete copy of the diagram. Anyone with the link can view it. The copy travels in the #d= fragment, so it does not go in the HTTP request either. Fluyo does not store this copy on a server and cannot revoke the link. Later changes in the editor do not modify the copy. The limit in this version is 64 KiB for the final URL; if it is exceeded, you can export the file.

Autosave

The current session is saved to your browser's localStorage, under the key fluyo.autosave.v1. That is local storage on your own machine, not a server: nobody else can read it, and it is erased when you clear site data in your browser.

Product analytics

The public site includes usage analytics served by Umami Cloud, without cookies and without identifying you by name or account, although Umami derives a session identifier.

What Fluyo sends is this closed list of events; automatic capture is off and there are no pageviews:

EventMeaning and properties
editor_openedOnce per editor load. entry: direct, example (arrived with ?ejemplo=) or link (arrived with #d=), never the URL. returning: yes if this browser had opened Fluyo before, no otherwise (see “First visit”). locale: interface language (es, en, fr, ja, zh or other).
first_edit_completedFirst real change per editor load. Selection, pan, zoom, navigation, import and restore do not count. No properties.
diagram_createdFirst edit that leaves nodes in a previously empty document, at most once per load. No properties.
diagram_savedExplicit download started from Save; not autosave, and no confirmation that it reached the disk. format: fluyo_json.
diagram_exportedFile generated and download started. format: gif, png, jpg or svg. No confirmation that it reached the disk.
file_importedA valid document was applied. source: file or link; format: fluyo_json. The source does not attribute MCP authorship.
present_startedPresentation mode actually entered, even without full screen. No properties.
example_loadedA published example ended up open. example: identifier from the fixed list. source: url (?ejemplo=), menu (the “Example” button) or entry (the entry card).
entry_chosenFirst visit only: what was done with the entry card. choice: explore, blank or dismiss (Escape, touching the canvas or opening something else).
story_createdA Story was created in the editor. origin: new, variant (“Another way from here” or “Duplicate as failure”) or copy (duplicate). Never its name or its sentences.
story_startedA Story started playing. surface: editor or present. trigger: user or entry (started by the entry card). Once per playback, not per step.
story_completedThat playback reached the end, watched or skipped through. surface: editor or present. Once per playback.
gif_animation_addedanim: key of one of the eight built-in animations.
link_failedreason: decode, schema, too_large or unsupported.
share_createdAfter confirming and actually creating a link within the limit. kind: story or diagram. variants: yes if its other ways travel with it, no otherwise.
share_viewedAfter the viewer's first successful render. story: yes if it carries a playable Story. locale: interface language, as above.
viewer_story_startedIn the viewer, when “Play” is pressed. No properties.
viewer_story_completedIn the viewer, that playback reached the end. No properties. Once per playback.
share_opened_in_editorWhen “Open in Fluyo” is explicitly pressed in the viewer. No properties.

What Umami gets from the request itself. Like any server, Umami receives your IP address and User-Agent. From them it records approximate country, region and city, browser, operating system and device type, and computes a session identifier using a hash of the site, the IP, the User-Agent and a salt that, according to Umami, rotates monthly by default. Also according to Umami, the IP is processed transiently for those calculations and not stored as a field in its analytics records, although Umami and its providers may record it in operational and security logs, separate from analytics. Whoever administers Fluyo can see this derived data and each session's sequence of events in Umami's dashboard, and consults it to understand how Fluyo is used. Fluyo sends Umami no user or account identifier and does not publish per-session activity. The session identifier avoids cookies, but it is not a guarantee of absolute anonymity.

First visit

The first time this browser opens the editor without a document in the link, a card over the canvas offers to watch an example in motion or to start blank. So that it is not offered again, the editor stores the key fluyo.seen with the value 1 in localStorage: no date, no identifier, and it is never sent. It does not appear either if any other fluyo.* key exists (saved session, theme or language). The only thing that leaves is its consequence, returning: yes/no in editor_opened; it counts browsers, not people: a private window, cleared site data or another device count as new.

The content of your diagrams is never sent to analytics. Only the events and values in these closed lists are accepted. The events carry no file or node names, text, images, prompts, document IDs or personal data. The comparison that detects the first edit happens only in local memory.

No private URLs are sent. Automatic capture is disabled with data-auto-track="false". Query and fragment are excluded with data-exclude-search and data-exclude-hash; on top of that, the data-before-send filter rebuilds the payload with a fixed path /, a fixed title Fluyo and an empty referrer. No additional automatic browser properties are sent. Asynchronous loading uses a bounded in-memory queue; blocking Umami does not stop you from working.

The analytics script loads only when the domain is fluyo.space or www.fluyo.space. If you clone the repository, open it locally or self-host it, that code never runs and no network call is made. Preview domains are deliberately excluded. The condition lives in js/analytics.js, in a single block, so you can verify it yourself.

If you want zero analytics: run the project locally or self-hosted, or block the cloud.umami.is domain. Fluyo works the same — the analytics code is written to fail silently.

The other external request

Besides the analytics script above, the editor makes a single request to a third party: it loads gif.js — and its gif.worker.js — from the cdnjs (Cloudflare) CDN; that is the library that encodes the GIF. It is a code download: none of your content is sent to it. As with any HTTP request, Cloudflare sees your IP address and user agent while serving the file. The service worker precaches it on first visit, so on later visits it is usually not even requested.

Umami serves its script from cloud.umami.is and receives the sanitized events at gateway.umami.is. These are the only third-party services the editor calls, and this list is complete: there are no external fonts, icons or stylesheets. Everything else is served from fluyo.space.

B. The MCP server at mcp.fluyo.space

Here is the part that needs saying plainly: the MCP server does receive the content of your diagrams over the network. This is unavoidable — it cannot edit or export a diagram it has not received — and it is the substantive difference from the editor.

This applies only if you have added https://mcp.fluyo.space/mcp as a remote connector in your AI assistant. If you run the server locally over stdio (npx fluyo-mcp), nothing leaves your machine and this section does not apply either.

What is received

How it is used and for how long

It is processed in memory and discarded. Each HTTP request builds a fresh server, handles the message and throws it away. There is no database, no disk, no cache and no sessions: the server is stateless by design, not by configuration. The document exists in the process's memory for as long as the request takes — milliseconds — and disappears with it.

The server does not store it, does not forward it to other services and does not use it to train anything. Since it runs on Cloud Run, the document passes through Google's infrastructure for the duration of the request.

The link it returns. Alongside the diagram, the tools return a fluyo.space/#d=… URL that opens it in the editor. It is built inside the same process from the document just received: no new request to anywhere, nothing stored, nothing logged. What that link means for whoever shares it is explained above, under Diagrams that arrive in a link.

What is logged

One line per request. A successful request looks like this:

{"ts":"2026-08-03T16:20:11.437Z","route":"/mcp","method":"POST",
 "status":200,"outcome":"ok","durationMs":7,
 "requestBytes":220,"responseBytes":472,"tools":["create_diagram"]}

When something fails, two more fields can appear, and neither carries content: toolErrors, which is how many tools returned an error — not which one, not why — and errorType, which is the error's class name (TypeError, ZodError…), never its message or its stack trace. Those nine fields plus the timestamp are the complete structure; there is no other.

No user data — document, labels, tool arguments, error messages, IP address — is written to the log. The name of the invoked tool is recorded, never its arguments; and if something fails, the log records that it failed and what class of error it was, never the value that caused it.

This does not rest on the discipline of whoever edits the code: the type describing a log line is a closed structure with no field that free text could occupy, and automated tests plant unrepeatable markers in a diagram's labels and fail if those markers appear in any log line. There is no debug mode that lifts these restrictions.

IP addresses and rate limiting

The server limits requests per IP address so that an open endpoint does not become an abuse or billing problem. For that purpose, and only that purpose, it keeps in RAM a record of the IP address and the timestamps of its recent requests.

Authentication

The server asks for no credentials, creates no accounts and issues no tokens. There is nothing of yours on file because there is no sign-up.

Dependencies involved

No dependency was added for the HTTP transport: it uses Node's standard library. The dependency tree is the one already pulled in by the official Model Context Protocol SDK.

Of that whole tree, six packages actually load at runtime: @modelcontextprotocol/sdk, zod, @hono/node-server, ajv, ajv-formats and zod-to-json-schema. None of them persists anything and none of them makes outbound network requests. Their role is limited to routing the message, validating its shape and converting between request representations.

One honest detail: @hono/node-server, the component that adapts the HTTP request, may write connection errors to the console — ECONNRESET and similar, typical of a client that disconnects mid-response. Those messages are socket errors and contain no user data: they carry no document, no labels and no tool arguments.

Hosting platform logs

The two domains have different providers: fluyo.space is hosted on Vercel, and mcp.fluyo.space on Google Cloud, specifically on Cloud Run. Cloudflare resolves the DNS for fluyo.space, without acting as a proxy: HTTP requests to that domain do not go through it.

Vercel serves requests to the site, so it receives your IP address, the requested path with its query, your user agent and other headers. Its logs are of several kinds, and not all periods are confirmed. According to Vercel's documentation, on the Hobby plan Fluyo uses, runtime logs are kept for 1 hour. We have not confirmed a period for its request logs or its CDN requests, and we have not found a published one for its operational and security logs. When you use the editor, the content of your diagrams does not reach it, nor does the #d= fragment of a link.

As the MCP server's hosting provider, Google Cloud keeps its own platform logs in Cloud Logging, separate from the MCP server's and outside the control of this project's code. In the case of Cloud Run, the platform writes one log entry per request automatically, before the request reaches our code. Those logs include:

Retention on Google Cloud: 7 days. This is not the default — Google Cloud Logging retains 30 days out of the box — but a value set explicitly on the _Default bucket. The exact command that sets it is published in the server's README, so this figure is verifiable rather than a promise.

They do not contain request bodies, so the content of your diagrams does not appear in them.

These logs should not be confused with the application log described above: they are two different things. The application log writes no user data at all, not even the IP address, and that stays true regardless of what happens to platform retention. Cloud Run's platform logs do contain the IP address, which is why they expire after 7 days.

For how Google handles that data as an infrastructure provider, see the Google Cloud privacy notice.

Who the data is shared with

Fluyo does not sell data and does not use it for advertising or to train models. The product does not read analytics data or make automated decisions about people with it. What Umami records per session and who consults it is described under “Product analytics”.

To work, the site needs hosting, resource delivery and analytics providers. When serving a request they receive information that can be personal, such as your IP address and User-Agent, and they process it to provide that service and under their own terms. This is what each one receives and why:

ProviderWhat it receivesWhy
VercelRequests to fluyo.space: IP, path with its query, user agent and other headers. According to Vercel, Hobby plan runtime logs are kept for 1 hour; the other periods are not confirmedHosting and delivery of the web application
Google CloudRequests to mcp.fluyo.space, with any document you send to the MCP server, which is processed in memory. Platform logs of those requests (IP, path, status, user agent) are retained 7 days and do not include the bodyHosting and running the MCP server
Umami CloudThe events listed above (no pageviews), plus IP and User-Agent on the request, from which it derives approximate location, browser, operating system, device and a cookieless session identifier. Analytics record retention: 6 months, as Umami states for the Hobby plan Fluyo uses.Usage analytics
CloudflareOn cdnjs, the request for the gif.js files: IP and user agent. As DNS for fluyo.space, the resolution queries; not the HTTP requestsDelivery of the GIF library and DNS
Cloudflare and GoogleOnly if you write to hello@fluyo.space: your address and your message. Cloudflare receives them and forwards them to the project's Gmail account, where they are read and answeredHandling your enquiry

In normal use of the editor, none of them receives the content of your diagrams. If you send a document to the MCP server, it reaches that server on Cloud Run, as section B explains. A link with #d= carries the diagram inside it: whoever opens it receives it, and so does any service you pass it through.

Children

Fluyo is not directed at children under 13 and does not knowingly collect data from them. Since there are no accounts and no sign-up, there is also no account that could belong to a child.

Your rights

The practical situation is unusual and worth stating as it is: there is no account of yours to access, rectify or erase, because Fluyo never asks for your name, email or sign-up.

Verify it yourself

What Fluyo's code does is checkable: the source of both parts is public and MIT-licensed.

Changes to this policy

If it changes, the date in the header is updated and the change is recorded in the repository's public history, commit by commit. A change that materially affects what data is received will additionally be announced in the repository.

In case of discrepancy between translations, the Spanish version prevails.