Running a Postgres server and a CSV server side by side works fine until the question spans both, at which point the agent has to fetch each side and join by hand. Embedding DuckDB makes that a single SQL statement — and `--read-only` defaulting to on means the agent gets the reach without the ability to write anything back.
One server for several data sources, with DuckDB running inside the process. That is what makes cross-source joins possible: a CSV file, a PostgreSQL table and a REST endpoint can all appear in the same SELECT, and the query runs locally rather than going out to a query service.
- Sources: `connect_source` and `list_sources`
- Schema: `list_tables` and `get_schema`, with column names and types inferred from CSV headers and Postgres metadata
- Data: `query` runs SQL across everything connected; `transform` reshapes the result
- Health: `check_health` retests a source after startup
- Types are normalised across sources to one set — string, integer, number, datetime, boolean, json, unknown — so a join doesn't fall over on a type mismatch
- REST responses are cached with a time-to-live you control
Node.js v20.19 or newer, and npm; a running PostgreSQL instance only if you use the Postgres connector. Add it to your client as `npx -y mcp-data-pipeline-connector@latest`. Define sources in `~/.mcp/data-sources.yaml`, each with a name and type, and keep connection strings in environment variables referenced from the YAML rather than written into it. Flags: `--config` points at a different YAML, `--rest-cache-ttl` sets the REST cache in seconds (default 300, `0` disables), `--max-rows` caps a single `query` result (default 1000), and `--read-only` rejects anything that is not a SELECT — it is on by default.
One command — npx -y mcp-data-pipeline-connector@latest
