Source profileQuality 93/100Review permissions

monte-carlo-data/mc-agent-toolkit/skills/push-ingestion/SKILL.md

push-ingestion

Expert guide for Monte Carlo's push ingestion model. Use this skill whenever a customer or engineer mentions: pushing data to Monte Carlo, the IngestionService, pycarlo push APIs, build me a collection script, push metadata/lineage/query logs, invocation_id tracing, custom lineage nodes or edges, deleting push tables, or any question about why pushed data is not showing up. Also trigger when they ask to generate code that collects metadata, table schema, row counts, freshness, lineage, or query

Source repository stars
91
Declared platforms
0
Static risk flags
2
Last source update
2026-08-24
Source checked
2026-08-28

Decision brief

What it does: where it fits

You are an agent that helps customers collect metadata, lineage, and query logs from their data warehouses and push that data to Monte Carlo via the push ingestion API. The push model works with any data source — if the customer's warehouse does not have a ready-made template, d…

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/monte-carlo-data/mc-agent-toolkit --skill "skills/push-ingestion"
    Safe inspection promptEditorial

    Inspect the Agent Skill "push-ingestion" from https://github.com/monte-carlo-data/mc-agent-toolkit/blob/b7e848b845a29799bedb792d0830cb9e76afa0cb/skills/push-ingestion/SKILL.md at commit b7e848b845a29799bedb792d0830cb9e76afa0cb. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      Imports and client setup

      Review the “Imports and client setup” section in the pinned source before continuing.

      Review and apply the “Imports and client setup” source section.
    2. 02

      Step 1 — Generate your collection scripts

      Ask Claude to build the script for your warehouse:

      Metadata (schema + volume + freshness): references/push-metadata.mdTable and column lineage: references/push-lineage.mdQuery logs: references/push-query-logs.md
    3. 03

      Step 2 — Validate pushed data

      After pushing, verify data is visible in Monte Carlo using the GraphQL API (GraphQL API key).

      Metadata: visible within a few minutesTable lineage: visible within seconds to a few minutes (fast direct path to Neo4j)Column lineage: a few minutes
    4. 04

      Step 3 — Anomaly detection (optional)

      If you want Monte Carlo's freshness and volume detectors to fire on pushed data, you need to push consistently over time — detectors require historical data to train.

      If you want Monte Carlo's freshness and volume detectors to fire on pushed data, you need to push consistently over time — detectors require historical data to train.→ references/anomaly-detection.md — recommended push frequency, minimum samples, training windows, and what to tell customers who ask why detectors aren't activating
    5. 05

      MANDATORY — Always start from templates

      When generating any push-ingestion script, you MUST:

      Read the corresponding template before writing any code. Templates live in this skill'sAdapt the template to the customer's needs — do not write pycarlo imports, model constructors,If no template exists for the target warehouse, read the Snowflake template as the canonical

    Permission review

    Static risk signals and limitations

    Runs scripts

    medium · line 119

    The documentation asks the agent to run terminal commands or scripts.

    generate a ready-to-run Python script that:

    Network access

    medium · line 260

    The documentation includes network, browsing, or remote request actions.

    | `/mc-validate-query-logs` | Verify pushed query logs via the GraphQL API |

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score93/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars91SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    monte-carlo-data/mc-agent-toolkit
    Skill path
    skills/push-ingestion/SKILL.md
    Commit
    b7e848b845a29799bedb792d0830cb9e76afa0cb
    License
    Apache-2.0
    Collected
    2026-08-28
    Default branch
    main
    View the original SKILL.md

    Monte Carlo Push Ingestion

    You are an agent that helps customers collect metadata, lineage, and query logs from their data warehouses and push that data to Monte Carlo via the push ingestion API. The push model works with any data source — if the customer's warehouse does not have a ready-made template, derive the appropriate collection queries from that warehouse's system catalog or metadata APIs. The push format and pycarlo SDK calls are the same regardless of source.

    Monte Carlo's push model lets customers send metadata, lineage, and query logs directly to Monte Carlo instead of waiting for the pull collector to gather it. It fills gaps the pull model cannot always cover — integrations that don't expose query history, custom lineage between non-warehouse assets, or customers who already have this data and want to send it directly.

    Push data travels through the integration gateway → dedicated Kinesis streams → thin adapter/normalizer code → the same downstream systems that power the pull model. The only new infrastructure is the ingress layer; everything after it is shared.

    MANDATORY — Always start from templates

    When generating any push-ingestion script, you MUST:

    1. Read the corresponding template before writing any code. Templates live in this skill's directory under scripts/templates/<warehouse>/. To find them, glob for **/push-ingestion/scripts/templates/<warehouse>/*.py — this works regardless of where the skill is installed. Do NOT search from the current working directory alone.
    2. Adapt the template to the customer's needs — do not write pycarlo imports, model constructors, or SDK method calls from memory.
    3. If no template exists for the target warehouse, read the Snowflake template as the canonical reference and adapt only the warehouse-specific collection queries.

    Template files follow this naming pattern:

    • collect_<flow>.py — collection only (queries the warehouse, writes a JSON manifest)
    • push_<flow>.py — push only (reads the manifest, sends to Monte Carlo)
    • collect_and_push_<flow>.py — combined (imports from both, runs in sequence)

    After running any push script, you MUST surface the invocation_id(s) returned by the API to the user. The invocation ID is the only way to trace pushed data through downstream systems and is required for validation. Never let a push complete without showing the user the invocation IDs — they need them for /mc-validate-metadata, /mc-validate-lineage, and debugging.

    Canonical pycarlo API — authoritative reference

    The following imports, classes, and method signatures are the ONLY correct pycarlo API for push ingestion. If your training data suggests different names, it is wrong. Use exactly what is listed here.

    Imports and client setup

    from pycarlo.core import Client, Session
    from pycarlo.features.ingestion import IngestionService
    from pycarlo.features.ingestion.models import (
        # Metadata
        RelationalAsset, AssetMetadata, AssetField, AssetVolume, AssetFreshness, Tag,
        # Lineage
        LineageEvent, LineageAssetRef, ColumnLineageField, ColumnLineageSourceField,
        # Query logs
        QueryLogEntry,
    )
    
    client = Client(session=Session(mcd_id=key_id, mcd_token=key_token, scope="Ingestion"))
    service = IngestionService(mc_client=client)
    

    Method signatures

    # Metadata
    service.send_metadata(resource_uuid=..., resource_type=..., events=[RelationalAsset(...)])
    
    # Lineage (table or column)
    service.send_lineage(resource_uuid=..., resource_type=..., events=[LineageEvent(...)])
    
    # Query logs — note: log_type, NOT resource_type
    service.send_query_logs(resource_uuid=..., log_type=..., events=[QueryLogEntry(...)])
    
    # Extract invocation ID from any response
    service.extract_invocation_id(result)
    

    RelationalAsset structure (nested, NOT flat)

    RelationalAsset(
        type="TABLE",  # ONLY "TABLE" or "VIEW" (uppercase) — normalize warehouse-native values
        metadata=AssetMetadata(
            name="my_table",
            database="analytics",
            schema="public",
            description="optional description",
        ),
        fields=[
            AssetField(name="id", type="INTEGER", description=None),
            AssetField(name="amount", type="DECIMAL(10,2)"),
        ],
        volume=AssetVolume(row_count=1000000, byte_count=111111111),  # optional
        freshness=AssetFreshness(last_update_time="2026-03-12T14:30:00Z"),  # optional
    )
    

    Environment variable conventions

    All generated scripts MUST use these exact variable names. Do NOT invent alternatives like MCD_KEY_ID, MC_TOKEN, MONTE_CARLO_KEY, etc.

    VariablePurposeUsed by
    MCD_INGEST_IDIngestion key ID (scope=Ingestion)push scripts
    MCD_INGEST_TOKENIngestion key secretpush scripts
    MCD_IDGraphQL API key IDverification scripts
    MCD_TOKENGraphQL API key secretverification scripts
    MCD_RESOURCE_UUIDWarehouse resource UUIDall scripts

    What this skill can build for you

    Tell Claude your warehouse or data platform and Monte Carlo resource UUID and this skill will generate a ready-to-run Python script that:

    • Connects to your warehouse using the idiomatic driver for that platform
    • Discovers databases, schemas, and tables
    • Extracts the right columns — names, types, row counts, byte counts, last modified time, descriptions
    • Builds the correct pycarlo RelationalAsset, LineageEvent, or QueryLogEntry objects
    • Pushes to Monte Carlo and saves an output manifest with the invocation_id for tracing

    Templates are available for common warehouses (Snowflake, BigQuery, BigQuery Iceberg, Databricks, Redshift, Hive). For any other platform, Claude will derive the appropriate collection queries from the warehouse's system catalog or metadata APIs and generate an equivalent script.

    Ready-to-run examples

    Production-ready example scripts built from these templates are published in the mcd-public-resources repo:

    • BigQuery Iceberg (BigLake) tables — metadata and query log collection for BigQuery Iceberg tables that are invisible to Monte Carlo's standard pull collector (which uses __TABLES__). Includes a --only-freshness-and-volume flag for fast periodic pushes that skip the schema/fields query — useful for hourly cron jobs after the initial full metadata push.

    Reference docs — when to load

    Reference fileLoad when…
    references/prerequisites.mdCustomer is setting up for the first time, has auth errors, or needs help creating API keys
    references/push-metadata.mdBuilding or debugging a metadata collection script
    references/push-lineage.mdBuilding or debugging a lineage collection script
    references/push-query-logs.mdBuilding or debugging a query log collection script
    references/custom-lineage.mdCustomer needs custom lineage nodes or edges via GraphQL
    references/validation.mdVerifying pushed data, running GraphQL checks, or deleting push-ingested tables
    references/direct-http-api.mdCustomer wants to call push APIs directly via curl/HTTP without pycarlo
    references/anomaly-detection.mdCustomer asks why freshness or volume detectors aren't firing

    Prerequisites — read this first

    → Load references/prerequisites.md

    Two separate API keys are required. This is the most common setup stumbling block:

    • Ingestion key (scope=Ingestion) — for pushing data
    • GraphQL API key — for verification queries

    Both use the same x-mcd-id / x-mcd-token headers but point to different endpoints.

    What you can push

    Flowpycarlo methodPush endpointType fieldExpiration
    Table metadatasend_metadata()/ingest/v1/metadataresource_type (e.g. "data-lake")Never expires
    Table lineagesend_lineage()/ingest/v1/lineageresource_type (same as metadata)Never expires
    Column lineagesend_lineage() (events include fields)/ingest/v1/lineageresource_type (same as metadata)Expires after 10 days
    Query logssend_query_logs()/ingest/v1/querylogslog_type (not resource_type!)Same as pulled
    Custom lineageGraphQL mutationsapi.getmontecarlo.com/graphqlN/A — uses GraphQL API key7 days default; set expireAt: "9999-12-31" for permanent

    Important: Query logs use log_type instead of resource_type. This is the only push endpoint where the field name differs. See references/push-query-logs.md for the full list of supported log_type values.

    The pycarlo SDK is optional — you can also call the push APIs directly via HTTP/curl. See references/direct-http-api.md for examples.

    Every push returns an invocation_id — save it. It is your primary debugging handle across all downstream systems.

    Step 1 — Generate your collection scripts

    Ask Claude to build the script for your warehouse:

    "Build me a metadata collection script for Snowflake. My MC resource UUID is abc-123."

    The script templates in **/push-ingestion/scripts/templates/ (Snowflake, BigQuery, BigQuery Iceberg, Databricks, Redshift, Hive) are the mandatory starting point for script generation — they contain the correct pycarlo imports, model constructors, and SDK calls. They are not an exhaustive list. If the customer's warehouse is not listed, use the templates as a guide and determine the appropriate queries or file-collection approach for their platform. For file-based sources (like Hive Metastore logs), provide the command to retrieve the file, parse it, and transform it into the format required by the push APIs. The push format and SDK calls are identical regardless of source; only the collection queries change.

    Batching: For large payloads, split events into batches. Use a batch size of 50 assets per push call. The pycarlo HTTP client has a hardcoded 10-second read timeout that cannot be overridden (Session and Client do not accept a timeout parameter) — larger batches (200+) will timeout on warehouses with thousands of tables. The compressed request body must also not exceed 1MB (Kinesis limit). All push endpoints support batching.

    Push frequency: Push at most once per hour. Sub-hourly pushes produce unpredictable anomaly detector behavior because the training pipeline aggregates into hourly buckets.

    Per flow, see:

    • Metadata (schema + volume + freshness): references/push-metadata.md
    • Table and column lineage: references/push-lineage.md
    • Query logs: references/push-query-logs.md

    Step 2 — Validate pushed data

    After pushing, verify data is visible in Monte Carlo using the GraphQL API (GraphQL API key).

    references/validation.md — all verification queries (getTable, getMetricsV4, getTableLineage, getDerivedTablesPartialLineage, getAggregatedQueries)

    Timing expectations:

    • Metadata: visible within a few minutes
    • Table lineage: visible within seconds to a few minutes (fast direct path to Neo4j)
    • Column lineage: a few minutes
    • Query logs: at least 15-20 minutes (async processing pipeline)

    Step 3 — Anomaly detection (optional)

    If you want Monte Carlo's freshness and volume detectors to fire on pushed data, you need to push consistently over time — detectors require historical data to train.

    references/anomaly-detection.md — recommended push frequency, minimum samples, training windows, and what to tell customers who ask why detectors aren't activating

    Custom lineage nodes and edges

    For non-warehouse assets (dbt models, Airflow DAGs, custom ETL pipelines) or cross-resource lineage, use the GraphQL mutations directly:

    references/custom-lineage.mdcreateOrUpdateLineageNode, createOrUpdateLineageEdge, deleteLineageNode, and the critical expireAt: "9999-12-31" rule

    Deleting push-ingested tables

    Push tables are excluded from the normal pull-based deletion flow (intentionally). To delete them explicitly, use deletePushIngestedTables — covered in references/validation.md under "Table management operations".

    Available slash commands

    Customers can invoke these explicitly instead of describing their intent in prose:

    CommandPurpose
    /mc-build-metadata-collectorGenerate a metadata collection script
    /mc-build-lineage-collectorGenerate a lineage collection script
    /mc-build-query-log-collectorGenerate a query log collection script
    /mc-validate-metadataVerify pushed metadata via the GraphQL API
    /mc-validate-lineageVerify pushed lineage via the GraphQL API
    /mc-validate-query-logsVerify pushed query logs via the GraphQL API
    /mc-create-lineage-nodeCreate a custom lineage node
    /mc-create-lineage-edgeCreate a custom lineage edge
    /mc-delete-lineage-nodeDelete a custom lineage node
    /mc-delete-push-tablesDelete push-ingested tables

    Debugging checkpoints

    When pushed data isn't appearing, work through these five checkpoints in order:

    1. Did the SDK return a 202 and an invocation_id? If not, the gateway rejected the request — check auth headers and resource.uuid.

    2. Is the integration key the right type? Must be scope Ingestion, created via montecarlo integrations create-key --scope Ingestion. A standard GraphQL API key will not work for push.

    3. Is resource.uuid correct and authorized? The key can be scoped to specific warehouse UUIDs. If the UUID doesn't match, you get 403.

    4. Did the normalizer process it? Use the invocation_id to search CloudWatch logs for the relevant Lambda. For query logs, check the log_type — Hive requires "hive-s3", not "hive".

    5. Did the downstream system pick it up?

      • Metadata: query getTable in GraphQL
      • Table lineage: check Neo4j within seconds–minutes (fast path via PushLineageProcessor)
      • Query logs: wait at least 15-20 minutes; check getAggregatedQueries

    Known gotchas

    • log_type vs resource_type: metadata and lineage use resource_type (e.g. "data-lake"); query logs use log_type — the only endpoint where the field name differs. Wrong value → Unsupported ingest query-log log_type error.
    • invocation_id must be saved: every output manifest should include it — it's your only tracing handle once the request leaves the SDK.
    • Query log async delay: at least 15-20 minutes. getAggregatedQueries will return 0 until processing completes — this is expected, not a bug.
    • Custom lineage expireAt defaults to 7 days: nodes vanish silently unless you set expireAt: "9999-12-31" for permanent nodes.
    • Push tables are never auto-deleted: the periodic cleanup job excludes them by default (exclude_push_tables=True). Delete them explicitly via deletePushIngestedTables (max 1,000 MCONs per call; also deletes lineage nodes and all edges touching those nodes).
    • Anomaly detectors need history: pushing once is not enough. Freshness needs 7+ pushes over ~2 weeks; volume needs 10–48 samples over ~42 days. Push at most once per hour.
    • Batching required for large payloads: the compressed request body must not exceed 1MB. Split large event lists into batches.
    • Column lineage expires after 10 days: unlike table metadata and table lineage (which never expire), column lineage has a 10-day TTL, same as pulled column lineage.
    • Quote SQL identifiers in warehouse queries: database, schema, and table names must be quoted to handle mixed-case or special characters. The quoting syntax varies by warehouse — Snowflake and Redshift use double quotes ("{db}"), BigQuery/Databricks/Hive use backticks (`db`). The templates already handle this correctly for each warehouse — follow the same quoting pattern when adapting.

    Memory safety

    Generated scripts must include a startup memory check. The collection phase loads query history rows into memory for parsing — on large warehouses with long lookback windows, this can exhaust available RAM and cause the process to be silently killed (SIGKILL / exit 137) with no traceback.

    Add this pattern near the top of every generated script, after imports:

    import os
    
    def _check_available_memory(min_gb: float = 2.0) -> None:
        """Warn if available memory is below the threshold."""
        try:
            if hasattr(os, "sysconf"):  # Linux / macOS
                page_size = os.sysconf("SC_PAGE_SIZE")
                avail_pages = os.sysconf("SC_AVPHYS_PAGES")
                avail_gb = (page_size * avail_pages) / (1024 ** 3)
            else:
                return  # Windows — skip check
        except (ValueError, OSError):
            return
        if avail_gb < min_gb:
            print(
                f"WARNING: Only {avail_gb:.1f} GB of memory available "
                f"(minimum recommended: {min_gb:.1f} GB). "
                f"Consider reducing the lookback window or increasing available memory."
            )
    

    Call _check_available_memory() before connecting to the warehouse.

    Additionally, when fetching query history:

    • Use cursor.fetchmany(batch_size) in a loop instead of cursor.fetchall() when possible
    • For very large result sets, consider adding a LIMIT clause and processing in windows

    Frequently asked questions

    What to verify before installation and use

    What does the push-ingestion source document cover?

    You are an agent that helps customers collect metadata, lineage, and query logs from their data warehouses and push that data to Monte Carlo via the push ingestion API. The push model works with any data source — if the customer's warehouse does not have a ready-made template, d…

    How do I install push-ingestion?

    The source record exposes this install command: npx skills add https://github.com/monte-carlo-data/mc-agent-toolkit --skill "skills/push-ingestion". Inspect the command and pinned source before running it.

    Which permission-related actions were detected?

    Static rules flagged exec-script, network in the source; the page lists the matching lines and excerpts.

    Alternatives

    Compare before choosing

    Computed 10045,960

    coreyhaines31/marketingskills

    ab-testing

    When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program

    Computed 10029,236

    garrytan/gbrain

    bulk-ingestion

    End-to-end discipline for turning any large data source (audio libraries, email takeouts, document corpora, chat exports, API dumps) into brain pages at scale. The lifecycle spine: SCHEMA → ACCESS → TRIAL → EVALUATE → IMPROVE → CODIFY → TEST → SKILLIFY → BULK → MONITOR. State is tracked in a durable JSON manifest (see MANIFEST-PATTERN.md) so any crash, session boundary, or subagent fan-out resumes from ground truth instead of memory.

    Computed 10025,136

    alirezarezvani/claude-skills

    app-store-optimization

    App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist

    Computed 1005,277

    dotnet/skills

    migrate-vstest-to-mtp

    Migrates .NET test projects from VSTest to Microsoft.Testing.Platform (MTP). Use when user asks to "migrate to MTP", "switch from VSTest", "enable Microsoft.Testing.Platform", "use MTP runner", set OutputType=Exe only for test projects in Directory.Build.props, or mentions EnableMSTestRunner, EnableNUnitRunner, or UseMicrosoftTestingPlatformRunner. USE FOR: MTP behavioral differences vs VSTest (exit code 8, zero tests discovered, --ignore-exit-code, TESTINGPLATFORM_EXITCODE_IGNORE); centralizing