get_instagram_posts
Fetch recent Instagram posts from a profile using Chrome login. Specify username, limit (1-3 posts or all), and starting index for pagination.
Instructions
Get recent posts from an Instagram profile using existing Chrome login
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of posts to fetch (1-3) or "all" for continuous batches | |
| startFrom | No | Index to start fetching from (for pagination) | |
| username | Yes | Instagram username to fetch posts from |
Input Schema (JSON Schema)
{
"properties": {
"limit": {
"description": "Number of posts to fetch (1-3) or \"all\" for continuous batches",
"type": [
"number",
"string"
]
},
"startFrom": {
"description": "Index to start fetching from (for pagination)",
"type": "number"
},
"username": {
"description": "Instagram username to fetch posts from",
"type": "string"
}
},
"required": [
"username"
],
"type": "object"
}
Implementation Reference
- Core handler implementing the get_instagram_posts tool: uses Playwright for stealthy scraping of Instagram posts with caching, progress updates, and anti-detection behaviors.public async fetchPosts( username: string, limit?: number | 'all', startFrom: number = 0, onProgress?: ProgressCallback ): Promise<IInstagramPost[]> { if (!onProgress) throw new Error('Progress callback required'); this.startHeartbeat(onProgress); try { this.currentProgress = 0; this.totalProgress = 5; const context = await this.initContext(); const page = await context.newPage(); try { this.sendProgress('Loading...', onProgress, true); // Human-like navigation to profile await this.humanNavigate(page, `https://www.instagram.com/${username}/`); const postLinks = await this.getCachedOrFetchLinks(page, startFrom + BATCH_SIZE); if (!postLinks.length) throw new InstagramError('No posts found'); const fetchedPosts = await this.postSaver.loadFetchedPosts(); const endIndex = limit === 'all' ? Math.min(startFrom + BATCH_SIZE, postLinks.length) : Math.min(startFrom + (limit || BATCH_SIZE), postLinks.length); const targetLinks = postLinks.slice(startFrom, endIndex); this.totalProgress = this.currentProgress + targetLinks.length; const posts: IInstagramPost[] = []; for (const postUrl of targetLinks) { try { // Human-like navigation to post await this.humanNavigate(page, postUrl); const postData = await this.extractPostData(page); if (!postData) continue; const post = await this.postProcessor.processPost( postData, this.config.instagram.defaultSaveDir, username ); await this.postSaver.savePost(post, this.config.instagram.defaultSaveDir); fetchedPosts.set(postUrl, new Date().toISOString()); await this.postSaver.saveFetchedPosts(fetchedPosts); posts.push(post); await this.randomDelay(2000, 5000); // Random delay between posts } catch (error) { log('Post error: %s', error instanceof Error ? error.message : String(error)); continue; } } const hasMore = endIndex < postLinks.length; this.sendProgress( hasMore ? 'More available' : 'Complete', onProgress, hasMore ); return posts; } finally { await page.close(); } } catch (error) { log('Fatal error: %s', error instanceof Error ? error.message : String(error)); throw error; } finally { this.stopHeartbeat(); } }
- src/server.ts:50-75 (registration)Registers the 'get_instagram_posts' tool with MCP server including name, description, and input schema.this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: 'get_instagram_posts', description: 'Get recent posts from an Instagram profile using existing Chrome login', inputSchema: { type: 'object', properties: { username: { type: 'string', description: 'Instagram username to fetch posts from' }, limit: { type: ['number', 'string'], description: 'Number of posts to fetch (1-3) or "all" for continuous batches' }, startFrom: { type: 'number', description: 'Index to start fetching from (for pagination)' } }, required: ['username'] } } ] }));
- src/server.ts:77-152 (handler)MCP CallTool request handler: validates arguments, calls InstagramService.fetchPosts, handles progress notifications and response formatting.this.server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name !== 'get_instagram_posts') { throw new McpError( ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}` ); } const args = request.params.arguments; if (!this.isValidFetchArgs(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid fetch arguments' ); } try { const posts = await this.instagramService.fetchPosts( args.username, args.limit, args.startFrom, ((message: string | IProgressUpdate) => { if (typeof message === 'string') { this.server.notification({ method: 'progress', params: { message, progress: 0, total: 0 } }); } else { this.server.notification({ method: 'progress', params: { message: message.message, progress: message.progress, total: message.total, keepAlive: message.keepAlive } }); } }) as ProgressCallback ); return { content: [ { type: 'json', json: { posts, pagination: { currentBatch: { start: args.startFrom || 0, end: (args.startFrom || 0) + posts.length, size: posts.length }, nextStartFrom: (args.startFrom || 0) + posts.length, hasMore: posts.length === 3 } } } ] }; } catch (error) { return { content: [ { type: 'text', text: `Instagram error: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } });
- src/core/types/instagram.ts:89-94 (schema)TypeScript interface defining input arguments for get_instagram_posts tool.export interface IGetInstagramPostsArgs { username: string; limit?: number | 'all'; saveDir?: string; delayBetweenPosts?: number; }
- src/core/utils/config.ts:66-76 (helper)Configuration settings specific to the get_instagram_posts tool including paths, delays, and batch sizes.get_instagram_posts: { defaultSaveDir, postsLogFile: path.join(defaultSaveDir, 'fetched_posts.json'), defaultDelay: 5000, // Increased to 5 seconds between posts maxPostsPerBatch: 25, // Reduced batch size batchBreakDelay: 60000, // Increased to 1 minute break between batches minDelay: 3000, // Increased minimum delay chromeUserDataDir: env.CHROME_USER_DATA_DIR, }, }, },