From 039bfe6a1e16e2dd3641d075f5fa349466528d71 Mon Sep 17 00:00:00 2001 From: Joel Horwitz Date: Thu, 1 Oct 2026 16:23:36 -0700 Subject: [PATCH 1/3] chore(cursor): marketplace review fixes - Remove root plugin.json symlink (read as a 26-byte text path by non-symlink-aware indexers) - Drop Cursor sessionStart shell hook; move the operator primer into rules/synter-operator.mdc (alwaysApply) - Logo referenced by relative path - Add SECURITY.md --- .cursor-plugin/marketplace.json | 2 +- .cursor-plugin/plugin.json | 4 ++-- SECURITY.md | 19 +++++++++++++++++++ hooks/cursor-hooks.json | 9 --------- plugin.json | 1 - rules/synter-operator.mdc | 14 ++++++++++++++ 6 files changed, 36 insertions(+), 13 deletions(-) create mode 100644 SECURITY.md delete mode 100644 hooks/cursor-hooks.json delete mode 120000 plugin.json create mode 100644 rules/synter-operator.mdc diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json index 1f2df9c..b41fc54 100644 --- a/.cursor-plugin/marketplace.json +++ b/.cursor-plugin/marketplace.json @@ -12,7 +12,7 @@ { "name": "synter", "source": ".", - "logo": "https://raw.githubusercontent.com/Synter-Media-AI/plugin/main/assets/logo.png", + "logo": "assets/logo.png", "description": "The AI Agent Operator for Ads. Connect 21 ad platforms, build audiences, generate on-brand creative, launch cross-platform campaigns, and reallocate spend by ROAS — one conversation, every platform. You direct, the agents execute. Nothing that spends money ships without your approval." } ] diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index b1e2018..ea3bd58 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -11,7 +11,7 @@ "homepage": "https://syntermedia.ai", "repository": "https://github.com/Synter-Media-AI/plugin", "license": "MIT", - "logo": "https://raw.githubusercontent.com/Synter-Media-AI/plugin/main/assets/logo.png", + "logo": "assets/logo.png", "keywords": [ "ads", "advertising", @@ -28,7 +28,7 @@ ], "skills": "./skills/", "agents": "./agents/", - "hooks": "./hooks/cursor-hooks.json", + "rules": "./rules/", "mcpServers": "./mcp.json", "variables": { "type": "object", diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..d3bef89 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,19 @@ +# Security + +## Reporting a vulnerability + +Email **joel@synterai.com** with the subject "Security: Synter plugin". Please include steps to reproduce. We'll acknowledge within 2 business days. Please don't open public issues for vulnerabilities. + +## What this plugin does + +- It contains Markdown skills, agents, and rules, plus one remote MCP server entry. It ships no executable hooks for Cursor. +- The MCP server is Synter's hosted server over HTTPS. Cursor authenticates with browser OAuth (scopes `tools:read` and `tools:write`). An API key is an optional fallback for headless use and is never stored in this repo. + +## Spend and write safety + +- Anything that spends money, launches campaigns, or changes budgets requires explicit user approval before it runs. Reads (`list_*`, `get_*`, reports) don't. +- Actions run only against ad accounts the user has connected and authorized in Synter. + +## Data handling + +Synter processes ad-account data only to perform the actions you request. See the [Privacy Policy](https://syntermedia.ai/privacy), [Terms](https://syntermedia.ai/terms), and [Security overview](https://syntermedia.ai/security). diff --git a/hooks/cursor-hooks.json b/hooks/cursor-hooks.json deleted file mode 100644 index 9b1fa2d..0000000 --- a/hooks/cursor-hooks.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "hooks": { - "sessionStart": [ - { - "command": "./scripts/session-context.sh" - } - ] - } -} diff --git a/plugin.json b/plugin.json deleted file mode 120000 index e22f3da..0000000 --- a/plugin.json +++ /dev/null @@ -1 +0,0 @@ -.claude-plugin/plugin.json \ No newline at end of file diff --git a/rules/synter-operator.mdc b/rules/synter-operator.mdc new file mode 100644 index 0000000..3a8bab8 --- /dev/null +++ b/rules/synter-operator.mdc @@ -0,0 +1,14 @@ +--- +description: Synter operator rules and money-safety guardrails for ad platform work +alwaysApply: true +--- + +You are the Synter operator — the AI Agent Operator for Ads. You direct, the agents execute. +Operating rules: +- MONEY SAFETY RULES: Nothing that spends money ships without explicit user approval. No exceptions, no tier carve-outs. +- Default to recommend-then-execute: propose the plan (platform, budget, audience, creative), show it, and wait for an explicit yes before any create/enable/budget/launch/pause call. +- Reads are free: list_*, get_*, pull_*, verify_*, and reports run without asking. +- Confirm the org/account before any write (list_connected_accounts). Never run one org's campaigns through another's credentials or session. Use real IDs the tools return — never invent them. +- "Created" != "live and spending" — verify before claiming. +- Brand voice: terse, certain, doing the work. Show, don't sell. No banned language (no "AI-Powered", "seamless", "beta", hype CTAs). Never fabricate prices, competitors, or stats. +- Get started or get help: /synter:quickstart and /synter:help. From 454e7434ab8165fa99059298555f89fcb3a2f511 Mon Sep 17 00:00:00 2001 From: Joel Horwitz Date: Thu, 1 Oct 2026 16:29:45 -0700 Subject: [PATCH 2/3] docs(rules): drop 'free' wording from operator rule --- rules/synter-operator.mdc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/synter-operator.mdc b/rules/synter-operator.mdc index 3a8bab8..00f66c6 100644 --- a/rules/synter-operator.mdc +++ b/rules/synter-operator.mdc @@ -7,7 +7,7 @@ You are the Synter operator — the AI Agent Operator for Ads. You direct, the a Operating rules: - MONEY SAFETY RULES: Nothing that spends money ships without explicit user approval. No exceptions, no tier carve-outs. - Default to recommend-then-execute: propose the plan (platform, budget, audience, creative), show it, and wait for an explicit yes before any create/enable/budget/launch/pause call. -- Reads are free: list_*, get_*, pull_*, verify_*, and reports run without asking. +- Reads run without asking: list_*, get_*, pull_*, verify_*, and reports. - Confirm the org/account before any write (list_connected_accounts). Never run one org's campaigns through another's credentials or session. Use real IDs the tools return — never invent them. - "Created" != "live and spending" — verify before claiming. - Brand voice: terse, certain, doing the work. Show, don't sell. No banned language (no "AI-Powered", "seamless", "beta", hype CTAs). Never fabricate prices, competitors, or stats. From d3e06b3f8769b74a8a7260955c79593e204fa200 Mon Sep 17 00:00:00 2001 From: Joel Horwitz Date: Thu, 1 Oct 2026 16:30:07 -0700 Subject: [PATCH 3/3] docs(cursor): drop 'free' wording from API key variable --- .cursor-plugin/plugin.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index ea3bd58..4d926cd 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -36,7 +36,7 @@ "SYNTER_API_KEY": { "type": "string", "title": "Synter API key", - "description": "Optional for onboarding. Paste your syn_... key from syntermedia.ai/developer to use connected ad accounts. Leave blank to run /synter:quickstart and the free GA4 tools." + "description": "Optional for onboarding. Paste your syn_... key from syntermedia.ai/developer to use connected ad accounts. Leave blank to run /synter:quickstart and the GA4 tools." } } }