fluxpy

fluxpy

An MCP server that enables real-time data streaming for AI agents, with persistent connections to live feeds, reactive operator pipelines, and consumption via push, pull, or block modes.

Category
访问服务器

README

<h1 align="center">fluxpy</h1>

<p align="center"> <strong>Reactive, real-time data streaming for AI agents — as a first-class citizen of MCP.</strong> </p>

<p align="center"> <a href="https://github.com/saudaljuaid/fluxpy/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/saudaljuaid/fluxpy/actions/workflows/ci.yml/badge.svg"></a> <a href="https://pypi.org/project/fluxpy/"><img alt="PyPI" src="https://img.shields.io/pypi/v/fluxpy.svg"></a> <a href="https://pypi.org/project/fluxpy/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/fluxpy.svg"></a> <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-green.svg"></a> <a href="https://modelcontextprotocol.io"><img alt="MCP" src="https://img.shields.io/badge/MCP-2026--07--28-blueviolet.svg"></a> <a href="docs/clients/README.md"><img alt="Clients" src="https://img.shields.io/badge/clients-24_AI_tools-orange.svg"></a> </p>

<p align="center"> <a href="docs/getting-started.md">Getting started</a> · <a href="docs/concepts.md">Concepts</a> · <a href="docs/tools.md">Tools</a> · <a href="docs/clients/README.md">Client setup</a> · <a href="docs/recipes.md">Recipes</a> · <a href="docs/faq.md">FAQ</a> </p>


The problem

Every MCP server today is a vending machine. The agent asks, the server answers, the connection closes, and nothing is remembered. That works fine for "read this file" and badly for anything that is still happening.

If you want an agent to follow a live match, watch a deploy, track a price, or react to a failing build, request/response makes you choose between two bad options: poll in a loop and burn tokens on 200 identical answers, or ask once and miss everything that happens next.

What fluxpy does

fluxpy holds persistent connections to live feeds, transforms them through a reactive operator pipeline, and keeps the results in a cursor-addressable buffer that survives between your turns. An agent can then consume a stream three different ways — and it needs all three, because no single one works everywhere:

How When to use it
Push subscriptions/listenResourceUpdated The client speaks MCP 2026-07-28. True server-initiated push, zero polling.
Pull flux_poll(cursor) Everywhere. Exactly-once and gap-aware — you learn what you missed.
Block flux_wait(where=...) React inside one turn. One tool call parks until the thing you care about happens.
flowchart LR
    A["SSE · WebSocket · HTTP poll<br/>files · processes · webhooks"] --> B[Source supervisor<br/><i>reconnect + backoff</i>]
    B --> C[Operator pipeline<br/><i>filter · window · throttle</i>]
    C --> D[(Ring buffer<br/>cursors)]
    D --> E[flux_poll / flux_wait]
    D --> F[Watches → alerts]
    D --> G[Sinks · recorder · SQLite]
    D --> H["subscriptions/listen<br/>push"]

It is not only a streaming server. It is a data plane: merge feeds into derived streams, compute rolling statistics, detect anomalies, set standing alerts, record a feed and replay it deterministically, and forward events onward to a file or a webhook. 28 tools in total.

And it is built for three quite different people:

Anyone 15 presets — ready-made streams behind a plain-language name. "Watch Hacker News", "tell me if my site goes down", "is my computer running hot". No spec to author, no API to learn. → fluxpy for everyone
Developers 13 source types, 19 operators, a sandboxed filter language, cursor semantics, and a CLI that reproduces the whole engine outside any client. → Concepts
Organisations Read-only mode, bearer auth, Prometheus metrics, JSONL audit logging, Kubernetes manifests. All off by default. → For organisations

Quickstart

Not on PyPI yet. Until the first release, install straight from this repository — the commands below already do. Once published, drop the --from git+... and plain uvx fluxpy serve works.

Check it runs at all:

uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy doctor
uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy tail scoreboard -o seconds=0.3 -n 5

That second command streams a simulated football match — no network, no credentials. If events scroll past, fluxpy works and anything that goes wrong next is client configuration.

Now pick your assistant:

<details open> <summary><b>Claude Code</b></summary>

claude mcp add fluxpy -- uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy serve

Then, in a session, ask: "Subscribe to the scoreboard source with seconds: 0.5, wait for a goal, and tell me who scored." </details>

<details> <summary><b>Claude Desktop</b></summary>

Add to claude_desktop_config.json (where is it?):

{
  "mcpServers": {
    "fluxpy": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/saudaljuaid/fluxpy", "fluxpy", "serve"]
    }
  }
}

Then fully quit and reopen Claude Desktop — closing the window is not enough. </details>

<details> <summary><b>Cursor</b></summary>

Add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "fluxpy": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/saudaljuaid/fluxpy", "fluxpy", "serve"]
    }
  }
}

</details>

<details> <summary><b>VS Code / Copilot</b></summary>

Add to .vscode/mcp.json — note the key is servers, not mcpServers:

{
  "servers": {
    "fluxpy": {
      "type": "stdio",
      "command": "uvx",
      "args": ["--from", "git+https://github.com/saudaljuaid/fluxpy", "fluxpy", "serve"]
    }
  }
}

</details>

<details> <summary><b>Codex CLI</b></summary>

codex mcp add fluxpy -- uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy serve

</details>

<details> <summary><b>ChatGPT</b> (remote, HTTP)</summary>

ChatGPT connects over HTTP only, so run fluxpy as a server and expose it:

uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy serve --transport http --port 8765

Then add the URL under Settings → Connectors → Advanced → Developer mode. See docs/clients/chatgpt.md — read the authentication section before exposing it publicly. </details>

Using something else? fluxpy ships configuration for 24 AI tools — Cline, Roo Code, Kilo Code, Continue, Gemini CLI, Amazon Q, Goose, opencode, Zed, Windsurf, Trae, JetBrains, Visual Studio, Warp, LibreChat, Cherry Studio, BoltAI, Witsy and more. See the client setup index, or let fluxpy do it:

# Add --from-git to any of these while fluxpy is unreleased.
uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy install
uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy install cline --from-git
uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy install cline --from-git --write

Verify it works — ask your agent:

Subscribe to the scoreboard source with seconds: 0.5, then wait for a goal and tell me who scored.

That needs no network and no credentials. If goals arrive, the whole path works.


Presets

Not everyone wants to write a source spec, and nobody wants to look up the USGS GeoJSON schema to find out whether an earthquake happened. A preset is a complete, working stream behind a name and a sentence — with the filtering that makes the feed usable already in place.

uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy presets
demo_match · my_computer Nothing required. No network, no credentials.
news · hacker_news · youtube_channel · reddit · web_page Feeds, and any page at all watched for changes.
github_releases · github_commits · ci_webhooks · app_log · website_up Software and work.
crypto_price · earthquakes · wikipedia Money and the world.

An agent reaches these through flux_list_presets and flux_use_preset, so a request phrased in ordinary words — "watch Hacker News for anything about AI" — becomes one tool call rather than a guess at a spec.

A preset builds an ordinary StreamSpec. Nothing about the resulting stream is special: inspect it, edit it, export it with flux_export_config, paste it into a config file. fluxpy presets <name> prints exactly that block, ready to paste.


What it looks like

An agent monitoring live earthquakes, doing all the filtering server-side:

// flux_subscribe
{
  "stream_id": "quakes",
  "source": {
    "type": "http_poll",
    "url": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson",
    "interval": 60,
    "select": "features"
  },
  "pipeline": [
    { "op": "flatten" },                                       // one event per quake
    { "op": "dedupe", "key": "id", "ttl": 3600 },              // the feed repeats itself
    { "op": "filter", "where": "properties.mag >= 4.5" },      // only significant ones
    { "op": "select", "fields": ["properties.place", "properties.mag", "properties.time"] }
  ]
}

That pipeline turns a 2 MB polled document into a handful of small events. The agent then either polls:

// flux_poll → { "events": [...], "cursor": 47, "missed": 0, "lag": 0 }

…or blocks until something big happens:

// flux_wait  { "stream_id": "quakes", "where": "properties.mag >= 6", "timeout": 300 }

…or sets a standing alert and gets on with something else:

// flux_watch { "stream_id": "quakes", "name": "Major quake",
//              "where": "properties.mag >= 6",
//              "message": "M{properties.mag} near {properties.place}" }

Sources

Type What it connects to
sse Server-Sent Events endpoints. Resumes with Last-Event-ID across reconnects.
websocket WebSocket feeds, with subscribe-on-connect frames re-sent on every reconnect.
http_poll Any REST endpoint, on an interval. emit: on_change turns state into events.
rss Any RSS or Atom feed — news, blogs, podcasts, YouTube, releases. Deduplicated.
web_page Any page at all, watched for changes. The fallback when there is no feed.
webhook Inbound HTTP. GitHub, Stripe, Sentry, CI — push to the agent.
file_tail A growing file, surviving truncation and log rotation.
process The stdout of a long-running command (kubectl logs -f, journalctl -f).
interval A clock-driven heartbeat or synthetic feed.
replay A recorded capture, replayed at any speed. Makes streaming testable.
derived Other fluxpy streams, merged. Composes to any depth.
scoreboard · random_walk · system_metrics Zero-setup demos. No network, no credentials.

Full options in docs/sources.md, or run fluxpy sources.

Operators

filter · reject · map · select · enrich · flatten · distinct · dedupe · throttle · debounce · sample · delay · take · skip · scan · window · buffer · rate_limit · tag

Operators run server-side, before events reach the agent, which is the single biggest lever on both noise and token cost. throttle vs debounce vs sample are three different answers to "too much data" and docs/operators.md explains exactly when each is right.


Try it without an agent

# alias flux='uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy'
uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy tail scoreboard -o seconds=0.3 --where "kind == 'goal'" -n 5
uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy tail system_metrics -o seconds=1 --select cpu_percent,mem_used_percent -n 5
uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy sources    # the full catalogue
uvx --from git+https://github.com/saudaljuaid/fluxpy fluxpy doctor     # diagnose a broken setup

fluxpy tail uses the same engine, sources, and operators as the MCP server, so it answers "is the feed broken, or is my client config broken?" in one command.


Configuration

fluxpy runs with zero configuration. A config file makes streams permanent:

streams:
  - id: wikipedia
    source:
      type: sse
      url: https://stream.wikimedia.org/v2/stream/recentchange
    pipeline:
      - op: filter
        where: wiki == 'enwiki' and namespace == 0 and bot == false
      - op: select
        fields: [title, user, comment]
      - op: throttle
        seconds: 1

watches:
  - id: cpu-hot
    stream_id: host
    name: CPU saturated
    where: cpu_percent > 90
    cooldown: 300

fluxpy init writes a commented starter. Streams an agent builds interactively can be exported with flux_export_config and pasted straight back in — the formats are identical by design.

Security

fluxpy connects wherever an agent tells it to, so it ships with a boundary:

  • Cloud metadata endpoints are blocked unconditionally (169.254.169.254 and friends). This is never a legitimate feed and always a credential-theft target.
  • Only stream-shaped schemeshttp, https, ws, wss.
  • Reading files and running processes are off by default. They turn a data client into something with authority over your machine.
  • Credentials never reach a transcript. URLs, headers, and error messages are redacted; secrets belong in ${ENV_VAR} references, not in tool calls.
  • Expressions are sandboxed — parsed to an AST and walked against an allowlist. There is no eval, no attribute access, and no import path.

Want none of that? One switch removes every restriction and every ceiling — any host, any path, any command, unlimited streams, buffers, and payloads:

fluxpy serve --unrestricted          # or FLUXPY_UNRESTRICTED=1, or security.unrestricted: true

Every limit is also individually configurable if you only need one raised. The expression sandbox stays on in every mode — that one is not a limit on you, it is what stops feed data from executing code.

Defaults suit a server on your own machine. Read docs/security.md before exposing one over HTTP.

Running it for a team

Four controls turn a laptop tool into shared infrastructure. All off by default, all independent:

access:
  read_only: true                              # withhold every state-changing tool
  tokens: ["sre:${FLUXPY_SRE_TOKEN}"]          # Authorization: Bearer <token>
  metrics: true                                # Prometheus at /metrics
  audit_log: /var/log/fluxpy/audit.jsonl       # one JSON line per request

The arrangement most teams land on: operations declare the streams in a version-controlled config file; agents connect read-only and read them. A new stream becomes a pull request rather than a tool call, and an agent's surface can no longer surprise you.

Withheld tools are not registered at all, so they never reach the model's context. Metrics include per-stream last_event_age_seconds — the one alert that catches a feed which went quiet, since a dead feed and a quiet feed look identical from the inside. The audit log records refused attempts too, and never records event payloads.

See docs/enterprise.md for the full picture, including Kubernetes manifests and a compliance summary.


Documentation

Full documentation index →

fluxpy for everyone No programming. What it can watch, in plain English.
Getting started Install, first stream, first watch.
FAQ Short answers, including "why is my filter matching nothing?"
Concepts Streams, events, cursors, backpressure, push vs pull.
Tool reference All 28 MCP tools with arguments and examples.
Sources Every source type, and how to write your own.
Operators Every operator, with the throttle/debounce/sample decision.
Expressions The filter language and its sandbox.
Recipes Complete worked setups for real problems.
Architecture How it works inside, and why.
Security Threat model and the hardened profile.
Deployment Docker, remote HTTP, tunnels, systemd.
For organisations Read-only, auth, metrics, audit, Kubernetes.
Client setup All 24 tools. Dedicated guides: Claude Code · Claude Desktop · Cursor · ChatGPT · Codex · VS Code · others

Contributing

Issues and pull requests are welcome — see CONTRIBUTING.md. Adding a source is deliberately easy: subclass Source, implement one run method, and the engine handles supervision, backpressure, pipelines, and fan-out for you.

git clone https://github.com/saudaljuaid/fluxpy && cd fluxpy
uv venv && uv pip install -e ".[dev]"
pytest && ruff check . && mypy src

License

MIT — see LICENSE.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选