@buzzposter/mcp 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/dist/index.js +205 -0
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -152,6 +152,17 @@ var BuzzPosterClient = class {
152
152
  async listForms() {
153
153
  return this.request("GET", "/api/v1/newsletters/forms");
154
154
  }
155
+ // Knowledge
156
+ async listKnowledge(params) {
157
+ return this.request("GET", "/api/v1/knowledge", void 0, params);
158
+ }
159
+ async createKnowledge(data) {
160
+ return this.request("POST", "/api/v1/knowledge", data);
161
+ }
162
+ // Brand Voice
163
+ async getBrandVoice() {
164
+ return this.request("GET", "/api/v1/brand-voice");
165
+ }
155
166
  // RSS
156
167
  async fetchFeed(url, limit) {
157
168
  const params = { url };
@@ -776,6 +787,198 @@ function registerAccountInfoTool(server2, client2) {
776
787
  );
777
788
  }
778
789
 
790
+ // src/tools/brand-voice.ts
791
+ function registerBrandVoiceTools(server2, client2) {
792
+ server2.tool(
793
+ "get_brand_voice",
794
+ "Get the customer's brand voice profile and writing rules. IMPORTANT: Call this tool BEFORE creating any post, draft, or content. Use the returned voice description, rules, and examples to match the customer's tone and style in everything you write for them.",
795
+ {},
796
+ async () => {
797
+ try {
798
+ const voice = await client2.getBrandVoice();
799
+ const lines = [];
800
+ lines.push(`## Brand Voice: ${voice.name || "My Brand"}`);
801
+ lines.push("");
802
+ if (voice.description) {
803
+ lines.push("### Voice Description");
804
+ lines.push(voice.description);
805
+ lines.push("");
806
+ }
807
+ if (voice.dos && voice.dos.length > 0) {
808
+ lines.push("### Do's");
809
+ for (const rule of voice.dos) {
810
+ lines.push(`- ${rule}`);
811
+ }
812
+ lines.push("");
813
+ }
814
+ if (voice.donts && voice.donts.length > 0) {
815
+ lines.push("### Don'ts");
816
+ for (const rule of voice.donts) {
817
+ lines.push(`- ${rule}`);
818
+ }
819
+ lines.push("");
820
+ }
821
+ if (voice.platformRules && Object.keys(voice.platformRules).length > 0) {
822
+ lines.push("### Platform-Specific Rules");
823
+ for (const [platform, rules] of Object.entries(voice.platformRules)) {
824
+ lines.push(`**${platform}:** ${rules}`);
825
+ }
826
+ lines.push("");
827
+ }
828
+ if (voice.examplePosts && voice.examplePosts.length > 0) {
829
+ lines.push("### Example Posts");
830
+ voice.examplePosts.forEach((post, i) => {
831
+ lines.push(`${i + 1}. ${post}`);
832
+ });
833
+ lines.push("");
834
+ }
835
+ return {
836
+ content: [{ type: "text", text: lines.join("\n") }]
837
+ };
838
+ } catch (error) {
839
+ const message = error instanceof Error ? error.message : "Unknown error";
840
+ if (message.includes("404") || message.includes("No brand voice")) {
841
+ return {
842
+ content: [
843
+ {
844
+ type: "text",
845
+ text: "No brand voice has been configured yet. The customer can set one up at their BuzzPoster dashboard."
846
+ }
847
+ ]
848
+ };
849
+ }
850
+ throw error;
851
+ }
852
+ }
853
+ );
854
+ }
855
+
856
+ // src/tools/knowledge.ts
857
+ import { z as z7 } from "zod";
858
+ function registerKnowledgeTools(server2, client2) {
859
+ server2.tool(
860
+ "get_knowledge_base",
861
+ "Get all items from the customer's knowledge base. Use this to access reference material about the business, products, team, competitors, and other context that helps you write better content.",
862
+ {},
863
+ async () => {
864
+ try {
865
+ const data = await client2.listKnowledge();
866
+ const items = data.items ?? [];
867
+ if (items.length === 0) {
868
+ return {
869
+ content: [
870
+ {
871
+ type: "text",
872
+ text: "The knowledge base is empty. The customer can add reference material at their BuzzPoster dashboard."
873
+ }
874
+ ]
875
+ };
876
+ }
877
+ const totalChars = items.reduce(
878
+ (sum, item) => sum + item.content.length,
879
+ 0
880
+ );
881
+ const shouldTruncate = totalChars > 1e4;
882
+ const lines = [];
883
+ lines.push(`## Knowledge Base (${items.length} items)`);
884
+ lines.push("");
885
+ for (const item of items) {
886
+ lines.push(`### ${item.title}`);
887
+ if (item.tags && item.tags.length > 0) {
888
+ lines.push(`Tags: ${item.tags.join(", ")}`);
889
+ }
890
+ if (shouldTruncate) {
891
+ lines.push(item.content.slice(0, 500) + " [truncated]");
892
+ } else {
893
+ lines.push(item.content);
894
+ }
895
+ lines.push("");
896
+ }
897
+ return {
898
+ content: [{ type: "text", text: lines.join("\n") }]
899
+ };
900
+ } catch (error) {
901
+ const message = error instanceof Error ? error.message : "Unknown error";
902
+ throw new Error(`Failed to get knowledge base: ${message}`);
903
+ }
904
+ }
905
+ );
906
+ server2.tool(
907
+ "search_knowledge",
908
+ "Search the customer's knowledge base by tag or keyword. Use this to find specific reference material when writing about a topic.",
909
+ {
910
+ query: z7.string().describe(
911
+ "Search query - matches against tags first, then falls back to text search on title and content"
912
+ )
913
+ },
914
+ async ({ query }) => {
915
+ try {
916
+ const data = await client2.listKnowledge({ tag: query });
917
+ const items = data.items ?? [];
918
+ if (items.length === 0) {
919
+ return {
920
+ content: [
921
+ {
922
+ type: "text",
923
+ text: `No knowledge base items found matching "${query}".`
924
+ }
925
+ ]
926
+ };
927
+ }
928
+ const lines = [];
929
+ lines.push(
930
+ `## Knowledge Base Results for "${query}" (${items.length} items)`
931
+ );
932
+ lines.push("");
933
+ for (const item of items) {
934
+ lines.push(`### ${item.title}`);
935
+ if (item.tags && item.tags.length > 0) {
936
+ lines.push(`Tags: ${item.tags.join(", ")}`);
937
+ }
938
+ lines.push(item.content);
939
+ lines.push("");
940
+ }
941
+ return {
942
+ content: [{ type: "text", text: lines.join("\n") }]
943
+ };
944
+ } catch (error) {
945
+ const message = error instanceof Error ? error.message : "Unknown error";
946
+ throw new Error(`Failed to search knowledge base: ${message}`);
947
+ }
948
+ }
949
+ );
950
+ server2.tool(
951
+ "add_knowledge",
952
+ "Add a new item to the customer's knowledge base. Use this to save useful information the customer shares during conversation.",
953
+ {
954
+ title: z7.string().describe("Title for the knowledge item"),
955
+ content: z7.string().describe("The content/text to save"),
956
+ tags: z7.array(z7.string()).optional().describe("Optional tags for categorization")
957
+ },
958
+ async ({ title, content, tags }) => {
959
+ try {
960
+ await client2.createKnowledge({
961
+ title,
962
+ content,
963
+ sourceType: "text",
964
+ tags: tags ?? []
965
+ });
966
+ return {
967
+ content: [
968
+ {
969
+ type: "text",
970
+ text: `Added "${title}" to the knowledge base.`
971
+ }
972
+ ]
973
+ };
974
+ } catch (error) {
975
+ const message = error instanceof Error ? error.message : "Unknown error";
976
+ throw new Error(`Failed to add knowledge item: ${message}`);
977
+ }
978
+ }
979
+ );
980
+ }
981
+
779
982
  // src/index.ts
780
983
  var apiKey = process.env.BUZZPOSTER_API_KEY;
781
984
  var apiUrl = process.env.BUZZPOSTER_API_URL ?? "https://api.buzzposter.com";
@@ -801,5 +1004,7 @@ registerMediaTools(server, client);
801
1004
  registerNewsletterTools(server, client);
802
1005
  registerRssTools(server, client);
803
1006
  registerAccountInfoTool(server, client);
1007
+ registerBrandVoiceTools(server, client);
1008
+ registerKnowledgeTools(server, client);
804
1009
  var transport = new StdioServerTransport();
805
1010
  await server.connect(transport);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buzzposter/mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "BuzzPoster MCP server - Social media, newsletters, and media hosting for Claude Desktop",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",