# MCP tools for conversion goals

Exact MCP arguments, event rules, responses, and draft behavior for creating, reading, updating, and deleting conversion goals.

Available on the Grow, Scale, and Pro plans.

Goals define which page views, clicks, and form submissions count as conversions. These tools manage goal definitions. They don't record a conversion or attach a goal to a campaign automatically. Campaign attachments use `goal_ids` in [campaign tools](https://rightmessage.com/help/mcp-tools-campaigns).

## MCP goal access and draft changes

Every tool accepts an optional `project_id`, a string containing the public project ID, and follows the [shared MCP authorization and project-selection rules](https://rightmessage.com/help/mcp-authorization-reference). An unresolved, invalid, or inaccessible project returns an MCP error.

These tools don't add a separate goal-plan check to draft edits. Publishing goals requires the project's conversion-goal entitlement. Goals that the plan cannot publish are removed from the published configuration.

Reads use the draft when one exists, otherwise the published configuration. Mutations save a draft and a pre-change snapshot. They do not publish. See [publication tools](https://rightmessage.com/help/mcp-tools-publishing).

Success values below are the JSON payload of an MCP tool result, not a REST response envelope. Errors are MCP error results. Mutation failures use `Validation error: ...` for configuration-schema failures or `Operation failed: ...` for other exceptions. Missing required IDs, names, and projects can return an error before mutation.

All examples are illustrative and were not executed. IDs identify fictional WorkForge resources. Replace them with IDs returned by your project.

## Goal and event objects

A goal result contains `id`, `name`, `isVisibleToUser`, `status`, and `events`. The input name `is_visible_to_user` becomes `isVisibleToUser` in stored and returned objects. Goal IDs begin with `gol_`. Event IDs begin with `gev_`.

Each object in the `events` array supports these properties:

| Property   | Type and behavior                                                                                                                          |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `id`       | Optional string. Preserves an existing event ID. Omission generates a new ID.                                                              |
| `type`     | String, trimmed, case-insensitive, and stored uppercase. `PAGEVIEW`, `CLICK`, or `SUBMIT`. Defaults to `CLICK`. Other values are rejected. |
| `selector` | CSS-selector string. Supply it for a usable `CLICK` or `SUBMIT` event. Not needed for `PAGEVIEW`.                                          |
| `page`     | Page target. Supply either a comma-separated `domain/path` string or an array of page-rule objects.                                        |

Each page-rule object contains `domain` and `path` strings, plus optional `operator`. Accepted operators are `equals`, `does not equal`, `contains`, `does not contain`, `starts with`, `ends with`, and `glob`. Explicit operators compare paths case-insensitively. `glob` supports `*`. Omission preserves legacy matching.

String page targets have no URL scheme. `example.com/thank-you` becomes `[{"domain":"example.com","path":"/thank-you"}]`. A domain without a path gets `path: "*"`. An empty domain before the slash becomes `"*"`. A domain and its `www.` form match each other. Other subdomains need their own targets.

Returning the event IDs and page-rule objects from `get-goal` preserves the existing rule semantics. An empty `events` array defines no conversion events. A paused goal records no conversions once that state is published.

Unsupported event types are rejected, but saving an event requires only `id` and `type`. The type-specific selector and page requirements above aren't enforced on save. A successful save is not proof that an incomplete event can match a visitor action. Unknown event properties are not copied.

## `create-goal`

Creates a draft goal.

| Argument             | Required | Type and default                                        |
| -------------------- | -------- | ------------------------------------------------------- |
| `project_id`         | No       | String. Shared project selection.                       |
| `name`               | Yes      | Nonempty string.                                        |
| `is_visible_to_user` | No       | Boolean. Defaults to `true`.                            |
| `status`             | No       | `active` or `paused`. Defaults to `active`.             |
| `events`             | No       | Array of event objects defined above. Defaults to `[]`. |

Returns the new goal object. It does not attach the goal to a campaign. Missing `name` returns `name is required.` Unsupported event types return an operation error naming the accepted types. Invalid event or page rules can fail configuration validation.

Illustrative request:

```json
{"name":"create-goal","arguments":{"name":"WorkForge signup","events":[{"type":"PAGEVIEW","page":"example.com/thank-you"}]}}
```

Illustrative result:

```json
{"id":"gol_workdemo","name":"WorkForge signup","isVisibleToUser":true,"status":"active","events":[{"id":"gev_workdemo","type":"PAGEVIEW","page":[{"domain":"example.com","path":"/thank-you"}]}]}
```

## `list-goals`

Returns every goal in the current draft-first configuration. Its only argument is optional string `project_id`. The result is an array of goal objects, or `[]` when none exist. Resolved resource-name annotations can accompany stored references. There is no pagination, date filter, or analytics calculation.

This read has no configuration side effect. Shared project and authentication errors apply.

Illustrative request and result for a project with no goals:

```json
{"name":"list-goals","arguments":{}}
```

```json
[]
```

## `get-goal`

Returns one complete goal definition, including its events and page-rule objects.

Arguments are optional string `project_id` and required string `goal_id`. The result is the goal object, with resolved resource-name annotations where applicable. This read changes no configuration.

Missing `goal_id` returns `goal_id is required.` An unknown ID returns `Goal 'ID' not found.`

Illustrative request:

```json
{"name":"get-goal","arguments":{"goal_id":"gol_workdemo"}}
```

Illustrative result:

```json
{"id":"gol_workdemo","name":"WorkForge signup","isVisibleToUser":true,"status":"active","events":[{"id":"gev_workdemo","type":"PAGEVIEW","page":[{"domain":"example.com","path":"/thank-you"}]}]}
```

## `update-goal`

Changes a draft goal. Arguments are optional string `project_id`, required string `goal_id`, and at least one of `name`, `is_visible_to_user`, `status`, or `events`. Their types match `create-goal`. Omitted fields retain their current values. Top-level `null` values are ignored, not clearing instructions.

`events` replaces the entire event array. An empty array removes all events. Event objects use the shared schema above. The tool returns the updated goal object.

Missing `goal_id` returns `goal_id is required.` Providing no non-null update fields returns `At least one field to update must be provided.` An unknown goal becomes `Operation failed: Goal 'ID' not found.` Event-type and configuration-validation errors match creation.

Illustrative request:

```json
{"name":"update-goal","arguments":{"goal_id":"gol_workdemo","status":"paused"}}
```

Illustrative result:

```json
{"id":"gol_workdemo","name":"WorkForge signup","isVisibleToUser":true,"status":"paused","events":[{"id":"gev_workdemo","type":"PAGEVIEW","page":[{"domain":"example.com","path":"/thank-you"}]}]}
```

The live goal keeps its prior status until publication.

## `delete-goal`

Deletes a goal from the draft and removes its ID from every campaign's `goal_ids` array in that draft. It does not delete those campaigns. Removing the first goal can change which remaining goal is primary for a campaign using `primary_goal`.

Arguments are optional string `project_id` and required string `goal_id`. Returns `{"deleted":true,"goal_id":"ID"}`. A missing ID returns `goal_id is required.` An unknown goal returns `Operation failed: Goal 'ID' not found.` Shared mutation-validation errors also apply.

Illustrative request and result:

```json
{"name":"delete-goal","arguments":{"goal_id":"gol_workdemo"}}
```

```json
{"deleted":true,"goal_id":"gol_workdemo"}
```

Deletion is a draft change. It does not publish or erase previously recorded conversion events.
