Security & Data

Last reviewed: 21 August 2026

Installing an MCP server means letting an unfamiliar service sit inside your AI assistant. The reasonable question is: what can it reach, what does it keep, and who else sees it? This page answers that. It is written from an internal audit of the server’s source code, and where something is imperfect it is stated rather than left out.

Who operates Liftli

Liftli is operated by Oded Tsamir (LinkedIn profile, a LinkedIn-verified identity). He is a second-time founder. Before Liftli he was VP Product at Optibus, a company that grew from 20 to 400 people, raised around $260M and became public transport’s first unicorn — and before that, more than 20 years in product.

Contact for anything on this page, including deletion requests: support@liftli.ai.

Liftli has three parts, and this page is mostly about the first: the MCP server that connects to your AI assistant, a web console at app.liftli.ai, and an optional messaging channel such as Telegram. The Privacy Policy covers the legal picture; this page covers the mechanics.

What the server can and cannot access

An MCP server has no channel for reading your conversation. That is a property of the protocol rather than a promise: your AI client decides when to call a tool and which values to put in it, and the server receives that call. Across all 28 tool definitions in the server there is no history, messages, conversation or context parameter — nothing a client fills with a transcript. What reaches Liftli is what your assistant puts into a tool call.

How the tools actually work

Most tools receive only what you hand them: a draft to critique, an idea to plan around, a post to save. A few work differently. When you ask for ideas, playbook(kind='seed_extraction') returns a mining brief rather than an answer — the mining is done by your assistant, which saves each seed via remember(..., body_content=...) — and the sources it accepts tell your assistant to fetch material from this chat or from another tool you have connected. playbook(kind='voice_extraction') does the same for voice calibration: it returns a prompt that mines your existing LLM history, and news_monitor returns a scan brief your assistant executes with its own web search — the server itself searches nothing. So for these tools the server does ask. It asks your assistant to find material in your own notes and conversations and send back what it finds — which happens when you ask for ideas, or ask Liftli to learn how you write.

Whatever your assistant sends arrives through an ordinary parameter. The tools that carry your material: remember(text, body_content) (a body up to 30,000 characters, saved as a seed file), critique(draft), ready_to_post(draft), plan_comment(post_text), playbook(source_text), analyze_results(posts, engagement), save_strategy(content, pillars_json), save_post(text), log_outcome(post_summary, published_text), distribute(text), media(prompt) and channel(message). contact_support takes a single message parameter — what you typed to support — and collects nothing alongside it.

So the accurate line is not “Liftli never sees your content”. It is: Liftli sees the material you ask it to work on, plus whatever your assistant mines when you ask for ideas, and it has no channel for reaching the rest.

The server does not run a language model

Liftli’s MCP server holds no model-provider credential and calls no model API. The writing happens in your assistant, on your subscription. What the server contributes is structure: a bundled knowledge base plus your own saved profile, assembled into a brief. Two things sit outside the MCP server and do use models — image generation when you call media(action='generate'), which the backend performs, and transcription of voice notes you send to the Liftli bot. Both are covered under Third parties.

The backend host is pinned to an allowlist

Every URL the MCP server builds for Liftli’s backend is checked against an exact host allowlist first. A host outside it resolves to an empty string and the feature goes inert instead of sending, so a misconfiguration — or a host someone tried to inject — cannot receive your data. The third parties below each have their own fixed endpoint set by configuration: no tool parameter chooses a destination host.

What is stored, and for how long

Everything Liftli saves for you is kept under your own account, and one account cannot read another’s data.

Your working data

The record of what your assistant sends to Liftli’s tools

The deployed telemetry setting is full. At that setting, when a hosted request runs for an identified account, Liftli records one entry against your account: the tool name, whether it succeeded, how long it took, and the values of a fixed list of 21 argument names:

Each value is truncated at 4,000 characters. Arguments outside that list of 21 are not written to this file. This capture requires a hosted request with an identified account, so a local install on your own machine records nothing. The file is written inside your own per-account folder, alongside everything else Liftli saves for you.

Which tools contribute is decided purely by parameter name — the list above — not by what the tool does. So critique(draft), remember(text, body_content) and plan_post(idea, goal) are captured, while recall(query), contact_support(message) and approve_post(post_id) are not: those parameter names are not on the list. The cut runs through the middle of tools, and in both directions — playbook’s source_text, the raw material you paste for seed mining, and analyze_results’ pasted posts and engagement data are NOT on the list either, so they are never captured anywhere.

How long it is kept: for the lifetime of your account. The files rotate monthly for housekeeping, but nothing expires and nothing is deleted automatically. If you want it gone, you have to ask — see Deletion.

Why it is kept. Seeing the actual inputs is how the prompts, briefs and gates get fixed when the output is wrong for a particular person. It is not sold, not shared with advertisers, and not used to train AI models.

Two related facts. This record lives on Liftli’s own disk: at the full setting the free-text intent block is not sent onward, so the analytics provider receives metadata. And a companion event log — tool name, success, duration and the account — is kept on the same disk with no expiry either. That log is a single shared file per month with one line per call tagged by account, rather than a file inside your folder; it holds no content.

Things that are deliberately not stored

One weakness worth naming

There is no encryption at rest. The files are UTF-8 JSON on the server’s disk, and confidentiality rests on host and filesystem controls plus the hosting platform’s own security. Writes are crash-atomic (written to a temporary file and swapped into place). If encryption at rest is a hard requirement for you, Liftli does not meet it today.

Deletion

Email support@liftli.ai and ask for your data to be deleted. It is handled manually, and you get a confirmation when it is done. Being exact about what that means, because the mechanism matters:

Deletion is also covered by the Privacy Policy, which sets a 30-day response commitment for verified requests. In practice it is far faster.

The two ways to connect

A personal key

You generate a key in the Liftli console and paste one command, which registers the connector in your AI client’s own config file. The key travels as an Authorization: Bearer header, or — for connector UIs that cannot set a header — in the connector URL. It is an identifier Liftli exchanges for your account id, and it cannot spend money: the one billing-related tool, upgrade, returns a link you open in your own browser, and payment happens at the payment provider.

OAuth sign-in

Your client runs a standard OAuth flow against Liftli’s identity provider and stores the token in its own credential store rather than in a config file you manage, so no Liftli secret ends up in a file you have to protect. In Claude Code this needs 2.1.186 or newer; the personal key exists so older versions and header-less connector UIs still work. Liftli sends nothing about you to the identity provider — the server fetches its public signing keys over a plain GET and verifies your token locally.

What the tools do

The source contains 24 hosted @mcp.tool functions plus 4 browser-bridge tools registered only for a local install, making 28 tool definitions. (The count used to be 54; a deliberate 2026-08 consolidation merged and retired thirty of them, which is why this page is shorter than it was.) How many your client is offered depends on the door: the default connector advertises all 24; the ChatGPT app-store door advertises 23, because that store’s policy bans in-app subscription upsells and the in-chat checkout tool is hidden there — along with every mention of it in the served instructions. One of the 24, the news scanner, is registered only when its feature flag is on (it is on in production). Nothing is added for any client, so 24 is the maximum.

Two things that happen on essentially every call

A timing wrapper wraps all 24 hosted tools and records the tool name, whether it succeeded, how long it took, which AI-client family called, and enum/counter flags; some tools also emit a named funnel event (strategy locked, seed used, profile rewritten, credit consumed, paywall hit, activated). Every hosted tool forwards this, so a claim that some tools contact nobody outside Liftli would be false. Separately, almost every tool touches your onboarding-progress file so the footer knows where you are — most through a shared footer, a few indirectly (the status render, dismissal preferences, or a first-read backfill). The one tool with no path to that file is upgrade, which keeps its own offer ledger instead.

Which tools can make something appear publicly under your name

One: distribute. It is the single door for publishing now or scheduling for later (send), rescheduling (move), cancelling (cancel) and replacing a queued post’s text (replace) — the three separate publishing tools this page used to describe were merged into it, behavior intact. connect_account returns an authorization link for you to open, and approve_post stamps a saved post as approved; neither publishes. Substack is deliberately not publishable at all — there is no Substack API behind it, so a Substack draft is reminder-only — and LinkedIn articles are refused at every door for the same reason.

The gate is enforced by the server rather than by a prompt an assistant could be talked around, and the decision lives in one rule that every ship path calls. Text that has never cleared a critique is hard-blocked; the authorizing review is matched by a hash of the exact text, so any material edit reads as unreviewed; and a review only clears the surface it examined — a Substack review cannot clear a LinkedIn publish. A critique stamp alone is not enough either: the executed review’s verdict has to be submitted back, so a review that was narrated but never run keeps the gate shut. A first post additionally has to score at least 8.0 overall and at least 8.0 on hook strength alone (a weighted total can hide a weak hook); after three honest review rounds the best pass ships with a receipt saying so. One caveat stated plainly: the score is graded by the reviewing model itself, and the server records it so drift is detectable. distribute and upgrade are annotated as requiring user interaction, so a client that honors that hint will not let a model fire them silently.

Where that is imperfect, stated plainly. The four distribute actions are not equally guarded. send and replace go through the review rule; move and attaching media do not, and a move can revive a failed post so that it publishes after all. What closes most of the old gap: a move that carries new text is refused outright, so timing can change without review but the words cannot. Cancelling can only reduce what goes out. The remaining exposure is timing and attached media on a post that already cleared review.

The 24 hosted tools, by group

Each group heading is true of every tool beneath it. Retention is decided separately, by parameter name — the 21-name list — rather than by what a tool does, so it is called out per group.

GroupWhat it receivesWhat it storesWhat leaves Liftli
1. Read what you have saved (2 — strategist_briefing, recall) nothing, or a query nothing new beyond housekeeping; neither takes a 21-name parameter the analytics event; both also ask the backend for your scheduled queue (and recall for your media list)
2. Build a brief, metered by plan (6 — plan_post, plan_comment, playbook, analyze_results, news_monitor, rewrite_profile) an idea, topic, question or pasted material a usage credit keyed by a hash of your text, not the text; all 6 take a 21-name parameter your account id, to ask the backend which plan you are on — no content
3. Review drafts — the publish gate (2 — critique, ready_to_post) your draft a review record: a hash of the draft, the verdict, two scores and up to 400 characters of findings — never the draft text itself (the draft can land in the interactions record, because draft is one of the 21 names); a cleared draft is saved as a reviewed post the analytics event only
4. Save what you tell Liftli (7 — remember, save_post, save_profile, save_strategy, log_outcome, approve_post, dismiss_suggestion) memory items and seed bodies, posts, strategy sections, profile fields, outcome notes, dismissal flags in your folder, as the thing you asked to save; 4 of the 7 take a 21-name parameter. remember refuses anything matching the credential pattern the analytics event. save_profile also sends your company, role and how you found Liftli — those three fields only — to Liftli’s own customer record via the backend
5. Act through Liftli’s backend (6 — distribute, media, connect_account, onboard, upgrade, contact_support) post text, media handles, an image prompt, a LinkedIn profile URL, a support message post status, media references and scrape results; 2 of the 6 take a 21-name parameter your account id plus that payload, to the backend — which holds your LinkedIn and X tokens and reaches LinkedIn or X, the payment provider or the image-generation provider on your behalf. onboard alone also sends your LinkedIn profile URL directly to a third-party profile-data provider
6. Your phone connection (1 — channel) a message, a post id, or a link/unlink action the identifier you linked, while it is linked; unlinking removes it the post text or digest to Telegram, or to a third-party messaging gateway if that is the channel you linked. Linking itself sends nothing at call time

The tool-by-tool breakdown behind this table — every tool, its parameters, what it reads, what it writes and where it sends — is available on request at support@liftli.ai.

distribute can also reach the plan lookup: a free account’s publish allowance is checked at the backend, and rescheduling a failed post re-books a plan-counted slot.

Tools that exist only on a local install (4, never advertised by the hosted server)

If you run Liftli on your own machine with the Chrome extension paired, four more tools are registered: they report whether the extension is paired, read the LinkedIn post or profile on your screen, and type a comment into the focused box for you to submit. The browser protocol has exactly three commands — read the current post, read the current profile, insert a comment — and none submits, so the server has no way to post one. They emit the same tool-name analytics event as every other tool; on a local install the event log is a file on your own machine. Two things can leave your computer: the comment tool’s plan check, and that analytics event if the analytics key is configured in your install.

Third parties

These are described by role and guarantee rather than by brand. That is deliberate: a list of vendor names is a supply-chain map for anyone hostile, and tells you nothing the role and the guarantee do not. If you want them named — for a vendor review, a DPA, or your own diligence — ask support@liftli.ai. LinkedIn, X and Telegram are named throughout, because you connect those yourself.

Reached by the MCP server itself

DestinationHow many tools reach itWhat it receives
A product-analytics providerall 24 hosted toolstool name, success flag, AI-client family, an internal-account flag, a timestamp and enum/counter flags; some calls add a named funnel event. Call duration stays in Liftli’s own log. At the deployed setting, no free-text intent fields. The account identity in these events is a hash, not your email or name
Liftli’s own backendabout half the toolsthe acting group sends content or an action (post text, media handles, image prompt, support message); the metered group sends your account id to ask which plan you are on — no content
Telegram, once you link it1 — channel, plus scheduled digests and remindersthe post text, or a digest headline and source link, pushed to your phone
A LinkedIn profile-data provider1 — onboardyour LinkedIn profile URL; the rest of the payload is fixed scrape options
A messaging gateway provider1 — channel, if that is the channel you linkedthe message text being pushed to your phone

Two more appear in the server that no tool can reach. A speech-to-text provider transcribes voice notes — but only when you send one to the Liftli bot, from the inbound webhook handler rather than from a tool; the audio is not kept. An identity provider is fetched for the public signing keys used to verify your sign-in token; nothing about you is sent, and verification happens locally.

Reached by Liftli’s backend on your behalf — one hop further out

The MCP server holds no LinkedIn, X, payment, image-generation or email credential — those live in the backend. It does hold credentials for the five services it calls itself.

What a search of the source does not find

A full search of the MCP server’s package finds no call to any model API, none to a web-search, team-chat or cloud-storage provider, none to SMTP, and none to the LinkedIn, X, payment or email-delivery APIs. The distinction that keeps this honest: publishing, payments, email and image generation are capabilities you get, but the MCP asks Liftli’s backend to perform them and holds none of those provider credentials itself; genuinely absent — not merely delegated — are model APIs, web search, cloud-storage SDKs and SMTP. A dormant team-chat placeholder exists with no feature flag behind it, so it is off. onboard builds a linkedin.com/in/<slug> string to hand to the profile-data provider; the server itself does not fetch linkedin.com. And one pre-emption for anyone grepping the source: the speech-to-text provider’s URL contains the substring /openai/ because that provider exposes an OpenAI-compatible route shape — no model-provider account is involved.

Things that happen outside any tool call

Questions, or something wrong on this page

If you or your AI assistant find a claim here that does not match the behaviour you observe, say so — support@liftli.ai. Corrections to this page are more useful than a good impression of it.

See also: Privacy Policy · Terms of Use · All legal documents