Read and manage the authenticated user's Echo campaigns, their sharing visuals, their folders, and their analytics. All tools operate only on campaigns and folders owned by the connected user. Reference a campaign by its numeric id or slug, a folder or visual by its numeric id. Each campaign holds up to 10 sharing visuals, each with its own box_* element layout and its own sharing_url and sharing_text (empty values inherit from the primary visual at share time); the first visual (lowest position) is the primary one used when the campaign is shared. Add visuals by https URL (preferred) or base64, update their layout and sharing fields, or reorder them. Analytics tools accept an optional from/to date range (YYYY-MM-DD); omitting it returns lifetime totals (summary) or the last 30 days (timeseries/breakdown).
Point any MCP-compatible client at this endpoint:
Authentication is handled automatically over OAuth — no manual token needed.
mcp:use scope.claude CLI:
This adds the server for the current project — append --scope user to make it available everywhere.
/mcp, then select echo to authenticate.mcp:use scope.mcp:use scope on our authorization screen.The server speaks OAuth 2.1, so clients connect without you copying any secrets:
mcp:use, grants access to your campaigns.https://mcp.echo.walls.io/.well-known/oauth-protected-resource and
https://mcp.echo.walls.io/.well-known/oauth-authorization-server.401 Unauthorized.Every tool operates only on campaigns owned by the connected user — other users' data is never exposed. Reference a campaign by its numeric id or slug.
16 tools, kept in sync with the server.
list-campaigns-tool
List the campaigns in the acting organisation, newest first, each with its id, title, slug, public URL and short link. Paged: the response carries the total count, so request further pages until page * per_page >= total.
| Input | Type | Required | Description |
|---|---|---|---|
per_page |
integer | no | Campaigns per page (1-100). |
page |
integer | no | Page number (1-based) for paging through results. |
get-campaign-tool
Get the full configuration and lifetime metrics for one of the authenticated user's campaigns, identified by its numeric id or slug.
| Input | Type | Required | Description |
|---|---|---|---|
campaign |
string | yes | The campaign id or slug. |
get-campaign-analytics-tool
Get analytics totals (views, clicks, shares, conversions) and engagement rates for one of the user's campaigns. Omit the dates for lifetime figures, or pass from/to for a window.
| Input | Type | Required | Description |
|---|---|---|---|
campaign |
string | yes | The campaign id or slug. |
from |
string | no | Start date (YYYY-MM-DD). Optional; omit with "to" for lifetime totals. |
to |
string | no | End date (YYYY-MM-DD). Optional. |
get-campaign-timeseries-tool
Get a daily time series for one metric (views, clicks, shares or conversions) of one of the user's campaigns. Defaults to the last 30 days; gaps are zero-filled.
| Input | Type | Required | Description |
|---|---|---|---|
campaign |
string | yes | The campaign id or slug. |
metric |
string | no | Which metric to chart. |
from |
string | no | Start date (YYYY-MM-DD). Optional. |
to |
string | no | End date (YYYY-MM-DD). Optional. |
get-campaign-breakdown-tool
Break down one of the user's campaign analytics by a dimension: "device" (works for any metric) or "platform" (share platforms). Defaults to the last 30 days.
| Input | Type | Required | Description |
|---|---|---|---|
campaign |
string | yes | The campaign id or slug. |
dimension |
string | yes | Group by device or by share platform. |
metric |
string | no | Metric to break down (ignored for the platform dimension, which always uses shares). |
from |
string | no | Start date (YYYY-MM-DD). Optional. |
to |
string | no | End date (YYYY-MM-DD). Optional. |
get-campaign-shares-tool
List a campaign's recent shares — the same merged groups shown in the dashboard, where repeat shares from the same person are combined and their clicks and conversions summed. Newest first by default; sortable by date, clicks or conversions, and paged. Each row carries the participant's name, role, platform, device, picture, share URL, code, sharing text, clicks, conversions, merged_count and timestamps — never their email.
| Input | Type | Required | Description |
|---|---|---|---|
campaign |
string | yes | The campaign id or slug. |
sort |
string | no | Sort field: share date, total clicks, or total conversions. |
direction |
string | no | Sort direction. |
per_page |
integer | no | Rows per page (1-100). |
page |
integer | no | Page number (1-based) for paging through results. |
create-campaign-tool
Create a new campaign in the acting organisation, attributed to the authenticated user. Only "title" is required; a unique slug is generated from the title when omitted.
| Input | Type | Required | Description |
|---|---|---|---|
title |
string | yes | Campaign title. |
slug |
string | no | URL slug. Optional; generated from the title when omitted. |
folder_id |
integer | no | Id of one of your folders to file the campaign into. Optional. |
utm_source |
string | no | UTM source. |
utm_medium |
string | no | UTM medium. |
utm_campaign |
string | no | UTM campaign. |
utm_content |
string | no | UTM content. |
hide_branding |
boolean | no | Hide Echo branding. |
viral_tracking |
boolean | no | Enable viral chain tracking. |
conversion_tracking |
boolean | no | Enable conversion tracking. |
social_proof |
boolean | no | Show recent sharers. |
language_default |
string | no | Default language code. |
update-campaign-tool
Update fields on one of the authenticated user's campaigns. Identify it by id or slug; only the provided fields are changed.
| Input | Type | Required | Description |
|---|---|---|---|
campaign |
string | yes | The campaign id or slug to update. |
title |
string | no | Campaign title. |
slug |
string | no | URL slug. |
folder_id |
integer|null | no | Id of one of your folders to file the campaign into; pass null to move it back to the root level. |
utm_source |
string | no | UTM source. |
utm_medium |
string | no | UTM medium. |
utm_campaign |
string | no | UTM campaign. |
utm_content |
string | no | UTM content. |
hide_branding |
boolean | no | Hide Echo branding. |
viral_tracking |
boolean | no | Enable viral chain tracking. |
conversion_tracking |
boolean | no | Enable conversion tracking. |
social_proof |
boolean | no | Show recent sharers. |
language_default |
string | no | Default language code. |
list-campaign-visuals-tool
List a campaign's sharing visuals in position order, each with its id, file URL, composited preview URL and box_* element layout. The first visual is the primary one, used when the campaign is shared. A campaign holds up to 10 visuals.
| Input | Type | Required | Description |
|---|---|---|---|
campaign |
string | yes | The campaign id or slug. |
create-campaign-visual-tool
Add a sharing visual to a campaign, appended at the end of the strip (a campaign holds at most 10). Provide the image either as a public https image_url (preferred) or as base64-encoded image_base64 data; jpeg, png and webp up to 10 MB are accepted. Optionally pass box_* fields to set the element layout right away, and sharing_url / sharing_text to give the visual its own sharing settings (empty values inherit from the primary visual at share time).
| Input | Type | Required | Description |
|---|---|---|---|
campaign |
string | yes | The campaign id or slug. |
image_url |
string | no | Public https URL of the visual's image file (jpeg, png, or webp, max 10 MB). Preferred over image_base64. |
image_base64 |
string | no | Base64-encoded image data (optionally as a data: URI). Use only for small images; prefer image_url. |
sharing_url |
string | no | Destination URL opened when a share of this visual is clicked. Leave empty to inherit the primary visual's URL at share time. |
sharing_text |
string | no | Sharing text for this visual (max 1000 characters). Leave empty to inherit the primary visual's text. |
box_name_enabled |
boolean | no | Show the name element on the image. |
box_name_x |
integer | no | X position of the name element, in px on the source image. |
box_name_y |
integer | no | Y position of the name element, in px on the source image. |
box_name_width |
integer | no | Width of the name element in px. |
box_name_height |
integer | no | Height of the name element in px. |
box_name_text_align |
string | no | Text alignment of the name element. |
box_name_font_size |
integer | no | Font size of the name element in px (8-120). |
box_name_color |
string | no | Text color of the name element as a hex value, e.g. #ffffff. |
box_name_font |
string | no | Font of the name element: a Google font from the editor's list or one of the organisation's custom fonts; invalid fonts fall back to the default. |
box_name_style |
string | no | Comma-joined text styles for the name element: bold, italic, underline. |
box_role_enabled |
boolean | no | Show the role element on the image. |
box_role_x |
integer | no | X position of the role element, in px on the source image. |
box_role_y |
integer | no | Y position of the role element, in px on the source image. |
box_role_width |
integer | no | Width of the role element in px. |
box_role_height |
integer | no | Height of the role element in px. |
box_role_text_align |
string | no | Text alignment of the role element. |
box_role_font_size |
integer | no | Font size of the role element in px (8-120). |
box_role_color |
string | no | Text color of the role element as a hex value, e.g. #ffffff. |
box_role_font |
string | no | Font of the role element: a Google font from the editor's list or one of the organisation's custom fonts; invalid fonts fall back to the default. |
box_role_style |
string | no | Comma-joined text styles for the role element: bold, italic, underline. |
box_custom_1_enabled |
boolean | no | Show the custom field 1 element on the image. |
box_custom_1_x |
integer | no | X position of the custom field 1 element, in px on the source image. |
box_custom_1_y |
integer | no | Y position of the custom field 1 element, in px on the source image. |
box_custom_1_width |
integer | no | Width of the custom field 1 element in px. |
box_custom_1_height |
integer | no | Height of the custom field 1 element in px. |
box_custom_1_text_align |
string | no | Text alignment of the custom field 1 element. |
box_custom_1_font_size |
integer | no | Font size of the custom field 1 element in px (8-120). |
box_custom_1_color |
string | no | Text color of the custom field 1 element as a hex value, e.g. #ffffff. |
box_custom_1_font |
string | no | Font of the custom field 1 element: a Google font from the editor's list or one of the organisation's custom fonts; invalid fonts fall back to the default. |
box_custom_1_style |
string | no | Comma-joined text styles for the custom field 1 element: bold, italic, underline. |
box_custom_2_enabled |
boolean | no | Show the custom field 2 element on the image. |
box_custom_2_x |
integer | no | X position of the custom field 2 element, in px on the source image. |
box_custom_2_y |
integer | no | Y position of the custom field 2 element, in px on the source image. |
box_custom_2_width |
integer | no | Width of the custom field 2 element in px. |
box_custom_2_height |
integer | no | Height of the custom field 2 element in px. |
box_custom_2_text_align |
string | no | Text alignment of the custom field 2 element. |
box_custom_2_font_size |
integer | no | Font size of the custom field 2 element in px (8-120). |
box_custom_2_color |
string | no | Text color of the custom field 2 element as a hex value, e.g. #ffffff. |
box_custom_2_font |
string | no | Font of the custom field 2 element: a Google font from the editor's list or one of the organisation's custom fonts; invalid fonts fall back to the default. |
box_custom_2_style |
string | no | Comma-joined text styles for the custom field 2 element: bold, italic, underline. |
box_custom_3_enabled |
boolean | no | Show the custom field 3 element on the image. |
box_custom_3_x |
integer | no | X position of the custom field 3 element, in px on the source image. |
box_custom_3_y |
integer | no | Y position of the custom field 3 element, in px on the source image. |
box_custom_3_width |
integer | no | Width of the custom field 3 element in px. |
box_custom_3_height |
integer | no | Height of the custom field 3 element in px. |
box_custom_3_text_align |
string | no | Text alignment of the custom field 3 element. |
box_custom_3_font_size |
integer | no | Font size of the custom field 3 element in px (8-120). |
box_custom_3_color |
string | no | Text color of the custom field 3 element as a hex value, e.g. #ffffff. |
box_custom_3_font |
string | no | Font of the custom field 3 element: a Google font from the editor's list or one of the organisation's custom fonts; invalid fonts fall back to the default. |
box_custom_3_style |
string | no | Comma-joined text styles for the custom field 3 element: bold, italic, underline. |
box_custom_1_label |
string | no | Label of custom field 1 (max 64 characters). |
box_custom_2_label |
string | no | Label of custom field 2 (max 64 characters). |
box_custom_3_label |
string | no | Label of custom field 3 (max 64 characters). |
box_picture_enabled |
boolean | no | Show the profile-picture element on the image. |
box_picture_x |
integer | no | X position of the profile picture, in px on the source image. |
box_picture_y |
integer | no | Y position of the profile picture, in px on the source image. |
box_picture_width |
integer | no | Width of the profile picture in px. |
box_picture_height |
integer | no | Height of the profile picture in px. |
box_picture_z_index |
string | no | Whether the profile picture renders behind or in front of the image. |
box_picture_shape |
string | no | Shape of the profile picture. |
box_picture_border_color |
string | no | Border color of the profile picture as a hex value. |
box_picture_border_width |
integer | no | Border width of the profile picture in px (0-30). |
update-campaign-visual-tool
Update one of a campaign's sharing visuals: its box_* element layout and its own sharing_url / sharing_text (empty values inherit from the primary visual at share time); only the provided fields are changed. The composited preview is not regenerated (it is produced by the dashboard editor), but layout changes affect how shares are rendered.
| Input | Type | Required | Description |
|---|---|---|---|
campaign |
string | yes | The campaign id or slug. |
visual_id |
integer | yes | The id of the visual to update. |
sharing_url |
string | no | Destination URL opened when a share of this visual is clicked. Leave empty to inherit the primary visual's URL at share time. |
sharing_text |
string | no | Sharing text for this visual (max 1000 characters). Leave empty to inherit the primary visual's text. |
box_name_enabled |
boolean | no | Show the name element on the image. |
box_name_x |
integer | no | X position of the name element, in px on the source image. |
box_name_y |
integer | no | Y position of the name element, in px on the source image. |
box_name_width |
integer | no | Width of the name element in px. |
box_name_height |
integer | no | Height of the name element in px. |
box_name_text_align |
string | no | Text alignment of the name element. |
box_name_font_size |
integer | no | Font size of the name element in px (8-120). |
box_name_color |
string | no | Text color of the name element as a hex value, e.g. #ffffff. |
box_name_font |
string | no | Font of the name element: a Google font from the editor's list or one of the organisation's custom fonts; invalid fonts fall back to the default. |
box_name_style |
string | no | Comma-joined text styles for the name element: bold, italic, underline. |
box_role_enabled |
boolean | no | Show the role element on the image. |
box_role_x |
integer | no | X position of the role element, in px on the source image. |
box_role_y |
integer | no | Y position of the role element, in px on the source image. |
box_role_width |
integer | no | Width of the role element in px. |
box_role_height |
integer | no | Height of the role element in px. |
box_role_text_align |
string | no | Text alignment of the role element. |
box_role_font_size |
integer | no | Font size of the role element in px (8-120). |
box_role_color |
string | no | Text color of the role element as a hex value, e.g. #ffffff. |
box_role_font |
string | no | Font of the role element: a Google font from the editor's list or one of the organisation's custom fonts; invalid fonts fall back to the default. |
box_role_style |
string | no | Comma-joined text styles for the role element: bold, italic, underline. |
box_custom_1_enabled |
boolean | no | Show the custom field 1 element on the image. |
box_custom_1_x |
integer | no | X position of the custom field 1 element, in px on the source image. |
box_custom_1_y |
integer | no | Y position of the custom field 1 element, in px on the source image. |
box_custom_1_width |
integer | no | Width of the custom field 1 element in px. |
box_custom_1_height |
integer | no | Height of the custom field 1 element in px. |
box_custom_1_text_align |
string | no | Text alignment of the custom field 1 element. |
box_custom_1_font_size |
integer | no | Font size of the custom field 1 element in px (8-120). |
box_custom_1_color |
string | no | Text color of the custom field 1 element as a hex value, e.g. #ffffff. |
box_custom_1_font |
string | no | Font of the custom field 1 element: a Google font from the editor's list or one of the organisation's custom fonts; invalid fonts fall back to the default. |
box_custom_1_style |
string | no | Comma-joined text styles for the custom field 1 element: bold, italic, underline. |
box_custom_2_enabled |
boolean | no | Show the custom field 2 element on the image. |
box_custom_2_x |
integer | no | X position of the custom field 2 element, in px on the source image. |
box_custom_2_y |
integer | no | Y position of the custom field 2 element, in px on the source image. |
box_custom_2_width |
integer | no | Width of the custom field 2 element in px. |
box_custom_2_height |
integer | no | Height of the custom field 2 element in px. |
box_custom_2_text_align |
string | no | Text alignment of the custom field 2 element. |
box_custom_2_font_size |
integer | no | Font size of the custom field 2 element in px (8-120). |
box_custom_2_color |
string | no | Text color of the custom field 2 element as a hex value, e.g. #ffffff. |
box_custom_2_font |
string | no | Font of the custom field 2 element: a Google font from the editor's list or one of the organisation's custom fonts; invalid fonts fall back to the default. |
box_custom_2_style |
string | no | Comma-joined text styles for the custom field 2 element: bold, italic, underline. |
box_custom_3_enabled |
boolean | no | Show the custom field 3 element on the image. |
box_custom_3_x |
integer | no | X position of the custom field 3 element, in px on the source image. |
box_custom_3_y |
integer | no | Y position of the custom field 3 element, in px on the source image. |
box_custom_3_width |
integer | no | Width of the custom field 3 element in px. |
box_custom_3_height |
integer | no | Height of the custom field 3 element in px. |
box_custom_3_text_align |
string | no | Text alignment of the custom field 3 element. |
box_custom_3_font_size |
integer | no | Font size of the custom field 3 element in px (8-120). |
box_custom_3_color |
string | no | Text color of the custom field 3 element as a hex value, e.g. #ffffff. |
box_custom_3_font |
string | no | Font of the custom field 3 element: a Google font from the editor's list or one of the organisation's custom fonts; invalid fonts fall back to the default. |
box_custom_3_style |
string | no | Comma-joined text styles for the custom field 3 element: bold, italic, underline. |
box_custom_1_label |
string | no | Label of custom field 1 (max 64 characters). |
box_custom_2_label |
string | no | Label of custom field 2 (max 64 characters). |
box_custom_3_label |
string | no | Label of custom field 3 (max 64 characters). |
box_picture_enabled |
boolean | no | Show the profile-picture element on the image. |
box_picture_x |
integer | no | X position of the profile picture, in px on the source image. |
box_picture_y |
integer | no | Y position of the profile picture, in px on the source image. |
box_picture_width |
integer | no | Width of the profile picture in px. |
box_picture_height |
integer | no | Height of the profile picture in px. |
box_picture_z_index |
string | no | Whether the profile picture renders behind or in front of the image. |
box_picture_shape |
string | no | Shape of the profile picture. |
box_picture_border_color |
string | no | Border color of the profile picture as a hex value. |
box_picture_border_width |
integer | no | Border width of the profile picture in px (0-30). |
reorder-campaign-visuals-tool
Reorder a campaign's sharing visuals. Pass every visual id of the campaign exactly once, in the desired order; the first id becomes the primary visual used when the campaign is shared.
| Input | Type | Required | Description |
|---|---|---|---|
campaign |
string | yes | The campaign id or slug. |
visual_ids |
array | yes | Every visual id of the campaign exactly once, in the desired order. |
list-folders-tool
List the campaign folders in the acting organisation, sorted by name, each with its id, name and campaign count. Paged: the response carries the total count.
| Input | Type | Required | Description |
|---|---|---|---|
per_page |
integer | no | Folders per page (1-100). |
page |
integer | no | Page number (1-based) for paging through results. |
create-folder-tool
Create a new campaign folder in the acting organisation, attributed to the authenticated user. Use folders to organize campaigns; file a campaign into one by passing folder_id to create-campaign or update-campaign.
| Input | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Folder name. |
update-folder-tool
Rename one of the authenticated user's campaign folders, identified by its numeric id.
| Input | Type | Required | Description |
|---|---|---|---|
folder |
integer | yes | The folder id to update. |
name |
string | no | New folder name. |
list-organisations-tool
Report the organisation this connection acts within — its id and name — plus a has_other_memberships flag saying whether you belong to any others. It never lists the other organisations and never discloses fellow members' names or emails.
No inputs.