Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
},
"metadata": {
"description": "Official Sent skills and remote MCP integration for messaging engineering, operations, migration, and specialist channel workflows.",
"version": "0.2.1"
"version": "0.3.0"
},
"plugins": [
{
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ The plugin declares the Streamable HTTP endpoint `https://mcp.sent.dm/mcp` and e
| Sender Profiles | `sender_profiles.list`, `sender_profiles.get`, `sender_profiles.create`, `sender_profiles.update`, `sender_profiles.delete` |
| SMS compliance | `compliance.requirements`, `compliance.setup_plan` |

The MCP client performs OAuth 2.1 authorization with PKCE and Dynamic Client Registration. The user selects an organization and Sender Profile during authorization; the client stores the resulting grant. An organization grant can use a schema-supported `profileId` to act as an owned profile; profile grants cannot. `sender_profiles.*` uses target `id` and rejects acting `profileId`. Reauthorize for another organization or scope outside the grant and revoke access from **Sent Dashboard → Settings → MCP Connections**. Do not paste API keys or tokens into prompts.
The MCP client performs OAuth 2.1 authorization with PKCE and Dynamic Client Registration. The user selects an organization and Sender Profile during authorization; the client stores the resulting grant. An organization grant can use a schema-supported `profileId` to act as an owned profile; profile grants cannot. `sender_profiles.*` uses target `id` and rejects acting `profileId`. Reauthorize for another organization or scope outside the grant and revoke access by deactivating the connection's API key in **Sent Dashboard → API Keys**. Do not paste API keys or tokens into prompts.

## Mutation and data-safety contract

Expand Down Expand Up @@ -162,6 +162,8 @@ See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the public-data policy, [`docs/PUBL

The public MCP surface includes 27 tools. `messages.send` uses an existing template with all required parameters; it supports `scheduledAt` with an explicit timezone offset, from 1 minute to 30 days ahead. Acceptance is not delivery, and quiet hours can defer release.

Connections authorized through Claude's hosted connector (Claude on the web, Desktop, mobile, and Cowork) get a server-enforced policy: Sender Profile creation and deletion are unavailable and happen in the Sent Dashboard, each `messages.send` call accepts one recipient, and organization-wide send quotas apply. Other clients, including Claude Code, keep the full surface.

Feedback goes to Sent staff only with user authorization and a reviewed, sanitized report. It is limited to 2000 characters and 20 calls per authenticated account scope per UTC day, shared across acting profiles. Its note does not guarantee storage, open a support ticket, or promise a response. Number lookup is paid and limited to 1000 calls per authenticated account scope per UTC day.

Profile create and delete require `idempotencyKey`; interrupted outcomes require reconciliation before another operation. MCP update changes only name, short name, or description. Compliance setup plans create a new profile, support SMS only, and hand required document uploads to the dashboard or REST API.
Expand Down
97 changes: 97 additions & 0 deletions adapter-sources/claude/overlay.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Claude adapter overlay. generate_adapters.py applies it to claude-plugins/sent only;
# the canonical package, repository root, and Codex adapter keep the full surface.
#
# It mirrors the Sent server's policy for hosted Claude connections. It is guidance,
# not a security control: the server enforces the policy independently.
#
# withheld_tools: removed from the Claude adapter's public-surface.json.
# edits: exact find/replace on generated Claude adapter files (paths relative to
# claude-plugins/sent). Each find must match exactly once, so canonical edits that
# invalidate an overlay fail generation instead of drifting silently.

withheld_tools:
sender_profiles.create: Create Sender Profiles in the Sent Dashboard.
sender_profiles.delete: Delete Sender Profiles in the Sent Dashboard.

edits:
skills/sent-profile-provisioning/SKILL.md:
- find: |-
description: Lists, inspects, creates, updates, and deletes Sender Profiles through Sent MCP tools and executes
replace: |-
description: Lists, inspects, and updates existing Sender Profiles through Sent MCP tools, hands Sender Profile creation and deletion to the Sent Dashboard, and executes
- find: |-
Use `sender_profiles.list`, `sender_profiles.get`, `sender_profiles.create`, `sender_profiles.update`, and `sender_profiles.delete` through client-managed OAuth 2.1/PKCE.
replace: |-
Use `sender_profiles.list`, `sender_profiles.get`, and `sender_profiles.update` through client-managed OAuth 2.1/PKCE.
- find: |-
- **Create:** requires `name`, `shortName`, and `idempotencyKey`. `shortName` is 3-11 letters, numbers, or spaces with at least one letter. Optional arguments are `description`, `smsCountry`, `smsNumberType`, `smsSenderValue`, `smsAreaCodes`, and `compliance`. A supplied `smsCountry` requires `smsNumberType`; omission uses the organization's shared routes. For a dedicated SMS market, use `sent-compliance` to inspect requirements and fill its setup plan first. Provisioning can claim a number and incur registration fees. WhatsApp, RCS, billing, document uploads, inheritance flags, and sandbox arguments are not exposed by this MCP create tool. Required document uploads block it before any write; use the dashboard or documented REST flow. No one-time API key is returned.
replace: |-
- **Create:** Sender Profiles are created in the Sent Dashboard, not from Claude, because provisioning can claim a number and incur registration fees. For a dedicated SMS market, use `sent-compliance` to explain the requirements, then hand the user to the Dashboard. If the connection lists `sender_profiles.create`, do not call it.
- find: |-
- **Delete:** fetch and preview the target. Explain that deletion can disconnect WhatsApp, release numbers, and disable live routes. Supply `id` and a nonempty `idempotencyKey`. `deleted: false` means no matching owned profile was deleted and does not prove another tenant's profile exists.
replace: |-
- **Delete:** Sender Profiles are deleted in the Sent Dashboard, not from Claude, because deletion can disconnect WhatsApp, release numbers, and disable live routes. If the connection lists `sender_profiles.delete`, do not call it.
- find: |-
For every create, update, or delete, preview
replace: |-
For every update, preview
- find: |-
Create and delete use durable receipts. Reuse the original key and arguments for the same intended operation; do not generate a new key after a timeout or an in-flight result. Inspect list/get and returned receipt guidance first. A key reused with different arguments is refused. If interrupted provisioning or teardown needs attention, stop and reconcile in the dashboard rather than retry automatically or replace the key. A new key authorizes a separate operation only after the existing outcome has been reconciled. Verify the returned profile and channel readiness; creation alone does not establish permission to send.
replace: |-
If provisioning or teardown started in the Dashboard looks incomplete, inspect it with list/get and reconcile it in the Dashboard. Profile creation alone does not establish permission to send.
- find: |-
The following `/v3/profiles` guidance describes the legacy REST lifecycle
replace: |-
From Claude, use the REST guidance below to write or review the user's application code; do not run profile-creating or profile-deleting requests on the user's behalf. The following `/v3/profiles` guidance describes the legacy REST lifecycle

skills/sent-compliance/SKILL.md:
- find: |-
3. Call `compliance.setup_plan` when the user needs the exact setup call. Its `call.tool` is `sender_profiles.create`, with camelCase argument names and null placeholders that must be filled before execution. Do not execute blank values or translate the plan into an invented REST call.
replace: |-
3. Call `compliance.setup_plan` when the user needs the setup steps for a market. From Claude, Sender Profiles are provisioned in the Sent Dashboard: present the plan's requirements, and when it returns a Dashboard handoff, give the user that link. If the plan contains a `call` that would create a Sender Profile, do not call `sender_profiles.create`; hand the setup to the Dashboard. Do not translate the plan into an invented REST call.
- find: |-
Required uploads cannot be carried through MCP; do not attempt a guaranteed-to-fail create.
replace: |-
Required uploads cannot be carried through MCP.
- find: |-
5. When setup can proceed, hand the completed plan to `sent-profile-provisioning` for scope validation, required idempotency key, payload preview, and explicit confirmation before creation.
replace: |-
5. When setup can proceed, direct the user to finish provisioning in the Sent Dashboard with the requirements you gathered.
- find: |-
The plan creates a new profile.
replace: |-
The plan describes a new profile, which the user creates in the Sent Dashboard.

skills/sent/SKILL.md:
- find: |-
| List, get, create, update, or delete owned Sender Profiles through MCP | `sent-profile-provisioning` |
replace: |-
| List, get, or update owned Sender Profiles through MCP, or hand creation and deletion to the Sent Dashboard | `sent-profile-provisioning` |

skills/sent-messaging/SKILL.md:
- find: |
Never call `messages.send` without the preview and explicit confirmation immediately before the call.
replace: |
Never call `messages.send` without the preview and explicit confirmation immediately before the call.

From Claude, send to exactly one recipient per call. Do not loop over a list or split recipients across repeated calls to reach many people; for bulk or campaign sends, direct the user to the Sent Dashboard or the REST API in their own application. If Sent returns a connection-policy or send-quota error, stop and report it with any retry time; do not retry automatically.

skills/sms-10dlc-registration/SKILL.md:
- find: |-
Its plan creates a new Sender Profile and does not manage campaigns on an existing profile.
replace: |-
From Claude, its plan is completed by creating the Sender Profile in the Sent Dashboard; it does not manage campaigns on an existing profile.

README.md:
- find: |-
- Sender Profiles: `sender_profiles.list`, `.get`, `.create`, `.update`, and `.delete`; and
replace: |-
- Sender Profiles: `sender_profiles.list`, `.get`, and `.update`, with creation and deletion in the Sent Dashboard; and
- find: |-
The public MCP surface includes 27 tools.
replace: |-
The public MCP surface includes 27 tools; this Claude plugin documents the 25 available to Claude connections.
- find: |-
Profile create and delete require `idempotencyKey`; interrupted outcomes require reconciliation before another operation. MCP update changes only name, short name, or description. Compliance setup plans create a new profile, support SMS only, and hand required document uploads to the dashboard or REST API.
replace: |-
Sender Profiles are created and deleted in the Sent Dashboard. MCP update changes only name, short name, or description. Compliance setup plans describe a new SMS profile and hand provisioning and required document uploads to the Dashboard.
4 changes: 3 additions & 1 deletion adapter-sources/shared/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ npx skills add https://github.com/sentdm/sent-plugin --skill sent

## MCP and authorization

The adapter connects only to `https://mcp.sent.dm/mcp`. The MCP client performs OAuth 2.1 with PKCE and Dynamic Client Registration; no credentials or credential placeholders are included. The grant is tied to the organization and Sender Profile selected during authorization. An organization grant can use a schema-supported `profileId` to act as an owned profile; profile grants cannot. `sender_profiles.*` uses target `id` and rejects acting `profileId`. Reauthorize for another organization or scope outside the grant and revoke access from **Sent Dashboard → Settings → MCP Connections**.
The adapter connects only to `https://mcp.sent.dm/mcp`. The MCP client performs OAuth 2.1 with PKCE and Dynamic Client Registration; no credentials or credential placeholders are included. The grant is tied to the organization and Sender Profile selected during authorization. An organization grant can use a schema-supported `profileId` to act as an owned profile; profile grants cannot. `sender_profiles.*` uses target `id` and rejects acting `profileId`. Reauthorize for another organization or scope outside the grant and revoke access by deactivating the connection's API key in **Sent Dashboard → API Keys**.

MCP-backed live operations cover:

Expand All @@ -62,6 +62,8 @@ This directory is generated. Make source changes in `packages/sent` or `adapter-

The public MCP surface includes 27 tools. `messages.send` uses an existing template with all required parameters; it supports `scheduledAt` with an explicit timezone offset, from 1 minute to 30 days ahead. Acceptance is not delivery, and quiet hours can defer release.

Connections authorized through Claude's hosted connector (Claude on the web, Desktop, mobile, and Cowork) get a server-enforced policy: Sender Profile creation and deletion are unavailable and happen in the Sent Dashboard, each `messages.send` call accepts one recipient, and organization-wide send quotas apply. Other clients, including Claude Code, keep the full surface.

Feedback goes to Sent staff only with user authorization and a reviewed, sanitized report. It is limited to 2000 characters and 20 calls per authenticated account scope per UTC day, shared across acting profiles. Its note does not guarantee storage, open a support ticket, or promise a response. Number lookup is paid and limited to 1000 calls per authenticated account scope per UTC day.

Profile create and delete require `idempotencyKey`; interrupted outcomes require reconciliation before another operation. MCP update changes only name, short name, or description. Compliance setup plans create a new profile, support SMS only, and hand required document uploads to the dashboard or REST API.
Expand Down
2 changes: 1 addition & 1 deletion claude-plugins/sent/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sent",
"version": "0.2.1",
"version": "0.3.0",
"description": "Official Sent plugin for SMS, WhatsApp, RCS, scheduled template sends, Sender Profiles, SMS compliance, authorized feedback, contacts, analytics, API integration, webhooks, routing, and migration.",
"author": {
"name": "Sent",
Expand Down
10 changes: 6 additions & 4 deletions claude-plugins/sent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ npx skills add https://github.com/sentdm/sent-plugin --skill sent

## MCP and authorization

The adapter connects only to `https://mcp.sent.dm/mcp`. The MCP client performs OAuth 2.1 with PKCE and Dynamic Client Registration; no credentials or credential placeholders are included. The grant is tied to the organization and Sender Profile selected during authorization. An organization grant can use a schema-supported `profileId` to act as an owned profile; profile grants cannot. `sender_profiles.*` uses target `id` and rejects acting `profileId`. Reauthorize for another organization or scope outside the grant and revoke access from **Sent Dashboard → Settings → MCP Connections**.
The adapter connects only to `https://mcp.sent.dm/mcp`. The MCP client performs OAuth 2.1 with PKCE and Dynamic Client Registration; no credentials or credential placeholders are included. The grant is tied to the organization and Sender Profile selected during authorization. An organization grant can use a schema-supported `profileId` to act as an owned profile; profile grants cannot. `sender_profiles.*` uses target `id` and rejects acting `profileId`. Reauthorize for another organization or scope outside the grant and revoke access by deactivating the connection's API key in **Sent Dashboard → API Keys**.

MCP-backed live operations cover:

Expand All @@ -47,7 +47,7 @@ MCP-backed live operations cover:
- analytics: number lookup, message volume, deliverability, and contact metrics; and
- account: account details, balance, and onboarding status;
- feedback: user-authorized reports to Sent with `feedback.send`;
- Sender Profiles: `sender_profiles.list`, `.get`, `.create`, `.update`, and `.delete`; and
- Sender Profiles: `sender_profiles.list`, `.get`, and `.update`, with creation and deletion in the Sent Dashboard; and
- SMS compliance: `compliance.requirements` and `compliance.setup_plan`.

Mutating workflows preview the exact scope and payload, then require explicit confirmation immediately before execution. They do not retry ambiguous sends blindly and do not equate an accepted message with delivery.
Expand All @@ -60,11 +60,13 @@ This directory is generated. Make source changes in `packages/sent` or `adapter-

## Additional MCP behavior

The public MCP surface includes 27 tools. `messages.send` uses an existing template with all required parameters; it supports `scheduledAt` with an explicit timezone offset, from 1 minute to 30 days ahead. Acceptance is not delivery, and quiet hours can defer release.
The public MCP surface includes 27 tools; this Claude plugin documents the 25 available to Claude connections. `messages.send` uses an existing template with all required parameters; it supports `scheduledAt` with an explicit timezone offset, from 1 minute to 30 days ahead. Acceptance is not delivery, and quiet hours can defer release.

Connections authorized through Claude's hosted connector (Claude on the web, Desktop, mobile, and Cowork) get a server-enforced policy: Sender Profile creation and deletion are unavailable and happen in the Sent Dashboard, each `messages.send` call accepts one recipient, and organization-wide send quotas apply. Other clients, including Claude Code, keep the full surface.

Feedback goes to Sent staff only with user authorization and a reviewed, sanitized report. It is limited to 2000 characters and 20 calls per authenticated account scope per UTC day, shared across acting profiles. Its note does not guarantee storage, open a support ticket, or promise a response. Number lookup is paid and limited to 1000 calls per authenticated account scope per UTC day.

Profile create and delete require `idempotencyKey`; interrupted outcomes require reconciliation before another operation. MCP update changes only name, short name, or description. Compliance setup plans create a new profile, support SMS only, and hand required document uploads to the dashboard or REST API.
Sender Profiles are created and deleted in the Sent Dashboard. MCP update changes only name, short name, or description. Compliance setup plans describe a new SMS profile and hand provisioning and required document uploads to the Dashboard.

Dashboard volume counts delivered/read outbound SMS and WhatsApp over supported windows; deliverability is an all-time outbound percentage including SENT, and contacts is a current total. Do not claim unsupported date filters or trends.

Expand Down
10 changes: 0 additions & 10 deletions claude-plugins/sent/public-surface.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,6 @@
"mutation": "read_only",
"confirmation_required": false
},
"sender_profiles.create": {
"owner": "sent-profile-provisioning",
"mutation": "state_changing",
"confirmation_required": true
},
"sender_profiles.delete": {
"owner": "sent-profile-provisioning",
"mutation": "destructive",
"confirmation_required": true
},
"sender_profiles.get": {
"owner": "sent-profile-provisioning",
"mutation": "read_only",
Expand Down
Loading