Persistent workspace
KV, files, snapshots, and branches. Versioned. Crash-safe. The agent's memory survives everything.
Keys stored
1,247
Snapshots
38
Branches
6
Plynf sits between your AI agents and your business tools — Salesforce, Slack, Jira, Drive, internal databases — and cuts every tool response down to what the agent actually needs. Agents that stay focused. Same answers, provably. 40–80% fewer tokens on bloated tool responses.
$ curl -fsSL https://raw.githubusercontent.com/nico-schindlbeck-jpg/plynf/main/install/install.sh | sh
Integrations & ecosystem
The problem
Without Plynf
Agents lose focus in the noise
A Salesforce lead has 50–200 fields. Your agent needs 8. The other 190 dilute attention, invite hallucinated detail, and blow the context window on long tasks.
You pay for fields nobody reads
Audit columns, sync tokens, null custom fields — serialized into every single call. On tool-heavy agents that's 40–80% of the tool-response tokens, every step, forever.
No control over what crosses the line
Whatever the API returns is what the model provider sees. PII, internal notes, fraud scores — shipped wholesale, with no record of what crossed.
With Plynf
The model sees only what matters
Keep-lists you control — casing- and schema-robust — cut each tool response to the fields the agent actually needs. Focused context, sharper answers.
Provably the same answers
A lossless layer (nulls, empties, metadata) can't change the answer by construction. The open-source verification harness replays raw vs. shaped through your model and diffs the answers — measured, not asserted.
Deterministic, auditable, never blanks
Pure transform — no second model in the path. Schema mismatch? It falls back safely instead of erasing data. PII can be masked or hashed before it ever leaves.
Try it now — no signup, no install
This is the actual shaping mechanism, running in your browser — same logic, same GPT-4o tokenizer the proxy bills against. Nothing leaves this page, so go ahead and paste a real response from your API, CRM, or MCP server.
No keep-list? You still get the lossless layer — null/empty
fields and audit metadata removed. That can never change the model's answer.
Field matching is casing-robust: order_id finds
orderId, OrderID, …
Paste JSON on the left — or load a sample —
and the saving appears here instantly.
Counted with the GPT-4o tokenizer (o200k_base) on the
compact JSON the model would actually receive. In production this happens inline,
deterministically, on every tool call — one base_url swap.
Quality is verifiable, not asserted: the open-source
verification harness
replays raw vs. shaped context through your model and diffs the answers.
Customer-Support Agent · Salesforce + Order-DB
The agent is asked "What's the status of order #12345?".
It calls get_order. The order
database returns 150 fields of payment metadata, warehouse pickers,
audit trails, internal flags. Plynf strips it down to the 8 fields
the agent actually needs — before the LLM ever sees the response.
Without Plynf
{
"order_id": "12345",
"customer_id": "C-0001102",
"customer_name": "Jane Doe",
"customer_email": "jane.doe@example.com",
"customer_phone": "+49 30 1234567",
"customer_tier": "gold",
"customer_lifetime_value": 12480.5,
"status": "in_transit",
"fulfillment_status": "shipped",
"payment_status": "paid",
"refund_status": "none",
"carrier": "DHL",
"tracking_number": "DHL-99887766554433",
"estimated_delivery": "2026-05-28",
"last_status_update": "2026-05-27T14:32:00Z",
"warehouse_id": "WH-DE-01",
"warehouse_zone": "B-04",
"warehouse_bin": "B-04-117",
"picker_id": "EMP-2218",
"packer_id": "EMP-1097",
"payment_provider_charge_id": "ch_3OabcXYZ123",
"payment_provider_fee": 9.62,
"card_brand": "visa",
"card_last4": "4242",
"risk_score": 0.04,
"fraud_review_status": "passed",
"items_summary": "3 items, $284.00 total",
"items": [
"… 3 line items, 18 fields each …"
],
"audit_log": [
"… 5 entries …"
],
"history": [
"… 8 events …"
],
"created_at": "2026-05-25T19:24:00Z",
"updated_at": "2026-05-27T14:32:00Z",
"_internal_trace_id": "trace-7f1a-9b2c-d4e5",
"_internal_correlation_id": "corr-5c6d-7e8f",
"// …": "… and ~120 more fields"
} With Plynf
{
"order_id": "12345",
"customer_name": "Jane Doe",
"status": "in_transit",
"tracking_number": "DHL-99887766554433",
"estimated_delivery": "2026-05-28",
"carrier": "DHL",
"items_summary": "3 items, $284.00 total",
"last_status_update": "2026-05-27T14:32:00Z",
"total_amount": 333.95
} examples/customer-support/run_demo.py · tiktoken (o200k_base) · gpt-4o input price $5/1M.
Six ways in. One engine.
The optimization layer underneath is identical — same policies, same caching, same audit log — whether you wire Plynf in as a drop-in LLM proxy (nine native dialects — OpenAI, Anthropic, Gemini, Bedrock, Ollama, Cohere and more — routing across any provider), an MCP server, a native SDK in five languages, a no-code node, a chat bot, or a webhook endpoint.
OpenAI · Anthropic · Gemini · Azure · Ollama · vLLM
Change `base_url`. Keep your client code. One front-door speaks all three API dialects.
client = OpenAI(
api_key="sk-…",
base_url="https://app.plynf.com/v1"
) Anthropic Claude API · MCP-native clients
Register Plynf as an MCP server in your client config.
mcp_servers=[{
"url": "https://app.plynf.com/mcp/salesforce"
}] Python · TypeScript · Go · Swift · Kotlin
Wrap your existing tools — LangChain, LlamaIndex, CrewAI, AutoGen.
from plynf.langchain import wrap_tools
tools = wrap_tools([sf_tool, slack_tool]) n8n · Zapier · Make.com · Copilot Studio
Install the Plynf node from the marketplace. Drag-and-drop.
// n8n workflow → Plynf · Salesforce → LLM Slack · Teams · Discord · Salesforce Agentforce
Deploy a ready-made bot. One-click deploy buttons or “Add to Slack” OAuth.
@Plynf what's the status of order #12345? Custom Python / Node agents · Bedrock Lambda
POST tool calls. Get shaped responses back.
curl -X POST app.plynf.com/v1/tools/get_order/invoke \
-d '{"order_id":"12345"}' Data minimization, not promises
That's not just a cost thing. It's a data-exposure thing. When you ship 200 Salesforce fields into an LLM call, you've effectively shared those fields with the model provider. Plynf lets you draw the line technically — which fields cross, which don't, which get masked, which get logged.
And it doesn't guess what matters. You set the rules — or start from a shipped default — and Plynf enforces them deterministically, plus a lossless pass that drops only null, empty, and metadata fields. Same answer the model would've given on the full payload, minus the wasted tokens.
Deterministic — no second model
Shaping is a pure transform, not another AI guessing what matters. Same input, same output, every decision in the audit log. No extra call, latency, tokens, or cost.
Field-level allow-lists you control
You whitelist what each tool may return (or start from a shipped default). Matching is casing- and synonym-robust — orderId, order_number, ORDER_ID all resolve.
Lossless auto-minimize
Null/empty fields and audit metadata are dropped automatically, zero config. It only removes data that carries no signal — so it can never change the model's answer.
Never blanks on a schema mismatch
If a keep-list can't find a field (a renamed schema), the response isn't emptied — it falls back to the safe, minimized body and flags the policy to fix.
PII masking and redaction
Sensitive fields can be hashed, masked, or removed before reaching the model.
Read-only mode per connector
Block write actions entirely. Useful for pilots and compliance reviews.
Tenant-isolated cache with TTL
Redis-backed, namespaced per tenant, never persisted to disk. TTLs bounded by policy.
Self-hosted or EU-hosted
Helm chart for your own infra; Plynf Cloud runs in Germany. You decide where your data is.
Plynf is a technical layer. It helps you implement data minimization, field-level access control, and audit logging — it does not replace a GDPR assessment, a DPIA, or your own legal review. DPA available on request.
The flow
Four stages, one call. The runtime carries the state so your prompt stays focused on the next decision, not the last ten.
How it works
Plynf is infrastructure, not a framework. It runs underneath whatever agent you already have. Anthropic, OpenAI, Mock, or local. Bring your own loop.
One command installs Plynf and starts the runtime in the background. Live dashboard at localhost:7424.
One SDK call. Pick Python, TypeScript, Go, Swift, or Kotlin. The agent gets a workspace, gateway, and channels.
Multi-tenancy, OAuth, audit, cost tracking, k8s + Helm + Terraform ready out of the box. v1 API stable.
Capabilities
Each one removes a category of plumbing you'd otherwise have to build, deploy, and maintain yourself. They are designed together, not retrofitted.
KV, files, snapshots, and branches. Versioned. Crash-safe. The agent's memory survives everything.
Keys stored
1,247
Snapshots
38
Branches
6
Single boundary for every external tool. Caching, audit, OAuth, cost-caps. All built-in.
Durable typed message queues. Multi-agent pipelines without prompt-history sprawl.
Worker pool with lease-based recovery. Crash mid-flight, pick up where you left off. Verified by a runnable demo.
JWT, multi-tenant, GDPR, rate limits, tamper-evident audit, published threat model.
GitHub, Slack, Linear, Notion, Google Workspace, Atlassian, Salesforce, Asana. Real flows.
Lifecycle
Every write is a version. Every snapshot is a checkpoint. Every branch is an experiment you can throw away or merge back without fear.
Every write is versioned
No silent overwrites. A monotonic version counter per workspace makes "what did we know at v17" trivially recoverable.
Snapshots are named checkpoints
Take a labelled freeze before a risky tool call. Restore in one call when the model goes off the rails.
Branches are speculative
Fork the workspace, let an agent try three approaches in parallel, throw away the failures, merge the winner.
Merges are explicit
Fast-forward or three-way merge, your choice. Conflicts surface to the agent as structured data, not raw diffs.
SDKs
The same primitives (workspace, gateway, channels, workflows) in the language your team already ships in. API-stable, no breaking changes through v1.
# Python
from plinth import Plynf
client = Plynf(
workspace_url="http://localhost:7421",
gateway_url="http://localhost:7422",
api_key="local-dev",
)
ws = client.workspace("my-research")
ws.kv.set("topic", "renewable energy")
# Token-efficient: stores in workspace, doesn't bloat prompt history
sources = client.tools.invoke("web.search", {"query": "renewable energy"})
for src in sources["results"]:
content = client.tools.invoke("web.fetch", {"url": src["url"]}) # cached
ws.files.write(f"sources/{slug(src['url'])}.txt", content)
ws.snapshot("sources-collected")// TypeScript
import { Plynf } from "@plinth/sdk";
const client = new Plynf({
workspaceUrl: "http://localhost:7421",
gatewayUrl: "http://localhost:7422",
apiKey: "local-dev",
});
const ws = client.workspace("my-research");
await ws.kv.set("topic", "renewable energy");
// Token-efficient: stores in workspace, doesn't bloat prompt history
const sources = await client.tools.invoke("web.search", {
query: "renewable energy",
});
for (const src of sources.results) {
const content = await client.tools.invoke("web.fetch", { url: src.url }); // cached
await ws.files.write(`sources/${slug(src.url)}.txt`, content);
}
await ws.snapshot("sources-collected");// Go
package main
import (
"context"
"github.com/plinth/sdk-go/plinth"
)
func main() {
ctx := context.Background()
client, _ := plinth.New(plinth.Config{
WorkspaceURL: "http://localhost:7421",
GatewayURL: "http://localhost:7422",
APIKey: "local-dev",
})
ws := client.Workspace("my-research")
_ = ws.KV.Set(ctx, "topic", "renewable energy")
// Token-efficient: stores in workspace, doesn't bloat prompt history
sources, _ := client.Tools.Invoke(ctx, "web.search", map[string]any{
"query": "renewable energy",
})
for _, src := range sources["results"].([]any) {
content, _ := client.Tools.Invoke(ctx, "web.fetch", map[string]any{
"url": src.(map[string]any)["url"],
}) // cached
_ = ws.Files.Write(ctx, "sources/"+slug(src)+".txt", content)
}
_ = ws.Snapshot(ctx, "sources-collected")
}// Swift
import Plynf
let client = Plynf(
workspaceURL: URL(string: "http://localhost:7421")!,
gatewayURL: URL(string: "http://localhost:7422")!,
apiKey: "local-dev"
)
let ws = client.workspace("my-research")
try await ws.kv.set("topic", value: "renewable energy")
// Token-efficient: stores in workspace, doesn't bloat prompt history
let sources = try await client.tools.invoke(
"web.search",
args: ["query": "renewable energy"]
)
for src in sources.results {
let content = try await client.tools.invoke(
"web.fetch",
args: ["url": src.url]
) // cached
try await ws.files.write("sources/\(slug(src.url)).txt", content)
}
try await ws.snapshot("sources-collected")// Kotlin
import dev.plinth.Plynf
suspend fun main() {
val client = Plynf(
workspaceUrl = "http://localhost:7421",
gatewayUrl = "http://localhost:7422",
apiKey = "local-dev",
)
val ws = client.workspace("my-research")
ws.kv.set("topic", "renewable energy")
// Token-efficient: stores in workspace, doesn't bloat prompt history
val sources = client.tools.invoke(
"web.search",
mapOf("query" to "renewable energy")
)
for (src in sources["results"] as List<Map<String, Any>>) {
val content = client.tools.invoke(
"web.fetch",
mapOf("url" to src["url"])
) // cached
ws.files.write("sources/${slug(src["url"] as String)}.txt", content)
}
ws.snapshot("sources-collected")
}→ Result: a 5-source research task uses 71% fewer tokens than the same task without Plynf. Measured across three topics, fully reproducible.
Token economics
Same task, same model, same five sources. The difference is whether the agent re-reads its own past notes on every step. Real workload, fully reproducible.
Without Plynf
23,704
tokens / task
Prompt re-reads history every step
tokens
removed
With Plynf
6,795
tokens / task
State lives in the workspace
Task
5-source research summary
Model
Claude · 10 reasoning steps
Reproducible
examples/token-bench in repo
The side-effect nobody counts: tokens you never send are compute that never runs — and data-center cooling water that never evaporates. At fleet scale that's an estimated ~0.7 mL of water per 1,000 tokens saved. Your dashboard tallies the litres. (order-of-magnitude estimate)
Across workloads · 800 simulated runs
We measured eight different workflows across eight personas — from a hobby researcher to a 14-file code review, from a 10-turn support agent to a quarterly market report. The shape is the same everywhere: chat-history goes quadratic, Plynf stays roughly linear. Token reduction averages 80.3% across 800 Monte-Carlo runs, typically 78.6 — 87.4% per workflow.
Headline · 800 runs
80.3%
mean token reduction
Across 8 workflows × 100 perturbed runs with realistic variance on page sizes, file counts, and conversation turns. The shape is the same everywhere:
Typical case: 78.6 — 87.4% per workflow (IQR). Stays above 76% for everything except RAG (where even good baselines compress aggressively). Stable across seeds — runs reproduce within ±0.5pp.
30 academic PDFs
From $91.68 → $9.39 on one report.
Analyst hands the agent 30 papers. Naive baseline carries 600k tokens of fetched text on every synthesis step. Plynf keeps them on the desk, carries handles in the prompt.
10-turn customer support
The bill stops doubling at turn 4.
Every prior message + every CRM lookup gets re-sent on every reply in the baseline. Plynf's per-turn prompt only carries the handles that turn actually needs.
14-file pull request
Same coverage. 84% cheaper.
Per-file analysis. The agent reviewing file 12 doesn't need to see findings for files 1–11 in its prompt — but the baseline insists. Plynf scopes each step.
12-section market report
Each section carries only what it cites.
13 sections, each drawing on different parts of a 6-source corpus. Naive chains drag every source + every prior section forward. Plynf's prompt grows with the decision, not the data.
All eight workflows · 100 runs each · seed-stable
Run yourself: python -m benchmarks.workflows.run_simulation
| Workflow | Mean | |
|---|---|---|
| 5-source research synthesis | 84.4% | |
| 30-PDF literature review | 97.4% | |
| Researcher → Writer → Reviewer (3 rounds) | 81.9% | |
| Code review on 14-file PR | 82.5% | |
| 10-turn customer support with lookups | 83.5% | |
| Sales lead enrichment + CRM sync | 77.3% | |
| Q&A across 50 contracts with citation | 47.0% | |
| 12-section quarterly market report | 88.7% | |
| Pooled across 800 simulated runs 800 pooled runs | 80.3% | |
800 Monte-Carlo runs
Each scenario perturbed 100 times — realistic variance on page sizes, file counts, conversation turns. The mean across all 800 is the headline.
Reproducible · seed=42
Md5-stable across processes, runs across Python invocations. Run with a different seed and you'll get within ±0.5pp of these numbers.
Cross-checked
Suite vs live LLM runs match within ±5 percentage points. The conservative 71% on the hero is from a real run; 80.3% is the upper-bound model.
Methodology: MODEL.md · Simulation results: SIMULATION_RESULTS.md · Raw JSON: /results
Token reduction
Mean across 8 workloads · 800 runs
Tests passing
Services + all SDKs
SDK languages
Py · TS · Go · Swift · Kotlin
OAuth providers
Real flows, real tokens
Services
Deployable units
Multi-agent
Pipelines without prompt-history sprawl. Each agent reads from one durable typed queue, writes to the next. Add a reviewer step without re-engineering the upstream.
Architecture
Each service runs as its own process. Replace, scale, or harden any one of them independently. No hidden coupling. No magic.
Agent side
SDK in 5 languages. One call, no glue code.
Plynf runtime
Workspace + Gateway + Identity. All replaceable.
Tools side
8 OAuth providers built-in. MCP for the rest.
Connect
Point a base URL at Plynf, paste one config, or click Install — across every major AI SDK, agent IDE and automation tool. No rewrite. Most people are one copy away.
Pricing
Apache 2.0 forever. Self-hosted is and will always be free. We gate on volume and features — never on how you connect. Every integration type (proxy, MCP, SDK, no-code node, webhook) works on every tier, including Free.
Cloud is in beta — Pro and Enterprise are confirmed-only today. Self-hosted available now. See roadmap →
For solo builders and OSS projects.
For teams shipping production agents.
For regulated industries and bigco.
Need something custom? Just ask. All tiers run on identical core code. Apache 2.0, no proprietary forks.
FAQ
Still have one? Email us or open a discussion.
Ready when you are
Subscribe, paste your key into your agent, done — nothing to install. Or self-host with one command. Either way: production-ready when you are.
Prefer self-hosting?
$ curl -fsSL https://plynf.com/install.sh | sh