datamcp-ai 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- datamcp_ai-0.1.0/.claude/scheduled_tasks.lock +1 -0
- datamcp_ai-0.1.0/.claude/settings.local.json +41 -0
- datamcp_ai-0.1.0/.env.example +40 -0
- datamcp_ai-0.1.0/.github/workflows/ci.yml +44 -0
- datamcp_ai-0.1.0/.gitignore +55 -0
- datamcp_ai-0.1.0/.pre-commit-config.yaml +26 -0
- datamcp_ai-0.1.0/PKG-INFO +205 -0
- datamcp_ai-0.1.0/ProductVision.md +313 -0
- datamcp_ai-0.1.0/README.md +159 -0
- datamcp_ai-0.1.0/SYSTEM_PROMPT.md +578 -0
- datamcp_ai-0.1.0/TechnicalArchitecture_Stone1.md +1323 -0
- datamcp_ai-0.1.0/docker/local-postgres-init.sql +55 -0
- datamcp_ai-0.1.0/docker-compose.yml +22 -0
- datamcp_ai-0.1.0/docs/CONTRIBUTING.md +50 -0
- datamcp_ai-0.1.0/docs/DATA_PRIVACY.md +48 -0
- datamcp_ai-0.1.0/docs/FAILURES.md +73 -0
- datamcp_ai-0.1.0/docs/SECURITY.md +57 -0
- datamcp_ai-0.1.0/mcp.json +13 -0
- datamcp_ai-0.1.0/presentation.html +1020 -0
- datamcp_ai-0.1.0/pyproject.toml +90 -0
- datamcp_ai-0.1.0/run_chat.sh +20 -0
- datamcp_ai-0.1.0/run_pipeline.py +297 -0
- datamcp_ai-0.1.0/scripts/validate_e2e.sh +103 -0
- datamcp_ai-0.1.0/src/__init__.py +0 -0
- datamcp_ai-0.1.0/src/datamcp/__init__.py +3 -0
- datamcp_ai-0.1.0/src/datamcp/ai/__init__.py +1 -0
- datamcp_ai-0.1.0/src/datamcp/ai/anthropic_client.py +54 -0
- datamcp_ai-0.1.0/src/datamcp/ai/client.py +50 -0
- datamcp_ai-0.1.0/src/datamcp/ai/gemini_client.py +179 -0
- datamcp_ai-0.1.0/src/datamcp/ai/ollama_client.py +54 -0
- datamcp_ai-0.1.0/src/datamcp/ai/openai_client.py +158 -0
- datamcp_ai-0.1.0/src/datamcp/ai/prompts/__init__.py +1 -0
- datamcp_ai-0.1.0/src/datamcp/ai/prompts/domain_inference.py +41 -0
- datamcp_ai-0.1.0/src/datamcp/ai/prompts/error_translation.py +17 -0
- datamcp_ai-0.1.0/src/datamcp/ai/prompts/kpi_generation.py +41 -0
- datamcp_ai-0.1.0/src/datamcp/ai/prompts/model_description.py +18 -0
- datamcp_ai-0.1.0/src/datamcp/ai/prompts/text_to_sql.py +54 -0
- datamcp_ai-0.1.0/src/datamcp/ai/typesafe_client.py +249 -0
- datamcp_ai-0.1.0/src/datamcp/ai/validators.py +142 -0
- datamcp_ai-0.1.0/src/datamcp/chat/__init__.py +0 -0
- datamcp_ai-0.1.0/src/datamcp/chat/query_engine.py +299 -0
- datamcp_ai-0.1.0/src/datamcp/cli/__init__.py +1 -0
- datamcp_ai-0.1.0/src/datamcp/cli/app.py +25 -0
- datamcp_ai-0.1.0/src/datamcp/cli/commands/__init__.py +1 -0
- datamcp_ai-0.1.0/src/datamcp/cli/commands/configure.py +38 -0
- datamcp_ai-0.1.0/src/datamcp/cli/commands/init.py +77 -0
- datamcp_ai-0.1.0/src/datamcp/cli/commands/install.py +63 -0
- datamcp_ai-0.1.0/src/datamcp/cli/commands/status.py +39 -0
- datamcp_ai-0.1.0/src/datamcp/cli/display.py +38 -0
- datamcp_ai-0.1.0/src/datamcp/config/__init__.py +1 -0
- datamcp_ai-0.1.0/src/datamcp/config/settings.py +83 -0
- datamcp_ai-0.1.0/src/datamcp/connectors/__init__.py +0 -0
- datamcp_ai-0.1.0/src/datamcp/connectors/kafka/__init__.py +1 -0
- datamcp_ai-0.1.0/src/datamcp/connectors/kafka/admin_client.py +69 -0
- datamcp_ai-0.1.0/src/datamcp/connectors/kafka/consumer.py +68 -0
- datamcp_ai-0.1.0/src/datamcp/connectors/metabase/__init__.py +0 -0
- datamcp_ai-0.1.0/src/datamcp/connectors/metabase/client.py +420 -0
- datamcp_ai-0.1.0/src/datamcp/generators/__init__.py +1 -0
- datamcp_ai-0.1.0/src/datamcp/generators/dagster_generator.py +113 -0
- datamcp_ai-0.1.0/src/datamcp/generators/dagster_runtime.py +347 -0
- datamcp_ai-0.1.0/src/datamcp/generators/dbt_runner.py +230 -0
- datamcp_ai-0.1.0/src/datamcp/generators/dlt_generator.py +162 -0
- datamcp_ai-0.1.0/src/datamcp/generators/er_diagram_generator.py +89 -0
- datamcp_ai-0.1.0/src/datamcp/generators/kpi_generator.py +120 -0
- datamcp_ai-0.1.0/src/datamcp/generators/macro_generator.py +181 -0
- datamcp_ai-0.1.0/src/datamcp/generators/mart_generator.py +366 -0
- datamcp_ai-0.1.0/src/datamcp/generators/project_generator.py +99 -0
- datamcp_ai-0.1.0/src/datamcp/generators/schema_doc_generator.py +254 -0
- datamcp_ai-0.1.0/src/datamcp/generators/source_generator.py +41 -0
- datamcp_ai-0.1.0/src/datamcp/generators/staging_generator.py +93 -0
- datamcp_ai-0.1.0/src/datamcp/gui/__init__.py +0 -0
- datamcp_ai-0.1.0/src/datamcp/gui/app.py +372 -0
- datamcp_ai-0.1.0/src/datamcp/gui/pages/1_Pipeline_Demo.py +652 -0
- datamcp_ai-0.1.0/src/datamcp/introspection/__init__.py +1 -0
- datamcp_ai-0.1.0/src/datamcp/introspection/change_detector.py +87 -0
- datamcp_ai-0.1.0/src/datamcp/introspection/domain_inferrer.py +49 -0
- datamcp_ai-0.1.0/src/datamcp/introspection/freshness_checker.py +167 -0
- datamcp_ai-0.1.0/src/datamcp/introspection/relationship_mapper.py +102 -0
- datamcp_ai-0.1.0/src/datamcp/introspection/schema_reader.py +243 -0
- datamcp_ai-0.1.0/src/datamcp/introspection/type_mapper.py +108 -0
- datamcp_ai-0.1.0/src/datamcp/knowledge/__init__.py +1 -0
- datamcp_ai-0.1.0/src/datamcp/knowledge/embeddings.py +29 -0
- datamcp_ai-0.1.0/src/datamcp/knowledge/migrations.py +255 -0
- datamcp_ai-0.1.0/src/datamcp/knowledge/retriever.py +147 -0
- datamcp_ai-0.1.0/src/datamcp/knowledge/schema_graph.py +43 -0
- datamcp_ai-0.1.0/src/datamcp/knowledge/store.py +721 -0
- datamcp_ai-0.1.0/src/datamcp/models/__init__.py +1 -0
- datamcp_ai-0.1.0/src/datamcp/models/ai.py +55 -0
- datamcp_ai-0.1.0/src/datamcp/models/dagster.py +29 -0
- datamcp_ai-0.1.0/src/datamcp/models/dbt.py +60 -0
- datamcp_ai-0.1.0/src/datamcp/models/dlt.py +28 -0
- datamcp_ai-0.1.0/src/datamcp/models/kpi.py +23 -0
- datamcp_ai-0.1.0/src/datamcp/models/pipeline.py +56 -0
- datamcp_ai-0.1.0/src/datamcp/models/schema.py +110 -0
- datamcp_ai-0.1.0/src/datamcp/py.typed +0 -0
- datamcp_ai-0.1.0/src/datamcp/server/__init__.py +1 -0
- datamcp_ai-0.1.0/src/datamcp/server/auth.py +155 -0
- datamcp_ai-0.1.0/src/datamcp/server/mcp_server.py +1355 -0
- datamcp_ai-0.1.0/src/datamcp/server/tool_registry.py +26 -0
- datamcp_ai-0.1.0/src/datamcp/tools/__init__.py +1 -0
- datamcp_ai-0.1.0/src/datamcp/tools/check_consumer_lag.py +100 -0
- datamcp_ai-0.1.0/src/datamcp/tools/check_dlt_alignment.py +138 -0
- datamcp_ai-0.1.0/src/datamcp/tools/check_freshness.py +44 -0
- datamcp_ai-0.1.0/src/datamcp/tools/configure_postgres_sink.py +133 -0
- datamcp_ai-0.1.0/src/datamcp/tools/connect_database.py +88 -0
- datamcp_ai-0.1.0/src/datamcp/tools/connect_metabase.py +110 -0
- datamcp_ai-0.1.0/src/datamcp/tools/create_metabase_chart.py +118 -0
- datamcp_ai-0.1.0/src/datamcp/tools/create_metabase_dashboard.py +263 -0
- datamcp_ai-0.1.0/src/datamcp/tools/execute_sql.py +74 -0
- datamcp_ai-0.1.0/src/datamcp/tools/explain_model.py +136 -0
- datamcp_ai-0.1.0/src/datamcp/tools/generate_dbt_macros.py +33 -0
- datamcp_ai-0.1.0/src/datamcp/tools/generate_dbt_project.py +86 -0
- datamcp_ai-0.1.0/src/datamcp/tools/generate_er_diagram.py +26 -0
- datamcp_ai-0.1.0/src/datamcp/tools/generate_kpis.py +50 -0
- datamcp_ai-0.1.0/src/datamcp/tools/generate_marts.py +117 -0
- datamcp_ai-0.1.0/src/datamcp/tools/generate_staging.py +101 -0
- datamcp_ai-0.1.0/src/datamcp/tools/get_pipeline_status.py +166 -0
- datamcp_ai-0.1.0/src/datamcp/tools/infer_domain.py +28 -0
- datamcp_ai-0.1.0/src/datamcp/tools/infer_model_candidates.py +173 -0
- datamcp_ai-0.1.0/src/datamcp/tools/introspect_schema.py +87 -0
- datamcp_ai-0.1.0/src/datamcp/tools/provision_kafka_topic.py +62 -0
- datamcp_ai-0.1.0/src/datamcp/tools/query_data.py +71 -0
- datamcp_ai-0.1.0/src/datamcp/tools/query_knowledge_base.py +49 -0
- datamcp_ai-0.1.0/src/datamcp/tools/run_dagster.py +154 -0
- datamcp_ai-0.1.0/src/datamcp/tools/run_dbt.py +93 -0
- datamcp_ai-0.1.0/src/datamcp/tools/run_dlt.py +175 -0
- datamcp_ai-0.1.0/src/datamcp/tools/scaffold_dagster.py +64 -0
- datamcp_ai-0.1.0/src/datamcp/tools/scaffold_dlt.py +76 -0
- datamcp_ai-0.1.0/src/datamcp/tools/sync_metabase.py +86 -0
- datamcp_ai-0.1.0/templates/dagster/assets.py.j2 +19 -0
- datamcp_ai-0.1.0/templates/dagster/definitions.py.j2 +19 -0
- datamcp_ai-0.1.0/templates/dagster/freshness_sensor.py.j2 +135 -0
- datamcp_ai-0.1.0/templates/dagster/schedules.py.j2 +14 -0
- datamcp_ai-0.1.0/templates/dbt/dbt_project.yml.j2 +28 -0
- datamcp_ai-0.1.0/templates/dbt/intermediate_model.sql.j2 +27 -0
- datamcp_ai-0.1.0/templates/dbt/mart_dim_model.sql.j2 +20 -0
- datamcp_ai-0.1.0/templates/dbt/mart_fact_model.sql.j2 +46 -0
- datamcp_ai-0.1.0/templates/dbt/profiles_combined.yml.j2 +18 -0
- datamcp_ai-0.1.0/templates/dbt/profiles_duckdb.yml.j2 +8 -0
- datamcp_ai-0.1.0/templates/dbt/profiles_postgres.yml.j2 +13 -0
- datamcp_ai-0.1.0/templates/dbt/schema_doc.yml.j2 +55 -0
- datamcp_ai-0.1.0/templates/dbt/snap_model.sql.j2 +12 -0
- datamcp_ai-0.1.0/templates/dbt/sources.yml.j2 +44 -0
- datamcp_ai-0.1.0/templates/dbt/staging_model.sql.j2 +18 -0
- datamcp_ai-0.1.0/templates/dbt/staging_model_streaming.sql.j2 +29 -0
- datamcp_ai-0.1.0/templates/dlt/pipeline.py.j2 +24 -0
- datamcp_ai-0.1.0/templates/dlt/source.py.j2 +44 -0
- datamcp_ai-0.1.0/test_streamlit.py +3 -0
- datamcp_ai-0.1.0/tests/__init__.py +0 -0
- datamcp_ai-0.1.0/tests/conftest.py +216 -0
- datamcp_ai-0.1.0/tests/integration/__init__.py +0 -0
- datamcp_ai-0.1.0/tests/integration/test_full_pipeline.py +674 -0
- datamcp_ai-0.1.0/tests/integration/test_mcp_server_smoke.py +58 -0
- datamcp_ai-0.1.0/tests/test_ai/__init__.py +0 -0
- datamcp_ai-0.1.0/tests/test_ai/test_client.py +38 -0
- datamcp_ai-0.1.0/tests/test_ai/test_gemini_client.py +127 -0
- datamcp_ai-0.1.0/tests/test_ai/test_openai_client.py +76 -0
- datamcp_ai-0.1.0/tests/test_ai/test_prompts.py +101 -0
- datamcp_ai-0.1.0/tests/test_ai/test_typesafe_client.py +139 -0
- datamcp_ai-0.1.0/tests/test_ai/test_validators.py +141 -0
- datamcp_ai-0.1.0/tests/test_config/__init__.py +0 -0
- datamcp_ai-0.1.0/tests/test_config/test_settings.py +34 -0
- datamcp_ai-0.1.0/tests/test_generators/__init__.py +0 -0
- datamcp_ai-0.1.0/tests/test_generators/test_dagster_generator.py +65 -0
- datamcp_ai-0.1.0/tests/test_generators/test_dagster_runtime.py +352 -0
- datamcp_ai-0.1.0/tests/test_generators/test_dbt_runner.py +93 -0
- datamcp_ai-0.1.0/tests/test_generators/test_dlt_generator.py +186 -0
- datamcp_ai-0.1.0/tests/test_generators/test_kpi_generator.py +92 -0
- datamcp_ai-0.1.0/tests/test_generators/test_mart_generator.py +393 -0
- datamcp_ai-0.1.0/tests/test_generators/test_project_generator.py +89 -0
- datamcp_ai-0.1.0/tests/test_generators/test_schema_doc_generator.py +306 -0
- datamcp_ai-0.1.0/tests/test_generators/test_staging_generator.py +50 -0
- datamcp_ai-0.1.0/tests/test_introspection/__init__.py +0 -0
- datamcp_ai-0.1.0/tests/test_introspection/test_change_detector.py +99 -0
- datamcp_ai-0.1.0/tests/test_introspection/test_domain_inferrer.py +57 -0
- datamcp_ai-0.1.0/tests/test_introspection/test_relationship_mapper.py +196 -0
- datamcp_ai-0.1.0/tests/test_introspection/test_schema_reader.py +85 -0
- datamcp_ai-0.1.0/tests/test_introspection/test_type_mapper.py +89 -0
- datamcp_ai-0.1.0/tests/test_knowledge/__init__.py +0 -0
- datamcp_ai-0.1.0/tests/test_knowledge/test_retriever.py +249 -0
- datamcp_ai-0.1.0/tests/test_knowledge/test_schema_graph.py +73 -0
- datamcp_ai-0.1.0/tests/test_knowledge/test_store.py +398 -0
- datamcp_ai-0.1.0/tests/test_mcp_server.py +874 -0
- datamcp_ai-0.1.0/tests/test_tools/__init__.py +0 -0
- datamcp_ai-0.1.0/tests/test_tools/test_check_freshness.py +93 -0
- datamcp_ai-0.1.0/tests/test_tools/test_connect_database.py +84 -0
- datamcp_ai-0.1.0/tests/test_tools/test_create_metabase_chart.py +190 -0
- datamcp_ai-0.1.0/tests/test_tools/test_create_metabase_dashboard.py +258 -0
- datamcp_ai-0.1.0/tests/test_tools/test_explain_model.py +71 -0
- datamcp_ai-0.1.0/tests/test_tools/test_generate_dbt_macros.py +65 -0
- datamcp_ai-0.1.0/tests/test_tools/test_generate_dbt_project.py +91 -0
- datamcp_ai-0.1.0/tests/test_tools/test_generate_er_diagram.py +55 -0
- datamcp_ai-0.1.0/tests/test_tools/test_generate_staging.py +100 -0
- datamcp_ai-0.1.0/tests/test_tools/test_get_pipeline_status.py +94 -0
- datamcp_ai-0.1.0/tests/test_tools/test_infer_model_candidates.py +150 -0
- datamcp_ai-0.1.0/tests/test_tools/test_kafka_tools.py +340 -0
- datamcp_ai-0.1.0/tests/test_tools/test_metabase.py +491 -0
- datamcp_ai-0.1.0/tests/test_tools/test_query_data.py +90 -0
- datamcp_ai-0.1.0/tests/test_tools/test_run_dagster.py +131 -0
- datamcp_ai-0.1.0/tests/test_tools/test_run_dbt.py +70 -0
- datamcp_ai-0.1.0/tests/test_tools/test_run_dlt.py +178 -0
- datamcp_ai-0.1.0/tests/test_tools/test_scaffold_dlt.py +65 -0
- datamcp_ai-0.1.0/uv.lock +4869 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"sessionId":"c2f0e0a2-3135-4fbc-9e9b-a88b9dde2cce","pid":75083,"procStart":"Sat Oct 3 11:24:24 2026","acquiredAt":1791047745871}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(read d *)",
|
|
5
|
+
"Bash(touch __TRACKED_VAR__/__init__.py)",
|
|
6
|
+
"Bash(python3 *)",
|
|
7
|
+
"Bash(uv --version)",
|
|
8
|
+
"Bash(rtk uv *)",
|
|
9
|
+
"Bash(uv run *)",
|
|
10
|
+
"Bash(rtk read *)",
|
|
11
|
+
"Bash(timeout 5 .venv/bin/python -m datamcp.server.mcp_server)",
|
|
12
|
+
"Bash(kill %1)",
|
|
13
|
+
"Bash(.venv/bin/python *)",
|
|
14
|
+
"Bash(brew list *)",
|
|
15
|
+
"Bash(brew services *)",
|
|
16
|
+
"Bash(rtk ls *)",
|
|
17
|
+
"Bash(xargs ls -la)",
|
|
18
|
+
"Bash(/Users/dev/Developer/DataMCP/.venv/bin/dbt compile *)",
|
|
19
|
+
"Bash(/Users/dev/Developer/DataMCP/.venv/bin/python --version)",
|
|
20
|
+
"Bash(claude mcp *)",
|
|
21
|
+
"mcp__plugin_supabase_supabase__list_projects",
|
|
22
|
+
"Bash(env)",
|
|
23
|
+
"mcp__datamcp__connect_database",
|
|
24
|
+
"Bash(rtk pytest *)",
|
|
25
|
+
"Bash(python -c \"import datamcp; print\\('import ok'\\)\")",
|
|
26
|
+
"Bash(rtk grep *)",
|
|
27
|
+
"Bash(rtk ps *)",
|
|
28
|
+
"Bash(rtk pip *)",
|
|
29
|
+
"Bash(rtk git *)",
|
|
30
|
+
"Bash(rtk find *)",
|
|
31
|
+
"Bash(/usr/bin/find /Users/dev/Developer/DataMCP/src -name \"*.pyc\" -delete)",
|
|
32
|
+
"Bash(rtk wc *)",
|
|
33
|
+
"mcp__datamcp__generate_mart_models",
|
|
34
|
+
"mcp__datamcp__scaffold_dlt"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
"enableAllProjectMcpServers": true,
|
|
38
|
+
"enabledMcpjsonServers": [
|
|
39
|
+
"datamcp"
|
|
40
|
+
]
|
|
41
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# ── Required ────────────────────────────────────────────────
|
|
2
|
+
# Postgres connection (stored in keychain after datamcp configure)
|
|
3
|
+
# Also used by run_pipeline.py and scripts/validate_e2e.sh
|
|
4
|
+
DATAMCP_DB_HOST=localhost
|
|
5
|
+
DATAMCP_DB_PORT=5432
|
|
6
|
+
DATAMCP_DB_NAME=postgres
|
|
7
|
+
DATAMCP_DB_USER=myuser
|
|
8
|
+
DATAMCP_DB_PASSWORD=
|
|
9
|
+
DATAMCP_DB_SCHEMA=public
|
|
10
|
+
DATAMCP_DB_SSL_MODE=prefer # use "require" for Supabase / managed Postgres
|
|
11
|
+
DATAMCP_PROJECT_NAME=datamcp
|
|
12
|
+
|
|
13
|
+
# AI inference — user brings their own key (never stored by DataMCP)
|
|
14
|
+
GEMINI_API_KEY=...
|
|
15
|
+
|
|
16
|
+
# Only needed if DATAMCP_AI_PROVIDER=openai
|
|
17
|
+
OPENAI_API_KEY=sk-...
|
|
18
|
+
|
|
19
|
+
# ── Optional ─────────────────────────────────────────────────
|
|
20
|
+
# Override AI model (default: gemini-2.5-flash; use a gpt-* model if
|
|
21
|
+
# DATAMCP_AI_PROVIDER=openai)
|
|
22
|
+
DATAMCP_AI_MODEL=gemini-2.5-flash
|
|
23
|
+
|
|
24
|
+
# Override AI provider (default: gemini)
|
|
25
|
+
DATAMCP_AI_PROVIDER=gemini # gemini | openai | anthropic | ollama
|
|
26
|
+
|
|
27
|
+
# Output paths
|
|
28
|
+
DATAMCP_PROJECT_DIR=./datamcp_output
|
|
29
|
+
DATAMCP_DUCKDB_PATH=./dev.duckdb
|
|
30
|
+
|
|
31
|
+
# dbt settings
|
|
32
|
+
DATAMCP_DBT_THREADS=4
|
|
33
|
+
DATAMCP_DBT_DEFAULT_TARGET=duckdb # Default to local DuckDB
|
|
34
|
+
|
|
35
|
+
# Freshness thresholds
|
|
36
|
+
DATAMCP_FRESHNESS_WARN_HOURS=24
|
|
37
|
+
DATAMCP_FRESHNESS_ERROR_HOURS=48
|
|
38
|
+
|
|
39
|
+
# Logging
|
|
40
|
+
DATAMCP_LOG_LEVEL=INFO
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
quality:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: astral-sh/setup-uv@v2
|
|
15
|
+
- run: uv sync --all-extras
|
|
16
|
+
|
|
17
|
+
- name: Lint
|
|
18
|
+
run: uv run ruff check src/ tests/
|
|
19
|
+
|
|
20
|
+
- name: Format
|
|
21
|
+
run: uv run ruff format --check src/ tests/
|
|
22
|
+
|
|
23
|
+
- name: Type check
|
|
24
|
+
run: uv run mypy src/datamcp --strict
|
|
25
|
+
|
|
26
|
+
- name: Tests
|
|
27
|
+
run: uv run pytest --cov=datamcp --cov-fail-under=90
|
|
28
|
+
env:
|
|
29
|
+
DATAMCP_TEST_DB_URL: postgresql://postgres:postgres@localhost:5432/datamcp_test
|
|
30
|
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY_TEST }}
|
|
31
|
+
|
|
32
|
+
services:
|
|
33
|
+
postgres:
|
|
34
|
+
image: postgres:16
|
|
35
|
+
env:
|
|
36
|
+
POSTGRES_PASSWORD: postgres
|
|
37
|
+
POSTGRES_DB: datamcp_test
|
|
38
|
+
options: >-
|
|
39
|
+
--health-cmd pg_isready
|
|
40
|
+
--health-interval 10s
|
|
41
|
+
--health-timeout 5s
|
|
42
|
+
--health-retries 5
|
|
43
|
+
ports:
|
|
44
|
+
- 5432:5432
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Environment and credentials — NEVER commit these
|
|
2
|
+
.env
|
|
3
|
+
.mcp.json
|
|
4
|
+
.dlt/secrets.toml
|
|
5
|
+
*.duckdb
|
|
6
|
+
dev.duckdb
|
|
7
|
+
|
|
8
|
+
# Python
|
|
9
|
+
__pycache__/
|
|
10
|
+
*.py[cod]
|
|
11
|
+
*$py.class
|
|
12
|
+
*.so
|
|
13
|
+
.Python
|
|
14
|
+
build/
|
|
15
|
+
dist/
|
|
16
|
+
*.egg-info/
|
|
17
|
+
.eggs/
|
|
18
|
+
*.egg
|
|
19
|
+
|
|
20
|
+
# Virtual environments
|
|
21
|
+
.venv/
|
|
22
|
+
venv/
|
|
23
|
+
env/
|
|
24
|
+
|
|
25
|
+
# uv
|
|
26
|
+
.uv/
|
|
27
|
+
|
|
28
|
+
# dbt
|
|
29
|
+
target/
|
|
30
|
+
dbt_packages/
|
|
31
|
+
logs/
|
|
32
|
+
|
|
33
|
+
# DataMCP knowledge base
|
|
34
|
+
datamcp_output/.datamcp_knowledge.db
|
|
35
|
+
*.db
|
|
36
|
+
|
|
37
|
+
# Generated project output (regeneratable, not source)
|
|
38
|
+
datamcp_output/
|
|
39
|
+
|
|
40
|
+
# IDE
|
|
41
|
+
.vscode/
|
|
42
|
+
.idea/
|
|
43
|
+
*.swp
|
|
44
|
+
*.swo
|
|
45
|
+
|
|
46
|
+
# macOS
|
|
47
|
+
.DS_Store
|
|
48
|
+
|
|
49
|
+
# Testing
|
|
50
|
+
.coverage
|
|
51
|
+
htmlcov/
|
|
52
|
+
.pytest_cache/
|
|
53
|
+
|
|
54
|
+
# mypy
|
|
55
|
+
.mypy_cache/
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.5.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
|
|
9
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
10
|
+
rev: v1.10.0
|
|
11
|
+
hooks:
|
|
12
|
+
- id: mypy
|
|
13
|
+
args: [--strict]
|
|
14
|
+
additional_dependencies:
|
|
15
|
+
- pydantic>=2.0.0
|
|
16
|
+
- pydantic-settings>=2.0.0
|
|
17
|
+
- types-Jinja2
|
|
18
|
+
|
|
19
|
+
- repo: local
|
|
20
|
+
hooks:
|
|
21
|
+
- id: pytest
|
|
22
|
+
name: pytest
|
|
23
|
+
entry: uv run pytest --no-cov -x -q
|
|
24
|
+
language: system
|
|
25
|
+
pass_filenames: false
|
|
26
|
+
always_run: true
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: datamcp-ai
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI Data Engineer MCP — Postgres + dlt + dbt + Dagster
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Keywords: dagster,data-engineering,dbt,dlt,mcp,postgres
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Requires-Dist: aiosqlite>=0.22.1
|
|
9
|
+
Requires-Dist: asyncpg>=0.31.0
|
|
10
|
+
Requires-Dist: dagster-dbt>=0.29.25
|
|
11
|
+
Requires-Dist: dagster-webserver>=1.13.25
|
|
12
|
+
Requires-Dist: dagster>=1.13.25
|
|
13
|
+
Requires-Dist: dbt-core>=1.12.5
|
|
14
|
+
Requires-Dist: dbt-duckdb>=1.11.0
|
|
15
|
+
Requires-Dist: dbt-postgres>=1.11.0
|
|
16
|
+
Requires-Dist: dlt>=1.30.0
|
|
17
|
+
Requires-Dist: duckdb>=1.5.6
|
|
18
|
+
Requires-Dist: google-genai>=2.27.0
|
|
19
|
+
Requires-Dist: httpx>=0.28.1
|
|
20
|
+
Requires-Dist: jinja2>=3.1.0
|
|
21
|
+
Requires-Dist: keyring>=25.7.0
|
|
22
|
+
Requires-Dist: mcp>=2.2.0
|
|
23
|
+
Requires-Dist: openai>=3.23.0
|
|
24
|
+
Requires-Dist: pandas>=3.0.6
|
|
25
|
+
Requires-Dist: plotly>=7.1.0
|
|
26
|
+
Requires-Dist: psycopg2-binary>=2.9.13
|
|
27
|
+
Requires-Dist: pydantic-settings>=2.15.0
|
|
28
|
+
Requires-Dist: pydantic>=2.13.5
|
|
29
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
30
|
+
Requires-Dist: rich>=13.0.0
|
|
31
|
+
Requires-Dist: sqlite-vec>=0.1.9
|
|
32
|
+
Requires-Dist: streamlit>=1.64.0
|
|
33
|
+
Requires-Dist: typer>=0.27.2
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: mypy>=2.4; extra == 'dev'
|
|
36
|
+
Requires-Dist: pre-commit>=4.6.2; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-asyncio>=1.4.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-cov>=7.1.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=9.1.1; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.16; extra == 'dev'
|
|
41
|
+
Provides-Extra: kafka
|
|
42
|
+
Requires-Dist: kafka-python>=2.0.0; extra == 'kafka'
|
|
43
|
+
Provides-Extra: typesafe
|
|
44
|
+
Requires-Dist: typesafe-sdk>=0.7.2; extra == 'typesafe'
|
|
45
|
+
Description-Content-Type: text/markdown
|
|
46
|
+
|
|
47
|
+
# DataMCP — AI Data Engineer
|
|
48
|
+
|
|
49
|
+
> Connect your Postgres database. Get a production dbt project in under 10 minutes.
|
|
50
|
+
|
|
51
|
+
DataMCP is an MCP server that acts as an AI data engineer inside Claude Code, Cursor, and Codex. It connects to your Postgres database, reads and maps the schema, infers the business domain, and generates a complete, production-quality dbt project — automatically.
|
|
52
|
+
|
|
53
|
+
## Quickstart
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Not yet on PyPI — install from source until the first release ships:
|
|
57
|
+
git clone https://github.com/<org>/datamcp.git && cd datamcp
|
|
58
|
+
pip install .
|
|
59
|
+
|
|
60
|
+
datamcp init
|
|
61
|
+
datamcp configure # stores credentials in OS keychain, never on disk
|
|
62
|
+
|
|
63
|
+
# Open Claude Code and type:
|
|
64
|
+
# "Set up analytics for my project"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
That's it. DataMCP calls the 10 core pipeline tools in sequence (of 30 MCP tools total — see below) and produces:
|
|
68
|
+
- Staging models (one per source table, DuckDB-validated)
|
|
69
|
+
- Fact and dimension mart models
|
|
70
|
+
- 5–11 domain-specific KPI definitions
|
|
71
|
+
- A dlt ingestion pipeline
|
|
72
|
+
- A Dagster project with a daily schedule
|
|
73
|
+
- 30+ data quality tests — all passing
|
|
74
|
+
|
|
75
|
+
**Total time: under 10 minutes.**
|
|
76
|
+
|
|
77
|
+
## Installation
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# PyPI release is pending — install from source for now:
|
|
81
|
+
git clone https://github.com/<org>/datamcp.git && cd datamcp
|
|
82
|
+
pip install .
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Requires Python 3.11+. Bring your own Gemini API key (OpenAI optional).
|
|
86
|
+
|
|
87
|
+
## Configuration
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
datamcp configure
|
|
91
|
+
# Prompts for: DB host, port, database, username, password, Gemini key
|
|
92
|
+
# (OpenAI key optional — only needed if DATAMCP_AI_PROVIDER=openai)
|
|
93
|
+
# All credentials stored in OS keychain — never on disk
|
|
94
|
+
|
|
95
|
+
datamcp install --editor claude-code # or cursor, codex
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## MCP Tools (30)
|
|
99
|
+
|
|
100
|
+
**Core pipeline** (steps 1–10 of the standard flow)
|
|
101
|
+
|
|
102
|
+
| Tool | Description |
|
|
103
|
+
|---|---|
|
|
104
|
+
| `connect_database` | Establish and validate a Postgres connection |
|
|
105
|
+
| `introspect_schema` | Read the complete Postgres schema: tables, columns, data types, PKs, FKs |
|
|
106
|
+
| `infer_domain` | Classify the business domain from schema metadata only |
|
|
107
|
+
| `generate_dbt_project` | Scaffold a complete dbt project with Postgres and DuckDB profiles |
|
|
108
|
+
| `generate_staging_models` | Generate one staging model (stg_*.sql) per source table |
|
|
109
|
+
| `generate_mart_models` | Generate fact and dimension mart models from the relationship graph |
|
|
110
|
+
| `generate_kpis` | Generate domain-specific KPI definitions as dbt metrics |
|
|
111
|
+
| `run_dbt` | Execute a dbt command (run, test, compile, build) |
|
|
112
|
+
| `check_freshness` | Check when each source table last received new rows |
|
|
113
|
+
| `get_pipeline_status` | Get an aggregated health dashboard across all pipeline components |
|
|
114
|
+
|
|
115
|
+
**Explore & query**
|
|
116
|
+
|
|
117
|
+
| Tool | Description |
|
|
118
|
+
|---|---|
|
|
119
|
+
| `query_knowledge_base` | Semantic search over the project knowledge base |
|
|
120
|
+
| `explain_model` | Get a plain-English explanation of any dbt model |
|
|
121
|
+
| `query_data` | Ask a natural language question about the data |
|
|
122
|
+
| `execute_sql` | Execute a raw SELECT query against the connected database |
|
|
123
|
+
|
|
124
|
+
**Schema analysis & scaffolding**
|
|
125
|
+
|
|
126
|
+
| Tool | Description |
|
|
127
|
+
|---|---|
|
|
128
|
+
| `get_project_id` | Look up the internal project UUID for a project_name, creating it on first use |
|
|
129
|
+
| `generate_er_diagram` | Generate a Mermaid erDiagram from the current schema snapshot |
|
|
130
|
+
| `infer_model_candidates` | Classify tables as fact, dimension, bridge, lookup, or scd_snapshot candidates |
|
|
131
|
+
| `generate_dbt_macros` | Generate dbt macros derived from schema column patterns |
|
|
132
|
+
| `scaffold_dagster` | Generate a complete Dagster project with dbt asset definitions and a daily schedule |
|
|
133
|
+
| `check_dlt_alignment` | Compare the dlt source schema against dbt staging models for drift |
|
|
134
|
+
| `configure_postgres_sink` | Generate a Kafka Connect connector config for Postgres |
|
|
135
|
+
| `scaffold_dlt` | Generate a complete dlt ingestion pipeline for the connected Postgres database |
|
|
136
|
+
| `run_dlt` | Execute a generated dlt pipeline.py and persist the run result |
|
|
137
|
+
|
|
138
|
+
**Orchestration, BI & streaming**
|
|
139
|
+
|
|
140
|
+
| Tool | Description |
|
|
141
|
+
|---|---|
|
|
142
|
+
| `run_dagster` | Start, stop, check status of, or trigger a run on a generated Dagster dev server |
|
|
143
|
+
| `connect_metabase` | Authenticate to Metabase, register the connected database, and trigger an initial sync |
|
|
144
|
+
| `sync_metabase` | Re-sync Metabase's metadata and flag charts referencing changed dbt models |
|
|
145
|
+
| `create_metabase_dashboard` | Create one Metabase question per project KPI and group them into a dashboard |
|
|
146
|
+
| `create_metabase_chart` | Turn a natural-language question into a real Metabase chart |
|
|
147
|
+
| `provision_kafka_topic` | Create a Kafka topic for streaming ingestion |
|
|
148
|
+
| `check_consumer_lag` | Check Kafka consumer group lag per partition |
|
|
149
|
+
|
|
150
|
+
## Security
|
|
151
|
+
|
|
152
|
+
- Database credentials: OS keychain only (Mac Keychain / Linux Secret Service / Windows Credential Manager)
|
|
153
|
+
- AI inference: schema metadata only — table names, column names, types, FK relationships. Never actual data values, credentials, or PII.
|
|
154
|
+
- Knowledge base: schema metadata and model definitions only. No row data.
|
|
155
|
+
|
|
156
|
+
See [SECURITY.md](docs/SECURITY.md) and [DATA_PRIVACY.md](docs/DATA_PRIVACY.md).
|
|
157
|
+
|
|
158
|
+
## What gets generated
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
datamcp_output/
|
|
162
|
+
├── dbt/
|
|
163
|
+
│ └── my_project/
|
|
164
|
+
│ ├── dbt_project.yml
|
|
165
|
+
│ ├── profiles.yml # Postgres target
|
|
166
|
+
│ ├── profiles_duckdb.yml # DuckDB local dev target
|
|
167
|
+
│ └── models/
|
|
168
|
+
│ ├── staging/
|
|
169
|
+
│ │ ├── sources.yml
|
|
170
|
+
│ │ ├── stg_users.sql
|
|
171
|
+
│ │ ├── stg_orders.sql
|
|
172
|
+
│ │ └── ...
|
|
173
|
+
│ └── marts/
|
|
174
|
+
│ ├── fct_orders.sql
|
|
175
|
+
│ ├── dim_customers.sql
|
|
176
|
+
│ └── _metrics.yml
|
|
177
|
+
├── dlt/
|
|
178
|
+
│ ├── pipeline.py
|
|
179
|
+
│ └── sources/my_project.py
|
|
180
|
+
└── dagster_datamcp/
|
|
181
|
+
├── assets/dbt_assets.py
|
|
182
|
+
├── schedules/daily_schedule.py
|
|
183
|
+
└── definitions.py
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Running locally
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
# Run dbt against DuckDB (no Postgres needed)
|
|
190
|
+
cd datamcp_output/dbt/my_project
|
|
191
|
+
dbt run --target duckdb
|
|
192
|
+
dbt test --target duckdb
|
|
193
|
+
|
|
194
|
+
# Or run the full Dagster pipeline
|
|
195
|
+
cd datamcp_output/dagster_datamcp
|
|
196
|
+
dagster dev
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Contributing
|
|
200
|
+
|
|
201
|
+
See [CONTRIBUTING.md](docs/CONTRIBUTING.md).
|
|
202
|
+
|
|
203
|
+
## License
|
|
204
|
+
|
|
205
|
+
Apache 2.0
|