-
Notifications
You must be signed in to change notification settings - Fork 9
Add Signals MCP tutorial: manage Signals with AI assistants #1891
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jborlase-snowplow
wants to merge
6
commits into
main
Choose a base branch
from
tutorial/t5-mcp-tutorial
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
57beacc
Add Signals MCP tutorial: manage Signals with AI assistants
jborlase-snowplow 7a7ddd6
Add live Console screenshots and align wording with verified UI
jborlase-snowplow f470c9d
Apply review feedback: versioning semantics, Inspector verification, …
jborlase-snowplow fd83670
Remove verification-run error artifacts from the warehouse testing note
jborlase-snowplow b78f9ab
Apply product-owner edits: cross-client install, OAuth-first auth
jborlase-snowplow 83a5766
Add the Snowplow Assistant as a first-class route alongside the MCP s…
jborlase-snowplow File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| --- | ||
| title: "Conclusions and next steps from the conversational Signals tutorial" | ||
| position: 5 | ||
| sidebar_label: "Conclusion" | ||
| description: "Recap of managing Signals conversationally in the Snowplow Assistant or with the Snowplow MCP server, with next steps for services and interventions." | ||
| keywords: ["snowplow assistant", "snowplow mcp", "signals services", "interventions", "next steps"] | ||
| date: "2026-08-04" | ||
| --- | ||
|
|
||
| In this tutorial you managed a complete Signals workflow conversationally, in the Snowplow Assistant or in your own MCP-connected assistant: | ||
|
|
||
| * Opened the assistant in Console, or installed the Snowplow plugin and authenticated with your Console account | ||
| * Defined a stream attribute group with three session metrics, saved as a draft | ||
| * Tested the definitions and published the group | ||
| * Verified the configuration in Console, and the live values in the Snowplow Inspector | ||
| * Added an attribute and published the new version, without leaving the conversation | ||
|
|
||
| ## Beyond attribute groups | ||
|
|
||
| Attribute groups are one part of [Signals](/docs/signals/introduction/). The same conversational approach applies to: | ||
|
|
||
| * [Services](/docs/signals/applications/services/): bundle attribute groups behind a single name for your applications to query | ||
| * [Interventions](/docs/signals/interventions/): define rules that push an action to your application the moment a user's attributes meet your criteria | ||
| * [Attribute keys](/docs/signals/attributes/attribute-keys/): create custom keys to aggregate by, such as an account or tenant ID | ||
| * [Agentic contexts](/docs/signals/agentic-contexts/): maintain a rolling log of each user's recent events to ground your own AI agents in live behavior | ||
|
|
||
| Both routes reach beyond Signals into the rest of Snowplow Console, from data structures and tracking plans to pipeline health and failed events. See [Snowplow Assistant](/docs/llms-support/console-agent/) and [Snowplow MCP server](/docs/llms-support/snowplow-mcp/) for what each one covers. | ||
|
|
||
| ## Next steps | ||
|
|
||
| Some directions to take from here: | ||
|
|
||
| * Follow the [interventions tutorial](/tutorials/signals-interventions/start) to react to attribute changes in an ecommerce app, then try recreating its configuration conversationally | ||
| * Use the [Python SDK](/tutorials/python-tracking-and-signals/introduction) when you want Signals definitions in version control, with the assistant helping you write them | ||
| * Ask your assistant to explore what's already in your account: "list my attribute groups and summarize what each one calculates" is a useful audit prompt |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| --- | ||
| title: "Open the Snowplow Assistant or connect the MCP server" | ||
| position: 2 | ||
| sidebar_label: "Connect your assistant" | ||
| description: "Start a conversation with the Snowplow Assistant in Console, or install the Snowplow MCP server in your own AI assistant, authenticate with OAuth, and check the connection." | ||
| keywords: ["snowplow assistant", "snowplow mcp install", "claude code plugin", "mcp authentication", "console api key", "mcp-remote"] | ||
| date: "2026-08-04" | ||
| --- | ||
|
|
||
| Both routes end in the same place: a conversation that can read and change your Signals configuration on your behalf. Pick the one that fits where you want to work. | ||
|
|
||
| ## Use the Snowplow Assistant | ||
|
|
||
| The [Snowplow Assistant](/docs/llms-support/console-agent/) is built into [Snowplow Console](https://console.snowplowanalytics.com) as a chat interface, so there's nothing to install and no credentials to configure. It authenticates with your current Console session and operates with your existing Console permissions, and it asks you to confirm any action that changes your configuration before it proceeds. | ||
|
|
||
| Log in to Console, open the assistant, and you're ready to start prompting. If the chat interface doesn't appear, an administrator can enable the assistant for your organization from the **Settings** section of Console: see [Snowplow Assistant](/docs/llms-support/console-agent/) for what it covers and how it handles your data. | ||
|
|
||
| On this route you can skip straight to [defining attributes](/tutorials/signals-mcp/define-attributes-conversationally). The rest of this page connects the MCP server to your own assistant instead. | ||
|
|
||
| ## Install the Snowplow plugin | ||
|
|
||
| The Snowplow MCP server is a remote server, hosted by Snowplow: there's no server for you to deploy or maintain. Connecting your assistant to it means pointing your MCP client at the server URL and authenticating with your Snowplow Console account. | ||
|
|
||
| The Snowplow plugin bundles the MCP server with six skills, including the `signals` skill that guides the assistant through Signals workflows like the one in this tutorial. The skills are loaded on demand: when you ask about attribute groups, the assistant automatically engages the `signals` skill, so there's no slash command to run. The plugin source lives in the [`snowplow/skills` repository](https://github.com/snowplow/skills). | ||
|
|
||
| ### Install in any assistant | ||
|
|
||
| Whichever assistant you use, the recommended way to install is the vendor-neutral [open-plugin](https://github.com/vercel-labs/plugins) CLI, which installs the MCP server and the skills together: | ||
|
|
||
| ```bash | ||
| npx plugins add snowplow/skills | ||
| ``` | ||
|
|
||
| The CLI detects which agent tools you have on your machine and installs the plugin to all of them. To install for a single one, name it with `--target`: | ||
|
|
||
| ```bash | ||
| npx plugins add snowplow/skills --target claude-code | ||
| ``` | ||
|
|
||
| ### Install in Claude Code | ||
|
|
||
| Claude Code also has a native plugin marketplace, which reads the plugin definition straight from the repository and updates it automatically when the repository changes. Run these two commands inside Claude Code: | ||
|
|
||
| ```text | ||
| /plugin marketplace add snowplow/skills | ||
| /plugin install snowplow@snowplow | ||
| ``` | ||
|
|
||
| ### Other MCP clients | ||
|
|
||
| Any MCP-capable client can connect to the server directly. For example, using [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) in a JSON-based client configuration such as Claude Desktop or Cursor: | ||
|
|
||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "snowplow-mcp": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "mcp-remote", | ||
| "https://console.snowplowanalytics.com/api/agent/mcp", | ||
| "3334", | ||
| "--static-oauth-client-info", | ||
| "{\"client_id\":\"NxCcdyu13Cr4umnIYw70evvUyRXRvyWf\"}" | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| See [Snowplow MCP server](/docs/llms-support/snowplow-mcp/) for tested configurations for Claude.ai, Claude Desktop, Claude Code, Codex, and Cursor. You won't get the bundled skills this way, but all the Signals tools work the same. | ||
|
|
||
| ## Authenticate with your Console account | ||
|
|
||
| Use OAuth. It's the simpler path and the one to start with: there's nothing to configure, because every installation route above is already set up for it. The first time your assistant calls a Snowplow tool, a browser window opens for you to log in to [Snowplow Console](https://console.snowplowanalytics.com). The assistant then operates with the same permissions as your user account, and can only access your organization's resources. | ||
|
|
||
| For most people that's the whole of authentication, and you can go straight to checking the connection. | ||
|
|
||
| ### Optional: authenticate with API keys | ||
|
|
||
| OAuth tokens expire, which means occasional re-authentication prompts. If you'd rather have a connection that keeps working without a browser, authenticate with a Console API key instead. You'll need three values: | ||
|
|
||
| 1. Your organization ID, from the **Manage organization** page in Console settings | ||
| 2. An API key ID, which you get when you [create an API key in Console](/docs/account-management/#create-an-api-key) | ||
| 3. The API key itself, which Console shows only once, at creation | ||
|
|
||
| Then pass them as headers in your MCP client configuration: | ||
|
|
||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "snowplow-mcp": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "mcp-remote", | ||
| "https://console.snowplowanalytics.com/api/agent/mcp", | ||
| "--header", | ||
| "X-Org-Id:<ORGANIZATION_ID>", | ||
| "--header", | ||
| "X-Api-Key-Id:<API_KEY_ID>", | ||
| "--header", | ||
| "X-Api-Key:<API_KEY>" | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| :::warning[API keys use admin permissions by default] | ||
| By default, API keys are created with all permissions, which may be broader than you intend for an assistant. If you want the assistant to operate with your user account's more limited permissions, stay with OAuth. Store the key securely, and never paste credentials into the assistant's chat. | ||
| ::: | ||
|
|
||
| See [Connect to Snowplow Signals](/docs/signals/connection/) for the full list of connection credentials and where to find each one. | ||
|
|
||
| ## Check the connection | ||
|
|
||
| Start a new session in your assistant and ask it something that requires a Snowplow tool call: | ||
|
|
||
| ```text | ||
| Which Snowplow organization am I connected to? | ||
| ``` | ||
|
|
||
| The assistant should call the `get_organization` tool and reply with your organization's name and ID. With OAuth, this first call is what triggers the browser login. Confirm the organization ID matches the one in Console before continuing: it's worth being certain the assistant is pointed at the right account before you start creating resources. | ||
115 changes: 115 additions & 0 deletions
115
tutorials/signals-mcp/define-attributes-conversationally.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| --- | ||
| title: "Define attributes conversationally" | ||
| position: 3 | ||
| sidebar_label: "Define attributes" | ||
| description: "Prompt the Snowplow Assistant or your own AI assistant to create a Signals stream attribute group, test it against warehouse data, and publish it." | ||
| keywords: ["signals attribute group", "snowplow assistant", "conversational configuration", "test attributes", "publish signals"] | ||
| date: "2026-08-04" | ||
| --- | ||
|
|
||
| With your assistant ready, you can define your first attribute group by describing it. You'll create a stream [attribute group](/docs/signals/attributes/attribute-groups/) that calculates three session metrics from page view events, the same ones as in the [Signals quick start](/tutorials/signals-quickstart/define-attribute-group): | ||
|
|
||
| * How many page views occurred in the last 15 minutes, per session | ||
| * The last seen browser name, per session | ||
| * The first seen page referrer, per session | ||
|
|
||
| Send the prompts on this page in the assistant you chose on the previous page. They're the same in the Snowplow Assistant and in an MCP-connected assistant, and so are the resources they create. | ||
|
|
||
| :::note[Transcripts are representative] | ||
| The transcript excerpts on this page come from a real Claude Code session with the MCP server, condensed for readability. Assistant output varies between runs and between assistants, so the wording you see, and even the steps your assistant takes, will differ. What stays the same are the resources it creates, and those are what you'll verify in Console in the next step. | ||
| ::: | ||
|
|
||
| ## Describe the attribute group | ||
|
|
||
| Write your prompt as a goal, with the details the assistant needs: the group name, the attribute key to aggregate against, and what each attribute should calculate. Asking the assistant not to publish keeps you in control of the review. | ||
|
|
||
| ```text | ||
| Create a stream attribute group called tut_mcp_session_metrics, keyed on | ||
| domain_sessionid, with three attributes calculated from page_view events: | ||
|
|
||
| 1. page_view_count: how many page views in the last 15 minutes | ||
| 2. most_recent_browser: the last seen browser name, from the YAUAA context | ||
| 3. first_referrer: the first seen referrer host, ignoring empty referrers | ||
|
|
||
| Save it as a draft, don't publish it yet. | ||
| ``` | ||
|
|
||
| The assistant works out the rest: which aggregation each attribute needs, the attribute types, and the exact event and entity references. A representative response: | ||
|
|
||
| ```text | ||
| Assistant: | ||
| [calls signals_list_attribute_keys] | ||
| [calls signals_create_attribute_group] | ||
|
|
||
| Created tut_mcp_session_metrics version 1 as a draft, keyed on the built-in | ||
| domain_sessionid attribute key: | ||
|
|
||
| - page_view_count (int32): counter of page_view events over a 15-minute period | ||
| - most_recent_browser (string): last aggregation on the agentName property of | ||
| the yauaa_context entity | ||
| - first_referrer (string): first aggregation on the refr_urlhost atomic field, | ||
| with a criteria filter excluding events where page_referrer is empty | ||
|
|
||
| It's not published, so Signals isn't calculating anything yet. | ||
| ``` | ||
|
|
||
| The `most_recent_browser` attribute relies on the [YAUAA enrichment](/docs/pipeline/enrichments/available-enrichments/yauaa-enrichment/), which attaches a `yauaa_context` entity to each event. If it's not enabled on your pipeline, ask the assistant to check: it can list your enrichment configurations too. | ||
|
|
||
| ## Review the draft | ||
|
|
||
| New attribute groups are saved as drafts: definitions in the registry that aren't deployed to any compute engine. Nothing is calculated, and nothing reaches your applications, until you publish. | ||
|
|
||
| Before moving on, review what was actually created rather than trusting the summary. Ask the assistant to show the full definition: | ||
|
|
||
| ```text | ||
| Show me the full definition of tut_mcp_session_metrics. | ||
| ``` | ||
|
|
||
| The assistant returns the stored configuration. Check that: | ||
|
|
||
| * The attribute key is `domain_sessionid` | ||
| * `page_view_count` uses a `counter` aggregation with a 15-minute period (`PT15M`) | ||
| * `most_recent_browser` uses a `last` aggregation on the `yauaa_context` entity's `agentName` property | ||
| * `first_referrer` uses a `first` aggregation on `refr_urlhost`, with a criteria filter on `page_referrer` | ||
|
|
||
| You'll confirm the same details in Snowplow Console on the next page. If anything is off, say so in plain language, for example "the period should be 15 minutes, not 15 days", and ask the assistant to update the draft. | ||
|
|
||
| ## Test against warehouse data | ||
|
|
||
| Before publishing, you can test what the group would calculate. Testing runs the attribute definitions against recent events in your warehouse's atomic events table and returns sample results, the same calculation as [previewing an attribute group](/tutorials/signals-quickstart/define-attribute-group#test-the-attribute-definitions) in Console. | ||
|
|
||
| ```text | ||
| Test tut_mcp_session_metrics against recent events before we publish. | ||
| ``` | ||
|
|
||
| The result is a small table: one row per `domain_sessionid` value found in the sample, with a column for each of the three attributes. Use it to sanity-check the definitions, and iterate conversationally if something looks wrong: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't get a small table on the Snowplow Assistant, in that case it just summarized the data: |
||
|
|
||
| * If `most_recent_browser` is always null, the YAUAA enrichment probably isn't enabled on your pipeline | ||
| * If `first_referrer` is mostly null, your traffic may be mostly direct, so try a test visit that arrives via a link | ||
| * If no rows come back at all, there were no page view events in the sampled window, so check that your tracking is sending events | ||
|
|
||
| Adjust the draft as many times as you like: ask for a different period, another filter, or an extra attribute, and test again. | ||
|
|
||
| :::note[Testing requires a warehouse connection] | ||
| Signals runs test queries against your warehouse rather than the live stream, so testing attribute definitions requires a warehouse destination connected to your organization. Without one, publish the draft and verify it against live events instead: the next page checks the values Signals calculates. | ||
| ::: | ||
|
|
||
| ## Publish the attribute group | ||
|
|
||
| Once you're satisfied with the definition, publish it: | ||
|
|
||
| ```text | ||
| Looks good. Publish tut_mcp_session_metrics. | ||
| ``` | ||
|
|
||
| ```text | ||
| Assistant: | ||
| [calls signals_publish] | ||
|
|
||
| Published tut_mcp_session_metrics version 1. Signals is now calculating the | ||
| three attributes from your live event stream. | ||
| ``` | ||
|
|
||
| Publishing deploys the configuration to the Signals streaming engine. From this moment on, every page view event flowing through your pipeline updates the three attributes for its session. Stream attribute groups only process events from the publish time onwards, unless you configured a [backfill](/docs/signals/attributes/attribute-groups/#backfill-attributes) — see the [configuration workflow](/docs/signals/attributes/#configuration-workflow) for how the lifecycle fits together. | ||
|
|
||
| The assistant says it's published. Next, you'll confirm that independently in Console, and watch the attribute values change in real time. | ||
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+433 KB
tutorials/signals-mcp/images/console-attribute-group-four-attributes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| --- | ||
| title: "Manage Snowplow Signals conversationally with the Snowplow Assistant or the MCP server" | ||
| position: 1 | ||
| sidebar_label: "Introduction" | ||
| description: "Manage Snowplow Signals conversationally, either with the Snowplow Assistant in Console or with your own MCP-connected assistant: define, test, publish, and verify a real-time attribute group." | ||
| keywords: ["snowplow assistant", "snowplow mcp", "model context protocol", "ai assistant", "snowplow signals", "attribute groups"] | ||
| date: "2026-08-04" | ||
| --- | ||
|
|
||
| You can manage [Signals](/docs/signals/introduction/) by describing what you want in plain language and letting an AI assistant make the API calls for you: define, test, publish, and query real-time attributes conversationally. There are two routes, and this tutorial works with either: | ||
|
|
||
| * The [Snowplow Assistant](/docs/llms-support/console-agent/) built into Snowplow Console, where there's nothing to install | ||
| * The [Snowplow MCP server](/docs/llms-support/snowplow-mcp/), which connects the AI assistant you already work in to your Snowplow account | ||
|
|
||
| The prompts are the same either way. In this tutorial you'll build the same attribute group as the [Signals quick start](/tutorials/signals-quickstart/start), conversationally instead of through the Console UI. You'll: | ||
|
|
||
| * Open the Snowplow Assistant in Console, or connect the MCP server to your own assistant | ||
| * Define a stream attribute group that calculates three session metrics from page view events | ||
| * Test the definition, then publish it to Signals | ||
| * Verify the results in Snowplow Console, and watch the live attribute values in the Snowplow Inspector | ||
| * Ask for a change, and publish the new version it creates | ||
|
|
||
| The assistant handles the mechanics, but you stay in control: Signals saves new attribute groups as drafts, so nothing is calculated until you review the definition and publish it. Every step ends with a check you can make yourself in Console or in the [Snowplow Inspector](/docs/testing/snowplow-inspector/), rather than relying on the assistant's own description of what it did. | ||
|
|
||
| The transcripts in this tutorial come from a [Claude Code](https://claude.com/product/claude-code) session, because Snowplow ships a plugin that bundles the MCP server with Signals-aware skills. | ||
|
|
||
| This tutorial should take around 20 minutes to complete. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| This tutorial assumes that you have: | ||
|
|
||
| * A Snowplow account with a running pipeline, and page view tracking on a web application, so Signals has events to calculate from | ||
| * [Signals enabled](/docs/signals/setup/) on your account | ||
| * Either the [Snowplow Assistant](/docs/llms-support/console-agent/) enabled on your organization, or an MCP-capable AI assistant such as Claude Code, Claude Desktop, or Cursor | ||
| * The [Snowplow Inspector](/docs/testing/snowplow-inspector/) browser extension, to check the calculated attribute values | ||
|
|
||
| :::note[You need a Snowplow account and pipeline] | ||
| Signals computes attributes from real events flowing through your pipeline, so you need a Snowplow account with a running pipeline and Signals enabled. | ||
|
|
||
| If you don't have one, you can deploy and use a [Snowplow free trial](https://snowplow.io/get-started/snowplow-free-trial) to follow along. | ||
| ::: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "title": "Manage Signals with AI assistants using the Snowplow MCP server", | ||
| "description": "Connect the Snowplow MCP server to your AI coding assistant and define, test, and publish Signals attribute groups conversationally.", | ||
| "label": "Signals implementation", | ||
| "useCase": "Real-time personalization", | ||
| "technologies": ["MCP", "Claude Code"], | ||
| "snowplowTech": ["Signals", "Console"] | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't a screenshot be useful here? It would help someone like me at least to visualize what we are talking about when skimming the text faster. I see we don't add screenshots for Snowplow Assistant in Console also in other parts of the docs, not sure if that is a conscious decision.