@sendraven/mcp 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -82,7 +82,7 @@ hold. The tools respect all three. See
82
82
  ## Tools
83
83
 
84
84
  <!-- tools:start -->
85
- 47 tools, generated from the server's registry.
85
+ 49 tools, generated from the server's registry.
86
86
 
87
87
  | Tool | What it does |
88
88
  | --- | --- |
@@ -96,11 +96,13 @@ hold. The tools respect all three. See
96
96
  | `list_suppressions` | List addresses we refuse to mail and why (hard_bounce, complaint, unsubscribe, manual). Check here first when someone reports not receiving email. |
97
97
  | `add_suppression` | Stop sending to an address. Scope 'marketing' leaves transactional mail working. |
98
98
  | `remove_suppression` | Remove a suppression so the address can be mailed again. Be careful with hard bounces — the address was rejected by the receiving server, and re-sending raises the bounce rate that AWS enforces on. |
99
- | `get_broadcast` | One campaign, with a 'progress' object while it is sending or paused: how many addresses are still pending, sent, failed, or skipped because the person opted out after the campaign started. This is how you tell a paused campaign that is still making progress from one waiting on quota. |
100
- | `list_broadcasts` | List campaigns with their status and send progress. A campaign showing 'paused' is not broken: it ran out of the day's sending quota part way and is waiting to continue. Use get_broadcast to see how much is left, and resume_broadcast to continue it now. |
101
- | `preview_broadcast` | How many contacts a campaign would reach, and whether the reputation gate would allow it. Always run this before sending it is the only way to see the size of a campaign without starting it. |
102
- | `resume_broadcast` | Continue a campaign left 'paused' by the daily sending quota. It mails only the addresses still pendingthe audience was frozen when the campaign started and everyone already reached is marked so calling this twice cannot double-send. Only works on a paused campaign; anything else answers 409. A background worker also resumes paused campaigns on its own once quota frees up, so use this only when waiting is not acceptable. |
103
- | `send_broadcast` | Send a campaign now, or schedule it with scheduled_at. This mails every contact in the segment and cannot be undone once started — run preview_broadcast first. A campaign bigger than the day's remaining quota is not rejected: it sends what it can and stops as 'paused', then continues later. That is expected, not an error to retry. |
99
+ | `create_broadcast` | Create a campaign as a draft. Nothing is sent: follow with preview_broadcast, then send_broadcast. identity_id must be a marketing sending domain (see list_sending_domains; risk_class 'marketing'). To A/B test, pass 2 to 10 'variants' that differ in subject, from_name or send_at, and optionally 'ab_test'. A subject or from-name test sends sample_share of the audience (default 0.2) split evenly across the variants, waits decide_after_minutes (default 240) after the sample is out, picks the variant with the best unique open rate (or click rate with metric 'click'), and sends the rest to it. Each variant needs at least 100 recipients in the sample or the send is refused preview_broadcast shows the number. Metric 'click' only works once the domain has click tracking; until then every variant shows zero clicks and the first variant wins by default. |
100
+ | `get_broadcast` | One campaign, with a 'progress' object while it is sending, paused or testing: how many addresses are still pending, sent, failed, or skipped because the person opted out after the campaign started. This is how you tell a paused campaign that is still making progress from one waiting on quota. An A/B test carries 'ab_test' with live per-variant results sent, unique opens, unique clicks and their rates — plus 'decide_at' and, once decided, 'winner' and 'decided_by'. Status 'testing' means the sample is out and the rest of the audience is waiting on the decision. |
101
+ | `list_broadcasts` | List campaigns with their status and send progress. A campaign showing 'paused' is not broken: it ran out of the day's sending quota part way and is waiting to continue. One showing 'testing' is an A/B test whose sample has gone out and whose winner is not yet decided. Use get_broadcast to see how much is left or how each variant is doing, and resume_broadcast to continue a paused one now. |
102
+ | `preview_broadcast` | How many contacts a campaign would reach, and whether the reputation gate would allow it. Always run this before sendingit is the only way to see the size of a campaign without starting it. For an A/B test it also reports the sample size and per-variant count against the 100-per-variant floor; a send below the floor is refused. |
103
+ | `send_broadcast` | Send a campaign now, or schedule it with scheduled_at. This mails every contact in the segment and cannot be undone once started — run preview_broadcast first. A campaign bigger than the day's remaining quota is not rejected: it sends what it can and stops as 'paused', then continues later. That is expected, not an error to retry. An A/B test sends its sample, goes to 'testing', and sends the rest to the winner after decide_after_minutes or when pick_broadcast_winner is called. A send-time test is scheduled by its variants' send_at and does not accept scheduled_at. |
104
+ | `pick_broadcast_winner` | Decide an A/B test now instead of waiting for decide_at. Pass 'variant' to choose a key yourself, or omit it to have the metric decide on the figures so far. The rest of the audience is then sent to the winner and cannot be redirected. Only a campaign in status 'testing' can be decided; anything else answers 409. Read get_broadcast first — a variant with a handful of opens more is not a result, and the worker decides on its own at decide_at. |
105
+ | `resume_broadcast` | Continue a campaign left 'paused' by the daily sending quota. It mails only the addresses still pending — the audience was frozen when the campaign started and everyone already reached is marked — so calling this twice cannot double-send. Only works on a paused campaign; anything else answers 409. A background worker also resumes paused campaigns on its own once quota frees up, so use this only when waiting is not acceptable. An A/B test paused mid-sample resumes the sample; one paused after the decision resumes the winner. |
104
106
  | `list_threads` | List email conversations. Pass awaiting_reply=true to get only the threads where someone has written to you and you haven't answered — this is the tool to poll when deciding what needs a response. |
105
107
  | `get_thread` | Read a conversation as a chronological transcript of outbound and inbound messages. Inbound text already has quoted history and signatures stripped, so read `text`; `raw_text` holds the untrimmed body if the stripped version looks wrong. Check spf_verdict and dkim_verdict before trusting a reply's claimed sender. |
106
108
  | `reply_to_message` | Reply to a message, keeping it on the same conversation. Sets the threading headers so the recipient's mail client shows it as part of the existing exchange rather than a new one. Prefer this over send_email whenever you are answering something. |
@@ -1,40 +1,122 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sendBroadcastTool = exports.resumeBroadcastTool = exports.getBroadcastTool = exports.previewBroadcastTool = exports.listBroadcastsTool = void 0;
3
+ exports.sendBroadcastTool = exports.resumeBroadcastTool = exports.pickBroadcastWinnerTool = exports.getBroadcastTool = exports.previewBroadcastTool = exports.createBroadcastTool = exports.listBroadcastsTool = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const client_1 = require("../client");
6
6
  exports.listBroadcastsTool = {
7
7
  name: "list_broadcasts",
8
8
  description: "List campaigns with their status and send progress. A campaign showing 'paused' is not " +
9
- "broken: it ran out of the day's sending quota part way and is waiting to continue. Use " +
10
- "get_broadcast to see how much is left, and resume_broadcast to continue it now.",
9
+ "broken: it ran out of the day's sending quota part way and is waiting to continue. One " +
10
+ "showing 'testing' is an A/B test whose sample has gone out and whose winner is not yet " +
11
+ "decided. Use get_broadcast to see how much is left or how each variant is doing, and " +
12
+ "resume_broadcast to continue a paused one now.",
11
13
  schema: {},
12
14
  handler: async () => (0, client_1.request)("GET", "/v1/broadcasts"),
13
15
  };
16
+ const variantSchema = zod_1.z.object({
17
+ key: zod_1.z
18
+ .string()
19
+ .describe("Your name for this variant, lowercase letters, digits, - or _: 'urgent', 'question'"),
20
+ subject: zod_1.z.string().optional().describe("Subject for this variant; omit to use the campaign's"),
21
+ from_name: zod_1.z.string().optional().describe("From display name for this variant; omit to use the campaign's"),
22
+ send_at: zod_1.z
23
+ .string()
24
+ .optional()
25
+ .describe("ISO 8601 send time, for a send-time test only. Set it on every variant or on none; a " +
26
+ "send-time test mails the whole audience, each variant at its own time, with nothing held back"),
27
+ });
28
+ exports.createBroadcastTool = {
29
+ name: "create_broadcast",
30
+ description: "Create a campaign as a draft. Nothing is sent: follow with preview_broadcast, then " +
31
+ "send_broadcast. identity_id must be a marketing sending domain (see list_sending_domains; " +
32
+ "risk_class 'marketing'). To A/B test, pass 2 to 10 'variants' that differ in subject, " +
33
+ "from_name or send_at, and optionally 'ab_test'. A subject or from-name test sends " +
34
+ "sample_share of the audience (default 0.2) split evenly across the variants, waits " +
35
+ "decide_after_minutes (default 240) after the sample is out, picks the variant with the " +
36
+ "best unique open rate (or click rate with metric 'click'), and sends the rest to it. " +
37
+ "Each variant needs at least 100 recipients in the sample or the send is refused — " +
38
+ "preview_broadcast shows the number. Metric 'click' only works once the domain has click " +
39
+ "tracking; until then every variant shows zero clicks and the first variant wins by default.",
40
+ schema: {
41
+ audience_id: zod_1.z.string(),
42
+ identity_id: zod_1.z.string().describe("A marketing sending domain's id"),
43
+ name: zod_1.z.string(),
44
+ subject: zod_1.z.string(),
45
+ html: zod_1.z.string(),
46
+ from_name: zod_1.z.string().optional().describe("From display name, e.g. 'Ana at Example'"),
47
+ topic_key: zod_1.z.string().optional().describe("Lets recipients opt out of this kind of mail only"),
48
+ segment_id: zod_1.z.string().optional().describe("A saved segment to narrow the audience"),
49
+ segment: zod_1.z
50
+ .object({
51
+ opened_within_days: zod_1.z.number().int().optional(),
52
+ clicked_within_days: zod_1.z.number().int().optional(),
53
+ exclude_unengaged_days: zod_1.z.number().int().optional(),
54
+ })
55
+ .optional(),
56
+ variants: zod_1.z.array(variantSchema).min(2).max(10).optional(),
57
+ ab_test: zod_1.z
58
+ .object({
59
+ metric: zod_1.z.enum(["open", "click"]).optional().describe("What decides the winner; default 'open'"),
60
+ sample_share: zod_1.z
61
+ .number()
62
+ .optional()
63
+ .describe("Share of the audience in the test, 0.05 to 1; default 0.2. Ignored for a send-time test"),
64
+ decide_after_minutes: zod_1.z
65
+ .number()
66
+ .int()
67
+ .optional()
68
+ .describe("How long after the sample is fully sent to decide; 15 to 10080, default 240"),
69
+ })
70
+ .optional(),
71
+ },
72
+ handler: async (args) => (0, client_1.request)("POST", "/v1/broadcasts", args),
73
+ };
14
74
  exports.previewBroadcastTool = {
15
75
  name: "preview_broadcast",
16
76
  description: "How many contacts a campaign would reach, and whether the reputation gate would allow it. " +
17
77
  "Always run this before sending — it is the only way to see the size of a campaign without " +
18
- "starting it.",
78
+ "starting it. For an A/B test it also reports the sample size and per-variant count " +
79
+ "against the 100-per-variant floor; a send below the floor is refused.",
19
80
  schema: { id: zod_1.z.string() },
20
81
  handler: async (args) => (0, client_1.request)("GET", `/v1/broadcasts/${args.id}/preview`),
21
82
  };
22
83
  exports.getBroadcastTool = {
23
84
  name: "get_broadcast",
24
- description: "One campaign, with a 'progress' object while it is sending or paused: how many addresses " +
25
- "are still pending, sent, failed, or skipped because the person opted out after the " +
26
- "campaign started. This is how you tell a paused campaign that is still making progress " +
27
- "from one waiting on quota.",
85
+ description: "One campaign, with a 'progress' object while it is sending, paused or testing: how many " +
86
+ "addresses are still pending, sent, failed, or skipped because the person opted out after " +
87
+ "the campaign started. This is how you tell a paused campaign that is still making " +
88
+ "progress from one waiting on quota. An A/B test carries 'ab_test' with live per-variant " +
89
+ "results — sent, unique opens, unique clicks and their rates — plus 'decide_at' and, once " +
90
+ "decided, 'winner' and 'decided_by'. Status 'testing' means the sample is out and the rest " +
91
+ "of the audience is waiting on the decision.",
28
92
  schema: { id: zod_1.z.string() },
29
93
  handler: async (args) => (0, client_1.request)("GET", `/v1/broadcasts/${args.id}`),
30
94
  };
95
+ exports.pickBroadcastWinnerTool = {
96
+ name: "pick_broadcast_winner",
97
+ description: "Decide an A/B test now instead of waiting for decide_at. Pass 'variant' to choose a key " +
98
+ "yourself, or omit it to have the metric decide on the figures so far. The rest of the " +
99
+ "audience is then sent to the winner and cannot be redirected. Only a campaign in status " +
100
+ "'testing' can be decided; anything else answers 409. Read get_broadcast first — a " +
101
+ "variant with a handful of opens more is not a result, and the worker decides on its own " +
102
+ "at decide_at.",
103
+ schema: {
104
+ id: zod_1.z.string(),
105
+ variant: zod_1.z.string().optional().describe("Variant key to send the remainder to; omit to let the metric decide"),
106
+ },
107
+ handler: async (args) => {
108
+ const { id, ...body } = args;
109
+ return (0, client_1.request)("POST", `/v1/broadcasts/${id}/winner`, body);
110
+ },
111
+ };
31
112
  exports.resumeBroadcastTool = {
32
113
  name: "resume_broadcast",
33
114
  description: "Continue a campaign left 'paused' by the daily sending quota. It mails only the addresses " +
34
115
  "still pending — the audience was frozen when the campaign started and everyone already " +
35
116
  "reached is marked — so calling this twice cannot double-send. Only works on a paused " +
36
117
  "campaign; anything else answers 409. A background worker also resumes paused campaigns on " +
37
- "its own once quota frees up, so use this only when waiting is not acceptable.",
118
+ "its own once quota frees up, so use this only when waiting is not acceptable. An A/B test " +
119
+ "paused mid-sample resumes the sample; one paused after the decision resumes the winner.",
38
120
  schema: { id: zod_1.z.string() },
39
121
  handler: async (args) => (0, client_1.request)("POST", `/v1/broadcasts/${args.id}/resume`),
40
122
  };
@@ -43,7 +125,10 @@ exports.sendBroadcastTool = {
43
125
  description: "Send a campaign now, or schedule it with scheduled_at. This mails every contact in the " +
44
126
  "segment and cannot be undone once started — run preview_broadcast first. A campaign bigger " +
45
127
  "than the day's remaining quota is not rejected: it sends what it can and stops as 'paused', " +
46
- "then continues later. That is expected, not an error to retry.",
128
+ "then continues later. That is expected, not an error to retry. An A/B test sends its " +
129
+ "sample, goes to 'testing', and sends the rest to the winner after decide_after_minutes " +
130
+ "or when pick_broadcast_winner is called. A send-time test is scheduled by its variants' " +
131
+ "send_at and does not accept scheduled_at.",
47
132
  schema: {
48
133
  id: zod_1.z.string(),
49
134
  scheduled_at: zod_1.z.string().optional().describe("ISO 8601 timestamp; omit to send now"),
@@ -1 +1 @@
1
- {"version":3,"file":"broadcasts.js","sourceRoot":"","sources":["../../src/tools/broadcasts.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AACxB,sCAAoC;AAEvB,QAAA,kBAAkB,GAAG;IAChC,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACT,yFAAyF;QACzF,yFAAyF;QACzF,iFAAiF;IACnF,MAAM,EAAE,EAAE;IACV,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,IAAA,gBAAO,EAAC,KAAK,EAAE,gBAAgB,CAAC;CACtD,CAAC;AAEW,QAAA,oBAAoB,GAAG;IAClC,IAAI,EAAE,mBAAmB;IACzB,WAAW,EACT,4FAA4F;QAC5F,4FAA4F;QAC5F,cAAc;IAChB,MAAM,EAAE,EAAE,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE;IAC1B,OAAO,EAAE,KAAK,EAAE,IAA6B,EAAE,EAAE,CAC/C,IAAA,gBAAO,EAAC,KAAK,EAAE,kBAAkB,IAAI,CAAC,EAAE,UAAU,CAAC;CACtD,CAAC;AAEW,QAAA,gBAAgB,GAAG;IAC9B,IAAI,EAAE,eAAe;IACrB,WAAW,EACT,2FAA2F;QAC3F,qFAAqF;QACrF,yFAAyF;QACzF,4BAA4B;IAC9B,MAAM,EAAE,EAAE,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE;IAC1B,OAAO,EAAE,KAAK,EAAE,IAA6B,EAAE,EAAE,CAAC,IAAA,gBAAO,EAAC,KAAK,EAAE,kBAAkB,IAAI,CAAC,EAAE,EAAE,CAAC;CAC9F,CAAC;AAEW,QAAA,mBAAmB,GAAG;IACjC,IAAI,EAAE,kBAAkB;IACxB,WAAW,EACT,4FAA4F;QAC5F,yFAAyF;QACzF,uFAAuF;QACvF,4FAA4F;QAC5F,+EAA+E;IACjF,MAAM,EAAE,EAAE,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE;IAC1B,OAAO,EAAE,KAAK,EAAE,IAA6B,EAAE,EAAE,CAC/C,IAAA,gBAAO,EAAC,MAAM,EAAE,kBAAkB,IAAI,CAAC,EAAE,SAAS,CAAC;CACtD,CAAC;AAEW,QAAA,iBAAiB,GAAG;IAC/B,IAAI,EAAE,gBAAgB;IACtB,WAAW,EACT,yFAAyF;QACzF,6FAA6F;QAC7F,8FAA8F;QAC9F,gEAAgE;IAClE,MAAM,EAAE;QACN,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE;QACd,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;KACrF;IACD,OAAO,EAAE,KAAK,EAAE,IAA6B,EAAE,EAAE;QAC/C,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;QAC7B,OAAO,IAAA,gBAAO,EAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5D,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"broadcasts.js","sourceRoot":"","sources":["../../src/tools/broadcasts.ts"],"names":[],"mappings":"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"}
@@ -32,11 +32,13 @@ exports.TOOLS = [
32
32
  suppressions_1.listSuppressionsTool,
33
33
  suppressions_1.addSuppressionTool,
34
34
  suppressions_1.removeSuppressionTool,
35
+ broadcasts_1.createBroadcastTool,
35
36
  broadcasts_1.getBroadcastTool,
36
37
  broadcasts_1.listBroadcastsTool,
37
38
  broadcasts_1.previewBroadcastTool,
38
- broadcasts_1.resumeBroadcastTool,
39
39
  broadcasts_1.sendBroadcastTool,
40
+ broadcasts_1.pickBroadcastWinnerTool,
41
+ broadcasts_1.resumeBroadcastTool,
40
42
  threads_1.listThreadsTool,
41
43
  threads_1.getThreadTool,
42
44
  threads_1.replyToMessageTool,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;GAQG;AACH,qCAKkB;AAClB,uCAA6E;AAC7E,iDAIwB;AACxB,6CAMsB;AACtB,uCAA+E;AAC/E,2CAAsF;AACtF,2CAAoE;AACpE,+CAA+E;AAC/E,qCAAkF;AAClF,2CAYqB;AACrB,6CAQsB;AAeT,QAAA,KAAK,GAAc;IAC9B,sBAAa;IACb,uBAAc;IACd,qBAAY;IACZ,wBAAe;IACf,yBAAe;IACf,uBAAa;IACb,0BAAgB;IAChB,mCAAoB;IACpB,iCAAkB;IAClB,oCAAqB;IACrB,6BAAgB;IAChB,+BAAkB;IAClB,iCAAoB;IACpB,gCAAmB;IACnB,8BAAiB;IACjB,yBAAe;IACf,uBAAa;IACb,4BAAkB;IAClB,6BAAiB;IACjB,8BAAkB;IAClB,4BAAgB;IAChB,6BAAiB;IACjB,8BAAkB;IAClB,iCAAmB;IACnB,wBAAU;IACV,2BAAa;IACb,uBAAc;IACd,2BAAkB;IAClB,2BAAkB;IAClB,6BAAiB;IACjB,0BAAc;IACd,0BAAc;IACd,6BAAiB;IACjB,4BAAgB;IAChB,wBAAY;IACZ,4BAAgB;IAChB,wBAAW;IACX,8BAAiB;IACjB,8BAAiB;IACjB,kCAAqB;IACrB,oCAAuB;IACvB,4BAAe;IACf,yBAAY;IACZ,2BAAe;IACf,kCAAsB;IACtB,6BAAiB;IACjB,0BAAc;CACf,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;GAQG;AACH,qCAKkB;AAClB,uCAA6E;AAC7E,iDAIwB;AACxB,6CAQsB;AACtB,uCAA+E;AAC/E,2CAAsF;AACtF,2CAAoE;AACpE,+CAA+E;AAC/E,qCAAkF;AAClF,2CAYqB;AACrB,6CAQsB;AAeT,QAAA,KAAK,GAAc;IAC9B,sBAAa;IACb,uBAAc;IACd,qBAAY;IACZ,wBAAe;IACf,yBAAe;IACf,uBAAa;IACb,0BAAgB;IAChB,mCAAoB;IACpB,iCAAkB;IAClB,oCAAqB;IACrB,gCAAmB;IACnB,6BAAgB;IAChB,+BAAkB;IAClB,iCAAoB;IACpB,8BAAiB;IACjB,oCAAuB;IACvB,gCAAmB;IACnB,yBAAe;IACf,uBAAa;IACb,4BAAkB;IAClB,6BAAiB;IACjB,8BAAkB;IAClB,4BAAgB;IAChB,6BAAiB;IACjB,8BAAkB;IAClB,iCAAmB;IACnB,wBAAU;IACV,2BAAa;IACb,uBAAc;IACd,2BAAkB;IAClB,2BAAkB;IAClB,6BAAiB;IACjB,0BAAc;IACd,0BAAc;IACd,6BAAiB;IACjB,4BAAgB;IAChB,wBAAY;IACZ,4BAAgB;IAChB,wBAAW;IACX,8BAAiB;IACjB,8BAAiB;IACjB,kCAAqB;IACrB,oCAAuB;IACvB,4BAAe;IACf,yBAAY;IACZ,2BAAe;IACf,kCAAsB;IACtB,6BAAiB;IACjB,0BAAc;CACf,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sendraven/mcp",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "MCP server for SendRaven: send email, read replies as threads, run campaigns, and decide approvals, with per-key limits for agents.",
5
5
  "mcpName": "ai.sendraven/mcp",
6
6
  "license": "MIT",
package/server.json CHANGED
@@ -6,14 +6,14 @@
6
6
  "url": "https://github.com/CommonNinja/sendraven-mcp-server",
7
7
  "source": "github"
8
8
  },
9
- "version": "0.2.0",
9
+ "version": "0.3.0",
10
10
  "websiteUrl": "https://sendraven.ai/mcp",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "registryBaseUrl": "https://registry.npmjs.org",
15
15
  "identifier": "@sendraven/mcp",
16
- "version": "0.2.0",
16
+ "version": "0.3.0",
17
17
  "transport": {
18
18
  "type": "stdio"
19
19
  },