Skip to content

Documentation navigation

Social Media

X, Meta, Instagram, LinkedIn, TikTok, YouTube, and other social toolsets.

#Social media

Public social-media platforms. Each toolset exposes the standard @toolset / @toolify shape; the snippets below show only the constructor and the headline tool surface.

Tip: most agents only need read access (browse + analytics). Register with add_toolset(..., include_tags=["read"]) or exclude_tags=["destructive"] to drop methods carrying that tag. Publishing methods can be ordinary WRITE tools; use an explicit read-method allowlist when publishing must be unavailable.
Agent-ready pattern. Across these connectors, broad list / search / feed tools return compact human-readable summaries by default with a response-local _ref field (tweet_ref, post_ref, media_ref, video_ref, status_ref, comment_ref, ...) and a small default page size (usually 10-25). Raw provider IDs are hidden unless you pass include_ids=True; pass include_metadata=False to get the raw provider response. Write tools that target a single item (delete_tweet, delete_post, like_tweet, delete_status, delete_pin, delete_message, destroy_update, ...) accept either a raw ID/URN/URI string or the summary dict from the corresponding list/search tool.

#XToolSet (formerly Twitter)

Python
from maivn_tools import XToolSet

connector = XToolSet(bearer_token=secrets["X_BEARER_TOKEN"])

Tools: get_me, get_user, get_user_by_ids, get_tweet, get_tweets, search_recent_tweets(query, max_results, next_token, start_time, end_time, tweet_fields, expansions, include_metadata, include_ids), get_user_tweets(user_id, max_results, pagination_token, exclude, tweet_fields, include_metadata, include_ids), get_user_mentions(user_id, max_results, pagination_token, include_metadata, include_ids), post_tweet, delete_tweet (destructive), like_tweet, unlike_tweet (destructive), retweet, unretweet (destructive), follow_user, unfollow_user (destructive), get_followers(user_id, max_results, pagination_token, include_metadata, include_ids), get_following(user_id, max_results, pagination_token, include_metadata, include_ids), list_owned_lists, create_list, delete_list (destructive), send_dm.

#Agent-ready behavior

search_recent_tweets, get_user_tweets, and get_user_mentions return compact summaries by default with tweet_ref (stable tweet_1 ...), author (@handle), text, posted_at, like / repost / reply counts, and url. get_followers and get_following return user_ref summaries (handle, name, follower counts, profile URL). Raw X tweet/user IDs are omitted unless include_ids=True; include_metadata=False returns the raw v2 payload. Default max_results is 10 for tweets, 25 for followers/following. delete_tweet, like_tweet, unlike_tweet, retweet, and unretweet accept either a raw tweet_id string or a tweet/search result dict — the connector extracts the ID for you.

Python
x.search_recent_tweets("anthropic claude")
# { "tweets": [{"tweet_ref": "tweet_1", "author": "@user",
#                "text": "...", "posted_at": "...",
#                "like_count": 12, "url": "https://x.com/..."}],
#   "next_token": "...", "result_count": 10 }

#Destructive tools

delete_tweet, unlike_tweet, unretweet, unfollow_user, and delete_list are tagged destructive=True. delete_tweet is not reversible. Confirm with the user before calling.

#MetaToolSet (Facebook Graph)

Python
from maivn_tools import MetaToolSet

connector = MetaToolSet(access_token=secrets["FB_PAGE_TOKEN"])

Pages, posts, comments, and insights via the Graph API. Tools: get_me, list_accounts, get_page, list_page_posts(page_id, limit, after, fields, include_metadata, include_ids), publish_page_post, delete_post (destructive), list_post_comments(post_id, limit, after, include_metadata, include_ids), reply_to_comment, delete_comment (destructive), get_page_insights, get_post_insights.

#Agent-ready behavior

list_page_posts returns compact summaries with post_ref, message, posted_at, and permalink_url. list_post_comments returns comment_ref with author, message, posted_at, and like_count. Default limit is 10. Raw Graph post / comment IDs are omitted unless include_ids=True; include_metadata=False returns the raw Graph response. delete_post accepts a raw post_id string or a post dict from list_page_posts.

Python
meta.list_page_posts(page_id)
# { "posts": [{"post_ref": "post_1", "message": "Launch day!",
#                "posted_at": "...", "permalink_url": "https://..."}],
#   "paging": {...} }

#Destructive tools

delete_post and delete_comment are tagged destructive=True and not reversible. Confirm with the user first.

#InstagramToolSet

Python
from maivn_tools import InstagramToolSet

connector = InstagramToolSet(access_token=secrets["IG_PAGE_TOKEN"])

Requires a Business or Creator IG account linked to a Facebook Page. Tools: get_account, list_media(ig_user_id, limit, after, fields, include_metadata, include_ids), get_media, create_media_container, publish_media, get_container_status, list_comments(media_id, limit, include_metadata, include_ids), reply_to_comment, delete_comment (destructive), hide_comment, get_media_insights, get_account_insights, list_stories.

#Agent-ready behavior

list_media returns media_ref summaries with caption, media type, permalink, posted-at, like / comment counts. list_comments returns comment_ref summaries (author username, text, posted-at, like count). Default limit is 10 for media, 25 for comments. Raw IG IDs are omitted unless include_ids=True; include_metadata=False returns the raw Graph response.

Python
instagram.list_media(ig_user_id)
# { "media": [{"media_ref": "media_1", "caption": "...",
#               "media_type": "IMAGE", "permalink": "https://...",
#               "like_count": 42, ...}], "paging": {...} }

Two-step publish: call create_media_container(...) then poll get_container_status(container_id) until the upload finishes, then publish_media(creation_id=...).

#Destructive tools

delete_comment is tagged destructive=True and not reversible — prefer hide_comment for soft-removing. publish_media posts publicly to the account's grid; treat it as a high-impact write and confirm with the user.

#LinkedInToolSet

Python
from maivn_tools import LinkedInToolSet

connector = LinkedInToolSet(access_token=secrets["LI_TOKEN"])

Posts, comments, member identity, and organization-level reads. Tools: get_userinfo, get_me, create_post, get_post, delete_post (destructive), list_posts_for_author(author_urn, count, start, include_metadata, include_ids), create_comment, list_comments(post_urn, count, include_metadata, include_ids), get_organization, list_organization_acls.

The Posts API uses URNs (urn:li:person:..., urn:li:organization:..., urn:li:share:...); pass them through directly.

#Agent-ready behavior

list_posts_for_author returns post_ref summaries with author URN, commentary, posted-at, visibility, and lifecycle state. list_comments returns comment_ref with actor, text, posted-at. Default count is 10 for posts, 25 for comments. Raw post URNs and comment IDs are omitted unless include_ids=True; include_metadata=False returns the raw REST response. delete_post accepts a raw URN string or a post dict from list_posts_for_author.

Python
linkedin.list_posts_for_author(author_urn="urn:li:person:...")
# { "posts": [{"post_ref": "post_1", "author": "urn:li:person:...",
#                "commentary": "...", "visibility": "PUBLIC", ...}],
#   "paging": {...} }

#Destructive tools

delete_post is tagged destructive=True and not reversible. Confirm with the user first.

#TikTokToolSet

Python
from maivn_tools import TikTokToolSet

connector = TikTokToolSet(access_token=secrets["TT_TOKEN"])

Content Posting + Display APIs. Tools: get_user_info, list_videos(fields, cursor, max_count, include_metadata, include_ids), query_videos, get_creator_info, init_video_upload, init_inbox_upload, get_publish_status, init_photo_publish.

#Agent-ready behavior

list_videos returns video_ref summaries with title, author username, posted-at, view / like / comment / share counts, duration, and a constructed url. Default max_count is 10 (TikTok caps at 20). Raw TikTok video IDs are omitted unless include_ids=True; include_metadata=False returns the raw TikTok response. query_videos is the explicit ID-lookup tool — pass it the video_id list obtained from list_videos(include_ids=True).

Python
tiktok.list_videos()
# { "videos": [{"video_ref": "video_1", "title": "...",
#                "author": "...", "view_count": 1234,
#                "url": "https://www.tiktok.com/@.../video/..."}],
#   "cursor": ..., "has_more": true }

init_video_upload and init_photo_publish start an asynchronous upload; poll get_publish_status(publish_id) until the job reports status: PUBLISHED.

#YouTubeToolSet

Python
from maivn_tools import YouTubeToolSet

connector = YouTubeToolSet(token=token_cache)

YouTube Data API v3. Tools: list_channels, list_videos(id, part, include_metadata, include_ids), search(q, channel_id, type, order, max_results, page_token, include_metadata, include_ids), list_playlists, list_playlist_items, add_to_playlist, delete_playlist_item (destructive), update_video, delete_video (destructive), list_comment_threads(video_id, channel_id, max_results, page_token, order, include_metadata, include_ids), post_comment.

#Agent-ready behavior

search, list_videos, and list_comment_threads return compact summaries by default. video_ref summaries include title, channel name, posted-at, description, view / like / comment counts, duration, and a url. comment_ref summaries include author, text, posted-at, like / reply counts. Default max_results is 10. Raw YouTube video / channel / comment IDs are omitted unless include_ids=True; include_metadata=False returns the raw YouTube response. delete_video accepts a raw video_id string or a search/list result dict.

Python
youtube.search(q="claude api demo")
# { "videos": [{"video_ref": "video_1", "title": "...",
#                "channel": "...", "url": "https://www.youtube.com/watch?v=..."}],
#   "next_page_token": "...", "page_info": {...} }

#Destructive tools

delete_video and delete_playlist_item are tagged destructive=True. delete_video is not reversible.

The YouTube Data API has tight daily quota costs (e.g. search is 100 units). Cache results and prefer narrowly-scoped list_videos / list_channels calls when you can.

#RedditToolSet

Python
from maivn_tools import RedditToolSet

connector = RedditToolSet(
    access_token=secrets["REDDIT_TOKEN"],
    user_agent="maivn-app:1.0 (by /u/your-handle)",
)

Reddit requires a descriptive User-Agent. Tools: get_me, list_subscribed_subreddits, get_subreddit_about, list_subreddit_posts(subreddit, sort, limit, after, time, include_metadata, include_ids), search(query, subreddit, sort, limit, after, include_metadata, include_ids), get_post, submit_post, submit_comment, vote, save, unsave, subscribe, delete_thing (destructive).

#Agent-ready behavior

list_subreddit_posts and search return compact summaries with post_ref, title, author, subreddit, posted-at (Unix epoch), score, comment count, URL, and a truncated selftext (first 500 chars). Default limit is 10. Raw Reddit fullnames (t3_...) are omitted unless include_ids=True; include_metadata=False returns the raw Reddit listing. submit_comment, vote, save, unsave, and delete_thing accept either a raw thing_id (fullname) or a post / comment dict from a listing.

Python
reddit.list_subreddit_posts("python", sort="hot")
# { "posts": [{"post_ref": "post_1", "title": "...",
#               "author": "...", "subreddit": "python",
#               "score": 1234, "num_comments": 56,
#               "url": "https://www.reddit.com/r/python/..."}],
#   "after": "...", "before": null }

#Destructive tools

delete_thing is tagged destructive=True and not reversible (the post or comment is removed permanently). Confirm with the user.

#PinterestToolSet

Python
from maivn_tools import PinterestToolSet

connector = PinterestToolSet(access_token=secrets["PINTEREST_TOKEN"])

Pinterest API v5: boards, pins, and analytics. Tools: get_user_account, list_boards(bookmark, page_size, privacy, include_metadata, include_ids), get_board, create_board, delete_board (destructive), list_board_pins(board_id, bookmark, page_size, include_metadata, include_ids), list_pins(bookmark, page_size, include_metadata, include_ids), get_pin, create_pin, delete_pin (destructive), get_pin_analytics, get_user_analytics.

#Agent-ready behavior

list_boards returns board_ref summaries with name, description, privacy, owner, pin / follower counts, created-at. list_board_pins / list_pins return pin_ref summaries with title, description, alt text, link, created-at, and a constructed url. Default page_size is 25. Raw Pinterest board / pin IDs are omitted unless include_ids=True; include_metadata=False returns the raw Pinterest response. delete_pin accepts either a raw pin_id string or a pin dict.

Python
pinterest.list_pins()
# { "pins": [{"pin_ref": "pin_1", "title": "...",
#              "url": "https://www.pinterest.com/pin/..."}],
#   "bookmark": "..." }

#Destructive tools

delete_board (removes board + all pins) and delete_pin are tagged destructive=True and not reversible.

#DiscordToolSet

Python
from maivn_tools import DiscordToolSet

connector = DiscordToolSet(token=secrets["DISCORD_BOT_TOKEN"])

Defaults to token_type="Bot"; set token_type="Bearer" for user OAuth tokens. Tools: get_current_user, list_current_user_guilds(before, after, limit, include_metadata, include_ids), get_guild, list_guild_channels(guild_id, include_metadata, include_ids), list_guild_members, get_channel, list_messages(channel_id, limit, before, after, around, include_metadata, include_ids), get_message, create_message, edit_message, delete_message (destructive), create_reaction, create_dm, add_guild_member_role, remove_guild_member (destructive), execute_webhook.

#Agent-ready behavior

list_current_user_guilds, list_guild_channels, and list_messages return compact summaries. guild_ref carries name + owner + permissions; channel_ref carries name + type + topic; message_ref carries author username, content, timestamp, and has_attachments. Default limit is 25 for guilds, 20 for messages. Raw Discord snowflakes are omitted unless include_ids=True; include_metadata=False returns the raw response. list_guild_channels populates a channel name -> ID cache; create_message, edit_message, delete_message, create_reaction, and get_message accept a channel name, raw snowflake, or channel-summary dict for channel_id, and the message dict or raw ID for message_id.

Python
discord.list_messages("general")
# { "messages": [{"message_ref": "message_1", "author": "alice",
#                  "content": "...", "timestamp": "...",
#                  "has_attachments": false}] }

#Destructive tools

delete_message (not reversible) and remove_guild_member (kicks the user) are tagged destructive=True. Confirm with the user before invoking.

#TelegramToolSet

Python
from maivn_tools import TelegramToolSet

connector = TelegramToolSet(bot_token=secrets["TG_BOT_TOKEN"])

The bot token is embedded in the request path (/bot<TOKEN>/...), as required by the Bot API. Tools: get_me, get_updates(offset, limit, timeout, allowed_updates, include_metadata, include_ids), send_message, edit_message_text, delete_message (destructive), send_photo, answer_callback_query, get_chat, get_chat_member, set_webhook, delete_webhook, get_webhook_info.

#Agent-ready behavior

get_updates returns compact summaries by default with update_ref, update type (message / callback_query / channel_post / ...), chat_title, sender, and text. Default limit is 25. Telegram update_id / message_id / chat_id integers are omitted unless include_ids=True; include_metadata=False returns the raw Telegram response. send_message, edit_message_text, delete_message, send_photo, get_chat, get_chat_member, and the reply_to_message_id argument all accept either a raw int/string ID or the update / message dict from get_updates.

Python
telegram.get_updates()
# { "ok": true,
#   "updates": [{"update_ref": "update_1", "type": "message",
#                 "chat_title": "Alice", "sender": "alice",
#                 "text": "hi"}] }

#Destructive tools

delete_message is tagged destructive=True — the message is removed for everyone in the chat and cannot be recovered.

#WhatsAppBusinessToolSet

Python
from maivn_tools import WhatsAppBusinessToolSet

connector = WhatsAppBusinessToolSet(
    access_token=secrets["WABA_TOKEN"],
    phone_number_id="123456789",
)

WhatsApp Business Cloud API (Meta Graph). Tools: send_text, send_template, send_media, mark_message_read, get_media_metadata, delete_media (destructive), list_phone_numbers, list_message_templates(waba_id, limit, include_metadata, include_ids), create_message_template.

#Agent-ready behavior

list_message_templates returns template_ref summaries with name, language, category, status. Default limit is 25. Raw template IDs are omitted unless include_ids=True; include_metadata=False returns the raw Graph response. mark_message_read accepts either a raw wamid string or the message-summary dict returned by a previous send_* call (extracts messages[0].id).

Python
whatsapp.list_message_templates(waba_id)
# { "templates": [{"template_ref": "template_1", "name": "welcome",
#                   "language": "en_US", "category": "MARKETING",
#                   "status": "APPROVED"}], "paging": {...} }

#Destructive tools

delete_media is tagged destructive=True — the uploaded asset is removed and cannot be recovered.

#MastodonToolSet

Python
from maivn_tools import MastodonToolSet

connector = MastodonToolSet(
    access_token=secrets["MASTODON_TOKEN"],
    instance_url="https://mastodon.social",
)

Tools: verify_credentials, get_account, lookup_account, home_timeline(limit, max_id, since_id, include_metadata, include_ids), public_timeline(local, remote, only_media, limit, include_metadata, include_ids), hashtag_timeline(hashtag, limit, max_id, include_metadata, include_ids), get_status, post_status, delete_status (destructive), favourite_status, reblog_status, follow_account, unfollow_account, list_notifications, search.

#Agent-ready behavior

All three timeline tools (home_timeline, public_timeline, hashtag_timeline) return compact status_ref summaries by default with author (acct handle), display name, HTML content, posted-at, visibility, favourites / reblogs / replies counts, and url. Default limit is 20. Raw Mastodon status IDs are omitted unless include_ids=True; include_metadata=False returns the raw response. delete_status, favourite_status, and reblog_status accept either a raw status_id or a status dict from a timeline.

Python
mastodon.home_timeline()
# { "statuses": [{"status_ref": "status_1", "author": "alice@example",
#                  "content": "...", "favourites_count": 5,
#                  "url": "https://..."}] }

#Destructive tools

delete_status is tagged destructive=True and not reversible.

#BlueskyToolSet

Python
from maivn_tools import BlueskyToolSet

connector = BlueskyToolSet(
    access_jwt=session["accessJwt"],
    did=session["did"],
)

AT Protocol XRPC. Obtain the JWT + DID via com.atproto.server.createSession (or any of the standard atproto clients) and pass them in. Tools: get_profile, get_timeline(limit, cursor, include_metadata, include_ids), get_author_feed(actor, limit, cursor, include_metadata, include_ids), search_posts(query, limit, cursor, author, include_metadata, include_ids), create_post, delete_post (destructive), like, repost, follow, get_followers(actor, limit, cursor, include_metadata, include_ids), get_follows(actor, limit, cursor, include_metadata, include_ids).

#Agent-ready behavior

get_timeline, get_author_feed, and search_posts return post_ref summaries with author handle, display name, text, posted-at, like / repost / reply counts, and url. get_followers / get_follows return user_ref summaries (handle, name, description, profile URL). Default limit is 25. Raw at:// URIs, CIDs, and DIDs are omitted unless include_ids=True; include_metadata=False returns the raw XRPC response. delete_post accepts a raw rkey, a full at:// URI, or a post dict. like and repost accept either a feed-view/post dict or explicit uri + cid arguments.

Python
bluesky.search_posts("agent ready toolsets")
# { "posts": [{"post_ref": "post_1", "author": "alice.bsky.social",
#                "text": "...", "like_count": 12,
#                "url": "https://bsky.app/profile/.../post/..."}],
#   "cursor": "..." }

#Destructive tools

delete_post is tagged destructive=True and not reversible.

#ThreadsToolSet

Python
from maivn_tools import ThreadsToolSet

connector = ThreadsToolSet(access_token=secrets["THREADS_TOKEN"])

Threads (Meta) Graph API. Two-step publish: call create_media_container(...) then poll get_container_status(creation_id), then publish_media(creation_id=...). Tools: get_me, list_threads(user_id, fields, limit, after, since, until, include_metadata, include_ids), get_thread, create_media_container, publish_media, get_container_status, list_replies(media_id, fields, reverse, include_metadata, include_ids), hide_reply, get_media_insights, get_user_insights.

#Agent-ready behavior

list_threads returns post_ref summaries with author username, text, posted-at, media type, and permalink. list_replies returns reply_ref summaries (author, text, posted-at, permalink). Default limit is 10. Raw thread / reply IDs are omitted unless include_ids=True; include_metadata=False returns the raw Graph response.

Python
threads.list_threads(user_id)
# { "posts": [{"post_ref": "post_1", "author": "alice",
#                "text": "...", "permalink": "https://www.threads.net/..."}],
#   "paging": {...} }

#Destructive tools

This connector does not expose a hard delete; hide_reply (with hide=False to unhide) is a soft alternative.

#BufferToolSet

Python
from maivn_tools import BufferToolSet

connector = BufferToolSet(api_key=secrets["BUFFER_TOKEN"])

Buffer Publish + Profiles API for cross-network scheduling. Tools: get_user, list_profiles, get_profile, list_pending_updates(profile_id, page, count, include_metadata, include_ids), list_sent_updates(profile_id, page, count, include_metadata, include_ids), get_update, create_update, update_update, share_update_now, destroy_update (destructive), get_update_interactions.

#Agent-ready behavior

list_pending_updates and list_sent_updates return update_ref summaries with text, status, scheduled-at, sent-at, service, author. Default count is 10. Raw Buffer update IDs are omitted unless include_ids=True; include_metadata=False returns the raw Buffer response. update_update, share_update_now, and destroy_update accept either a raw update_id string or an update dict from list_pending_updates / list_sent_updates.

Python
buffer.list_pending_updates(profile_id)
# { "updates": [{"update_ref": "update_1", "text": "Launch day!",
#                  "status": "buffer", "scheduled_at": 1716000000,
#                  "service": "twitter"}], "total": 3 }

#Destructive tools

destroy_update is tagged destructive=True and not reversible — the update is removed from the queue or revoked if already sent. share_update_now publishes immediately, bypassing the schedule; treat it as a high-impact write.