text2flink
You can generate, verify, and deploy Apache Flink SQL streaming jobs from natural language requests, with real cluster execution to ensure correctness. Capabilities:
Generate & verify Flink SQL jobs: Describe a streaming job in plain English along with source schemas and sample data; the server generates Flink SQL (supports windowed aggregates, top-N, deduplication, interval/temporal joins, filters), executes it on a real Flink cluster, and returns the verified SQL plus actual output or errors.
Ground Kafka topic schema: Automatically discover the schema of a live Kafka topic by sampling messages, returning the inferred schema and sample rows for direct use in job generation.
Deploy to Kafka: Generate a deployable topic-to-topic pipeline (
INSERT INTO <sink> SELECT ...) that reads from source topics and writes to a destination topic. The SELECT logic is verified on real Flink with sample data, and the sink can be upsert-kafka for aggregating/updating jobs.
Turns natural language into execution-verified Apache Flink SQL jobs, generating streaming pipelines with windowed aggregates, joins, late-data handling, and Kafka deployments that are verified by running against real Flink clusters.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@text2flink Convert "count page views per user per 5-minute tumbling window from Kafka topic 'events'" into a deployable Flink job"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
text2flink
Alpha: runnable & tested, APIs may change.
Give your AI coding agent the ability to write Apache Flink SQL that provably works.
AI agents write plausible Flink SQL — and streaming SQL is exactly where plausible isn't correct. A 30-second window where you meant one minute; late records kept when they should be dropped. It compiles, it runs, it returns believable rows, and it silently under-reports in production for weeks. The agent has no way to know it got the watermark or window semantics wrong — a compile check and a golden-file diff both pass.
text2flink closes that loop. Register it once as an MCP server and your agent can verify the SQL it just wrote on a real Flink cluster and self-correct from precise feedback — before you ever see it:
claude mcp add text2flink -- python3 -m text2flink.mcp_serverThe agent calls verify_flink_sql with its SQL + a schema + sample data + the intended
semantics, and gets back a machine-readable verdict it can act on:
{ "verified": false,
"violations": [
{ "kind": "value_mismatch", "detail": "(00:00:00, u1): got 2.0, expected 3.0" },
{ "kind": "spurious_window", "detail": "(00:00:30, u1) emitted but not expected" } ] }The agent reads the violations ("my window is 30s, should be 60s"), fixes the SQL, and verifies
again — a ~1–2s loop — until verified: true. Not "does it parse", not a golden diff:
actual streaming correctness, run on real Flink. (The server also exposes
generate_flink_job / ground_kafka_topic / deploy_to_kafka for the draft-and-ship flow — see
docs/USE_CASES.md.)
Or drive it yourself — CLI + CI
The same engine runs standalone. Write your Flink SELECT and a small test-file next to it
(sample data + the semantics you expect); verify grades it on Flink and exits non-zero on
failure, so it drops straight into a CI gate:
text2flink verify orders_per_min.test.json
# ✘ FAIL orders_per_min
# [value_mismatch] (00:00:00, u1): got 2.0, expected 3.0 ← 30s window, not 1 minFastest taste, no setup: python3 examples/verify_flink_sql.py verifies a correct job, then
catches a subtly-broken one.
New here? docs/USE_CASES.md for the AI-agent path, docs/VERIFY.md for the CLI/CI path, DESIGN.md for the architecture.
Status
Alpha — runnable and execution-verified today; APIs may change. The core loop is proven: take a Flink SQL job (hand-written or generated), run it on a real local Flink cluster, and assert streaming-specific properties (windows fire once, counts match a ground truth, event-time and watermarks respected) instead of brittle golden diffs — and, for generated jobs, repair a wrong one automatically from structured verification feedback.
What it does today
Verify an AI agent's Flink SQL over MCP — the
verify_flink_sqltool runs the SQL the agent wrote on real Flink and returnsverified+ machine-readable violations, so the agent self-corrects in a ~1–2s loop. This is the headline; see docs/USE_CASES.md.Verify hand-written Flink SQL —
text2flink verify job.test.jsonruns your own SELECT on real Flink and grades it against the streaming semantics you declare, with precise violations on failure and a non-zero exit for CI. See docs/VERIFY.md.Draft a job from natural language — NL → JobSpec extraction via a model-agnostic LLM layer that runs on OpenAI (
OPENAI_API_KEY) or Anthropic (ANTHROPIC_API_KEY), with an offline heuristic proposer fallback so everything runs with no API key. A convenience entry point into the same verifier.Windowed aggregates — tumbling, hopping, and session windows (per-key inactivity-gap merging via the Flink
SESSIONTVF).Updating operators — unbounded
GROUP BY(running totals), top-N, and deduplication (ROW_NUMBER()), verified via batch-mode collect and deployed to an upsert-kafka topic keyed by their partition keys.Joins — time-bounded interval joins of two event-time streams, and temporal (versioned-table) joins (
FOR SYSTEM_TIME AS OF). Semantics confirmed against real Flink before being encoded in the oracle.Late-data / watermark correctness as a first-class, tested dimension: the oracle drops records whose event-time is at/behind the watermark, and a task verifies the generated job drops exactly those records — the thing batch Text2SQL cannot express.
Live Kafka grounding — discover a source schema from a real Kafka topic (sample → infer → wire the connector), graded by running on real Flink against the real topic in bounded mode. Avro grounding is supported via the Flink
avroformat end-to-end; the Confluent Schema Registry (avro-confluent) path is verified offline against a mock registry.Deployable Kafka pipelines (topic → topic) — a spec compiles to a complete
INSERT INTO <sink> SELECT …script; still verified by running to completion and grading the sink topic against the oracle.Multiple codegen targets — Flink SQL (execution-verified), a submittable PyFlink Table API program (
flink run -py job.py), and Apache Spark SQL (a portability proof graded against the same oracle; the product stays Flink-first).
StreamBench
A declarative, contributable benchmark scored by execution pass rate, not string match —
22 tasks as JSON files in streambench/tasks/, grouped into
core / advanced / adversarial tiers. Add a task or submit a model result without writing
engine code (see CONTRIBUTING.md). Live results in
LEADERBOARD.md:
Proposer | core | advanced | adversarial | total |
| 6/6 | 9/9 | 7/7 | 22/22 (100%) |
| 6/6 | 9/9 | 0/7 | 15/22 (68%) |
The adversarial tier (misleading phrasing, implicit/negated filters, multi-key grouping,
reworded windows, non-second time units) makes the benchmark discriminating, and has surfaced
real bugs no prior task exercised. Every task's gold spec is execution-verified on Flink
(scripts/check_gold.py), so a broken task can't hide as a proposer failure.
Roadmap
Confluent Schema Registry (avro-confluent) end-to-end, DataStream codegen, K8s deployment
manifests, and a bigger adversarial tier.
Requirements
This machine's default Java (26) and Python (3.14) are too new for Flink, so Phase 0 uses:
Apache Flink + JDK 17, installed via Homebrew (
brew install apache-flink openjdk@17).Python 3.11+ for the orchestrator (no PyFlink dependency — it drives Flink's SQL client as a subprocess, so the system Python is fine).
For the live-Kafka example only:
brew install kafka, plus the Flink Kafka SQL connector jar in Flink'slib/(e.g.flink-sql-connector-kafka-5.0.0-2.2.jarfrom Maven Central).For the Avro example: the Flink Avro format jar in Flink's
lib/(e.g.flink-sql-avro-2.2.1.jarfrom Maven Central).For the (experimental) cross-engine example only:
brew install apache-spark(JDK 17).
Install
pip install "git+https://github.com/clementlemon02/text2flink.git" # the library + `text2flink` CLI(A pip install text2flink from PyPI is a tag away — see RELEASING.md.)
Contributors work from a checkout instead: pip install -e ".[dev]" (editable, with pytest).
No install is even required to try it: python3 -m text2flink.cli verify <file> runs from a
checkout, and the example scripts below run directly. Python 3.10+; running a verify needs a
local Flink + JDK 17 (see Requirements).
Run it
text2flink verify examples/verify/orders_per_min.test.json # verify your Flink SQL (see docs/VERIFY.md)
python3 examples/verify_flink_sql.py # verify a correct job, then catch a subtly-broken one
python3 examples/tumbling_count.py # generate a job, verify it, then catch & repair a broken one
python3 examples/run_streambench.py # run StreamBench, report execution pass raterun_streambench.py uses the offline heuristic proposer by default. To use a real model:
OPENAI_API_KEY=sk-... python3 examples/run_streambench.py # OpenAI (default gpt-4o)
ANTHROPIC_API_KEY=sk-... python3 examples/run_streambench.py # AnthropicRelated MCP server: Kafka MCP Server
Layout
text2flink/
ir.py # IR: JobSpec (windows/agg) + IntervalJoinSpec + TemporalJoinSpec
codegen.py # IR -> Flink SQL: aggregates, interval joins, temporal joins
data.py # row-dict -> Flink CSV
oracle.py # reference interpreter: ground truth incl. late-drop + session windows
runtime.py # local Flink cluster lifecycle + run SQL (sql-client), collect results
gateway.py # SQL Gateway harness: submit over REST (~1-2s/case, no per-run JVM boot)
assertions.py # property-based streaming correctness checks
verify.py # verify(spec) + verify_sql/verify_batch/gateway -> run on Flink -> assert
testfile.py # load a verify test-file (SQL + sources + data + expected semantics)
cli.py # `text2flink verify` / `text2flink cluster` — the correctness-layer command
llm.py # model-agnostic LLM clients: OpenAI + Anthropic (raw HTTPS, no SDK)
proposer.py # NL -> JobSpec + repair: LLM / offline-heuristic / scripted proposers
pipeline.py # extract -> verify -> repair loop for one task
kafka.py # live Kafka grounding: sample a topic, infer schema, build a Source
schema_registry.py # Avro/Schema-Registry grounding: exact types via avro-confluent
deploy.py # deployable INSERT jobs (append + upsert sinks), verify by consuming
mcp_server.py # MCP server (stdio) — lets an AI assistant call text2flink as a tool
mcp_tools.py # generate-and-run-on-Flink logic behind the MCP tool
pyflink.py # third codegen target: same IR -> a submittable PyFlink Table API program
spark.py # EXPERIMENTAL portability proof: same IR -> Spark SQL, same oracle
streambench.py # loader for the StreamBench corpus
streambench/
tasks/*.json # the benchmark corpus (declarative, contributable)
examples/
verify_flink_sql.py # verify hand-written Flink SQL; catch a subtly-broken job
verify/ # a verify test-file (.test.json) + the .sql it checks
tumbling_count.py
run_streambench.py
kafka_grounding.py # discover schema from a live Kafka topic, then verify
kafka_pipeline.py # deployable topic -> topic pipeline (INSERT INTO sink), verified
avro_pipeline.py # real Avro end-to-end on Flink (no Schema Registry)
cross_engine.py # (experimental) one IR compiled + verified on Flink AND Spark
tests/ # fast offline suite (no Flink): corpus, oracle, codegen, parsing
LICENSE # Apache-2.0
CONTRIBUTING.md # how to add a StreamBench task
.github/workflows/ci.yml # runs the offline tests on 3.10–3.12Development
pip install -e ".[dev]"
pytest # fast, offline — no Flink required
python3 scripts/check_gold.py # verify every task's gold spec on Flink (task soundness)
python3 scripts/leaderboard.py # score a proposer, update results/ + LEADERBOARD.mdContributions welcome — the highest-value ones are a new StreamBench task (especially adversarial) and submitting a model to the leaderboard. See CONTRIBUTING.md.
Available Tools
3 toolsdeploy_to_kafkaA
Produce a deployable topic->topic Flink job: INSERT INTO a Kafka sink topic SELECT ... The SELECT logic is verified on the sample data by running it on real Flink; the returned deployable_sql is the full pipeline (upsert-kafka sink for updating jobs). Use when the user wants to WRITE results to a Kafka topic, not just query them.
Inputs: request (required), sources (required), sink_topic (required), sample_data (required), +1 more.
generate_flink_jobA
Generate an Apache Flink SQL streaming job from a natural-language request and a schema, then RUN it on real Flink against sample data and return the verified SQL plus its actual output (or the Flink error). Use whenever the user wants a Flink streaming job (windowed aggregates, top-N, dedup, interval/temporal joins, filters) — it produces jobs that provably run, unlike hand-written SQL. Supply representative sample rows.
Inputs: request (required), sources (required), sample_data (required).
ground_kafka_topicA
Discover a Kafka topic's schema by sampling its messages, returning a schema + sample rows ready to pass to generate_flink_job. Use when the user references a real topic and you don't have its schema. Requires a reachable Kafka broker with the topic populated.
Inputs: topic (required), event_time (required), bootstrap, sample_size, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 3 tools
Each tool has a clearly distinct purpose: schema discovery, job generation with verification, and deployment to Kafka. There is no overlap that would confuse an agent.
All tool names follow a consistent verb_noun pattern in snake_case (generate_flink_job, ground_kafka_topic, deploy_to_kafka), making the set predictable and easy to navigate.
Three tools is a well-scoped count for a focused pipeline server, covering the essential stages without bloat or deficiency.
The tools form a complete workflow: discover a Kafka schema, generate and verify a Flink job, and deploy it to a Kafka sink. No obvious gaps or dead ends for the stated domain.
Related MCP Connectors
The grounded data layer for any LLM: governed SQL, metrics, lineage and catalog over your data.
33 tools that make AI write, implement, and verify intent against explicit, testable constraints.
Your Databricks Lakehouse in natural language: run SQL on your SQL warehouses, track long-running qu
Query, explore, and manage your databases through natural conversation.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage and monitor Apache Kafka clusters through natural language, providing real-time operations, health monitoring, consumer lag analysis, and temporal trend detection for intelligent cluster management.-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with Apache Kafka through natural language, supporting operations like producing/consuming messages, managing topics, and querying brokers, partitions, and consumer group offsets.1MIT
- AlicenseNot gradedqualityDmaintenanceTurns natural language into data pipeline actions using six specialist agents that collaborate through MCP to build, validate, and monitor data infrastructure.Apache 2.0
- FlicenseNot gradedqualityDmaintenanceEnables AI-powered MCP clients to interact with data lakehouse components including Kafka, Flink, and Trino/Iceberg for managing topics, jobs, catalogs, and executing queries.2-