mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-16 23:01:06 +02:00
refactor(mcp): align Instagram scraper tool with new pipeline
This commit is contained in:
parent
36bb4a1bea
commit
8fc86b7fa5
3 changed files with 30 additions and 87 deletions
|
|
@ -1,4 +1,4 @@
|
|||
"""Instagram scraper tools: posts/reels, comments, and details."""
|
||||
"""Instagram scraper tools: posts/reels and profile details (anonymous-only)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -14,14 +14,13 @@ from ..annotations import SCRAPE
|
|||
from ..capability import run_scraper
|
||||
|
||||
ResultType = Literal["posts", "reels", "mentions"]
|
||||
SearchType = Literal["hashtag", "profile", "place", "user"]
|
||||
DetailSearchType = Literal["hashtag", "profile", "place"]
|
||||
SearchType = Literal["profile", "user"]
|
||||
|
||||
|
||||
def register(
|
||||
mcp: FastMCP, client: SurfSenseClient, context: WorkspaceContext
|
||||
) -> None:
|
||||
"""Register the Instagram scrape, comments, and details tools."""
|
||||
"""Register the Instagram scrape and details tools (anonymous-only)."""
|
||||
|
||||
@mcp.tool(
|
||||
name="surfsense_instagram_scrape",
|
||||
|
|
@ -33,21 +32,22 @@ def register(
|
|||
urls: Annotated[
|
||||
list[str] | None,
|
||||
Field(
|
||||
description="Instagram URLs: a profile, post (/p/), reel "
|
||||
"(/reel/), hashtag (/explore/tags/), or place "
|
||||
"(/explore/locations/). Provide urls OR search_queries."
|
||||
description="Instagram URLs: a profile, post (/p/), or reel "
|
||||
"(/reel/). Hashtag/place URLs are unsupported (login-walled). "
|
||||
"Provide urls OR search_queries."
|
||||
),
|
||||
] = None,
|
||||
search_queries: Annotated[
|
||||
list[str] | None,
|
||||
Field(
|
||||
description="Terms to discover content for (hashtags as plain "
|
||||
"text, no '#'). Provide search_queries OR urls."
|
||||
description="Terms to discover public profiles for (resolved via "
|
||||
"Google). Provide search_queries OR urls."
|
||||
),
|
||||
] = None,
|
||||
search_type: Annotated[
|
||||
SearchType, Field(description="What to discover from search_queries.")
|
||||
] = "hashtag",
|
||||
SearchType,
|
||||
Field(description="Discovery kind (profile-only)."),
|
||||
] = "profile",
|
||||
result_type: Annotated[
|
||||
ResultType,
|
||||
Field(description="Which feed to return. 'mentions' needs profile URLs."),
|
||||
|
|
@ -61,10 +61,10 @@ def register(
|
|||
"""Scrape public Instagram posts or reels from URLs or search queries.
|
||||
|
||||
Use this for Instagram content research: a creator's recent posts, a
|
||||
hashtag or location feed, or discovering posts by keyword. For a post's
|
||||
comment section use surfsense_instagram_comments; for profile/hashtag/
|
||||
place metadata use surfsense_instagram_details. Returns per-item caption,
|
||||
likes, comments count, media URLs, and owner.
|
||||
single post/reel, or discovering public profiles by keyword. For a
|
||||
profile's metadata use surfsense_instagram_details. Returns per-item
|
||||
caption, likes, comments count, media URLs, and owner. Anonymous-only:
|
||||
hashtag/place feeds and comment threads are login-walled and unavailable.
|
||||
Example: urls=['https://www.instagram.com/natgeo/'], result_type='reels'.
|
||||
"""
|
||||
return await run_scraper(
|
||||
|
|
@ -83,64 +83,9 @@ def register(
|
|||
response_format=response_format,
|
||||
)
|
||||
|
||||
@mcp.tool(
|
||||
name="surfsense_instagram_comments",
|
||||
title="Fetch Instagram comments",
|
||||
annotations=SCRAPE,
|
||||
structured_output=False,
|
||||
)
|
||||
async def instagram_comments(
|
||||
urls: Annotated[
|
||||
list[str],
|
||||
Field(
|
||||
min_length=1,
|
||||
description="Instagram post or reel URLs, e.g. "
|
||||
"['https://www.instagram.com/p/Cabc123/'].",
|
||||
),
|
||||
],
|
||||
max_comments_per_post: Annotated[
|
||||
int,
|
||||
Field(ge=1, le=50, description="Max comments per post (Instagram caps at 50)."),
|
||||
] = 10,
|
||||
include_replies: Annotated[
|
||||
bool, Field(description="Include nested replies.")
|
||||
] = False,
|
||||
newest_first: Annotated[
|
||||
bool, Field(description="Return newest comments first.")
|
||||
] = False,
|
||||
max_items: Annotated[
|
||||
int, Field(ge=1, description="Max total comments across all posts.")
|
||||
] = 20,
|
||||
workspace: WorkspaceParam = None,
|
||||
response_format: ResponseFormatParam = "markdown",
|
||||
) -> str:
|
||||
"""Fetch the comments (and optionally replies) on Instagram posts or reels.
|
||||
|
||||
Use this when the user wants a post's discussion or audience reaction
|
||||
rather than the post itself; get post URLs from surfsense_instagram_scrape
|
||||
if you only have a topic or profile. Returns comment text, author, likes,
|
||||
and replies.
|
||||
Example: urls=['https://www.instagram.com/p/Cabc123/'], include_replies=True.
|
||||
"""
|
||||
return await run_scraper(
|
||||
client,
|
||||
context,
|
||||
platform="instagram",
|
||||
verb="comments",
|
||||
payload={
|
||||
"urls": urls,
|
||||
"max_comments_per_post": max_comments_per_post,
|
||||
"include_replies": include_replies,
|
||||
"newest_first": newest_first,
|
||||
"max_items": max_items,
|
||||
},
|
||||
workspace=workspace,
|
||||
response_format=response_format,
|
||||
)
|
||||
|
||||
@mcp.tool(
|
||||
name="surfsense_instagram_details",
|
||||
title="Fetch Instagram profile/hashtag/place details",
|
||||
title="Fetch Instagram profile details",
|
||||
annotations=SCRAPE,
|
||||
structured_output=False,
|
||||
)
|
||||
|
|
@ -148,35 +93,34 @@ def register(
|
|||
urls: Annotated[
|
||||
list[str] | None,
|
||||
Field(
|
||||
description="Profile, hashtag, or place URLs (or bare profile "
|
||||
"IDs). Provide urls OR search_queries."
|
||||
description="Profile URLs (or bare profile IDs). Provide urls OR "
|
||||
"search_queries."
|
||||
),
|
||||
] = None,
|
||||
search_queries: Annotated[
|
||||
list[str] | None,
|
||||
Field(
|
||||
description="Terms to discover profiles/hashtags/places for. "
|
||||
"Provide search_queries OR urls."
|
||||
description="Terms to discover public profiles for. Provide "
|
||||
"search_queries OR urls."
|
||||
),
|
||||
] = None,
|
||||
search_type: Annotated[
|
||||
DetailSearchType,
|
||||
Field(description="What to discover from search_queries."),
|
||||
] = "hashtag",
|
||||
SearchType,
|
||||
Field(description="Discovery kind (profile-only)."),
|
||||
] = "profile",
|
||||
max_items: Annotated[
|
||||
int, Field(ge=1, description="Max detail items to return.")
|
||||
] = 10,
|
||||
workspace: WorkspaceParam = None,
|
||||
response_format: ResponseFormatParam = "markdown",
|
||||
) -> str:
|
||||
"""Fetch Instagram profile, hashtag, or place metadata.
|
||||
"""Fetch Instagram profile metadata.
|
||||
|
||||
Use this for entity lookups: a profile's follower/post counts and bio, a
|
||||
hashtag's post volume and top posts, or a place's coordinates and post
|
||||
count. For a feed of posts use surfsense_instagram_scrape instead. Each
|
||||
item carries a detailKind field marking whether it is a profile, hashtag,
|
||||
or place.
|
||||
Example: urls=['https://www.instagram.com/explore/tags/crossfit/'].
|
||||
Use this for entity lookups: a profile's follower/post counts and bio.
|
||||
For a feed of posts use surfsense_instagram_scrape instead. Each item
|
||||
carries a detailKind field (always "profile"). Anonymous-only: hashtag
|
||||
and place details are login-walled and unavailable.
|
||||
Example: urls=['https://www.instagram.com/natgeo/'].
|
||||
"""
|
||||
return await run_scraper(
|
||||
client,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ EXPECTED_TOOLS = {
|
|||
"surfsense_google_maps_scrape",
|
||||
"surfsense_google_maps_reviews",
|
||||
"surfsense_instagram_scrape",
|
||||
"surfsense_instagram_comments",
|
||||
"surfsense_instagram_details",
|
||||
"surfsense_list_scraper_runs",
|
||||
"surfsense_get_scraper_run",
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ def build_server(settings: Settings) -> tuple[FastMCP, SurfSenseClient]:
|
|||
"Prefer these tools over generic/built-in web search whenever the "
|
||||
"task involves Reddit (posts, comments, finding subreddits or "
|
||||
"communities), YouTube (videos, transcripts, comments), Instagram "
|
||||
"(posts, reels, comments, profile/hashtag/place details), Google "
|
||||
"(posts, reels, profile details), Google "
|
||||
"Maps (places, reviews), Google Search results, or reading "
|
||||
"specific web pages. Scraper results are persisted as runs; if an "
|
||||
"inline result is truncated, fetch it in full with "
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue