Skip to content

feat(mcp): trace argument equality and similarity across tool calls - #1303

Open
Caleb Evans (calebevans-ab) wants to merge 13 commits into
release-candidate/v1from
devin/1790893296-mcp-arg-tracing
Open

Caleb Evans (calebevans-ab) wants to merge 13 commits into
release-candidate/v1from
devin/1790893296-mcp-arg-tracing

Conversation

@calebevans-ab

@calebevans-ab Caleb Evans (calebevans-ab) commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Adds argument records to MCP tool execution traces in OpenTelemetry and Datadog so we can distinguish repeated calls from calls where the agent changed its inputs, without logging raw free-form arguments.

We will use these records alongside tool outcomes to identify retry loops, small corrections after failures, and repeated attempts with substantially different inputs. This PR emits the data needed for that analysis; the analysis itself comes later.

Each traced argument is recorded under airbyte.mcp.arg.<name>. There are two comparison signals:

  • eq: exact equality after normalization. A 128-bit keyed HMAC of the canonical argument value. Matching hashes indicate the same canonical input; differently ordered object keys and list-classified arguments normalize consistently. The distance between two eq hashes says nothing about similarity.
  • fp: approximate similarity. A keyed 128-bit fingerprint built from overlapping three-character sequences in short text, or individual items in short string lists. Similar inputs tend to set many of the same bits. Fingerprints are generated for eligible text up to 40 normalized characters and lists of up to 32 strings; identifiers, SQL, API payloads, cursors, and streams remain equality-only.

For example, these are actual outputs from this implementation using the public test fixture, tool synthetic_tool, and argument name. All calls share scope ba5c45977e11f294. These are synthetic inputs and a test key; other keys produce different hashes and bit positions. The deployment key loader rejects this public test key.

Argument value eq fp Fingerprint similarity to "Contacts"
"Contacts" 01a27fdde5ccc0985037b874b853d796 04002802000000000009000808000000 8/8 = 1.00
"contacts" ea4df6e172b5ce4bd2ec870b8ac0c4f1 04002802000000000009000808000000 8/8 = 1.00
"contact" 8ea9c6c3d30a9b5c7f38e110245addd4 00002802000000000009000008000800 6/9 = 0.67
"invoice" af7c58222205a225343e4f6d083ceef2 00081000000000000120080000808000 0/15 = 0.00

Calling again with "Contacts" produces the same eq and fp. Changing only its case produces a different eq but the same fp. Removing the final s preserves most fingerprint bits; "invoice" shares none in this example.

The fingerprint combines text trigrams with a Bloom-filter-style bitset. Those techniques are established; the normalization, key scoping, and size limits are choices made here. Here is how the first row is generated:

  1. Equality: canonicalize the original value to the JSON bytes b'"Contacts"', preserving case. Compute HMAC-SHA256(k_eq, canonical_bytes), take the first 16 bytes, and encode them as hex to obtain the eq above.

  2. Fingerprint features: normalize Unicode and case and collapse whitespace, yielding contacts. Add start/end markers and extract overlapping three-character fragments. Below, ^ and $ stand for the actual boundary bytes 0x02 and 0x03.

    marked text: ^contacts$
    fragments:   ^co  con  ont  nta  tac  act  cts  ts$
    bit index:    51   48  109  107   27   97   35  122
    
  3. Fingerprint bits: HMAC each fragment with the scope/tool/argument-specific key. Its first digest byte modulo 128 gives the bit index shown above. Starting with 128 zero bits, set those eight positions to 1. Encoding the resulting bitset as 32 hex characters gives 04002802000000000009000808000000, the fp above. Bit 0 is the least significant bit. For a list, the same process hashes each eligible normalized item (prefixed with i:) instead of text fragments.

We need both because fingerprints deliberately discard information. They ignore case, repeated features set the same bit, and different features can collide. For example, ["id", "email"] and ["id", "email", "email"] also have identical fingerprints but different equality hashes. eq distinguishes an unchanged retry from a correction even when the fingerprints match exactly; fingerprint overlap tells us how much of the input's text or list items appears to be shared.

To compare an argument across tool executions:

  1. Select calls with the same airbyte.mcp.arg_scope_id. For fingerprints, also match the tool name and argument name, because those are part of the fingerprint key.
  2. Compare eq first to identify unchanged inputs.
  3. When eq differs and both records have fp, calculate bitset Jaccard similarity: popcount(fp_a & fp_b) / popcount(fp_a | fp_b). More shared bits means a higher score. For example, replacing one field in a select_fields list should usually score higher than replacing the entire list. Collisions make this an approximate signal, not proof of equality or semantic similarity.

Keys are scoped to the verified caller and server-issued session. Without a session, the scope falls back to the caller, client name/major version, and a 30-minute bucket. Comparisons across scopes are not meaningful; conversation grouping is not implemented yet. Without a valid secret or verified caller, no hashes are emitted.

Configs and manifests record presence only. Approved closed-set values, bounded pagination values, and bounded entity names can be recorded directly; existing intent capture remains. These exceptions let us retain useful context while keeping free-form payloads out of traces.

Validation: 978 targeted tests passed, including the native Datadog HTTP integration test with loopback access. poe check and formatting checks passed.

…rouping work, to be replaced)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…s, keyed eq/fp records, validator)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ity validity, and HTTP docs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

👋 Greetings, Airbyte Team Member!

Here are some helpful tips and reminders for your convenience.

💡 Show Tips and Tricks

Testing This PyAirbyte Version

You can test this version of PyAirbyte using the following:

# Run PyAirbyte CLI from this branch:
uvx --from 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1790893296-mcp-arg-tracing' pyairbyte --help

# Install PyAirbyte from this branch for development:
pip install 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1790893296-mcp-arg-tracing'

PR Slash Commands

Airbyte Maintainers can execute the following slash commands on your PR:

  • /fix-pr - Fixes most formatting and linting issues
  • /uv-lock - Updates uv.lock file
  • /test-pr - Runs tests with the updated PyAirbyte
  • /prerelease - Builds and publishes a prerelease version to PyPI
📚 Show Repo Guidance

Helpful Resources

Community Support

Questions? Join the #pyairbyte channel in our Slack workspace.

📝 Edit this welcome message.

@github-code-quality

github-code-quality Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: Python

Python / code-coverage/pytest-no-creds

The overall line coverage in commit e29be2d in the devin/1790893296-mcp... branch is 79%. The line coverage in commit d9f652f in the release-candidate/v1 branch is 65%.

Show a line coverage summary of the most impacted files.
File release-candidate/v1 d9f652f devin/1790893296-mcp... e29be2d +/-
airbyte/_util/api_util.py 36% 61% +25%
airbyte/mcp/cloud.py 52% 81% +29%
airbyte/cloud/connectors.py 34% 73% +39%
airbyte/mcp/_otel.py 0% 92% +92%
airbyte/_direct...ctors/models.py 0% 94% +94%
airbyte/mcp/_telemetry.py 0% 95% +95%
airbyte/mcp/_sso_auth.py 0% 96% +96%
airbyte/mcp/_arg_trace.py 0% 97% +97%
airbyte/cloud/models.py 0% 97% +97%
airbyte/mcp/int...nc_status_ui.py 0% 97% +97%

Python / code-coverage/pytest

The overall line coverage in commit e29be2d in the devin/1790893296-mcp... branch is 81%. The line coverage in commit d9f652f in the release-candidate/v1 branch is 71%.

Show a line coverage summary of the most impacted files.
File release-candidate/v1 d9f652f devin/1790893296-mcp... e29be2d +/-
airbyte/mcp/cloud.py 52% 81% +29%
airbyte/mcp/_otel.py 0% 92% +92%
airbyte/mcp/int..._registry_ui.py 0% 92% +92%
airbyte/mcp/_user_identity.py 0% 93% +93%
airbyte/_direct...ctors/models.py 0% 94% +94%
airbyte/mcp/_telemetry.py 0% 95% +95%
airbyte/mcp/_sso_auth.py 0% 96% +96%
airbyte/mcp/_arg_trace.py 0% 97% +97%
airbyte/cloud/models.py 0% 97% +97%
airbyte/mcp/int...nc_status_ui.py 0% 97% +97%

Python / code-coverage/pytest-unit

The overall line coverage in commit e29be2d in the devin/1790893296-mcp... branch is 75%. Line coverage data for the release-candidate/v1 branch is not yet available.

Show a line coverage summary of the most covered files.
File release-candidate/v1 devin/1790893296-mcp... e29be2d +/-
airbyte/mcp/_arg_trace.py — 97% —
airbyte/mcp/_sso_auth.py — 96% —
airbyte/_direct...ctors/models.py — 94% —
airbyte/mcp/_otel.py — 92% —
airbyte/cloud/client.py — 91% —
airbyte/mcp/cloud.py — 81% —
airbyte/progress.py — 80% —
airbyte/cloud/connectors.py — 73% —
airbyte/shared/...ql_processor.py — 68% —
airbyte/_util/api_util.py — 61% —

Updated October 02, 2026 21:55 UTC

…og capture in test

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…propagation; stable param ids

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…asses

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… similarity

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@calebevans-ab

Copy link
Copy Markdown
Contributor Author

Codex (@codex) review

@calebevans-ab Caleb Evans (calebevans-ab) changed the title feat(mcp): privacy-preserving argument tracing (eq/fp records) feat(mcp): trace argument equality and similarity across tool calls Oct 2, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-02T16:33:14.430128Z a76af58 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: ef2b7ce488

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

@calebevans-ab

Copy link
Copy Markdown
Contributor Author

/claude-review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ef2b7ce488

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment thread airbyte/mcp/_arg_trace.py
Comment thread airbyte/mcp/_arg_trace.py
Comment thread airbyte/mcp/_telemetry_key.py Outdated
@calebevans-ab

Copy link
Copy Markdown
Contributor Author

Codex (@codex) review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: a76af58301

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

View session

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant