A FastAPI-based social media automation server that summarizes URLs, generates content with hashtags, and posts to multiple platforms (Telegram, Twitter, LinkedIn) using AI agents powered by CrewAI
Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
This server has critical definition quality gaps that make it unsuitable for production agent use. It is NOT implemented as an MCP server, it is a standard FastAPI HTTP service. No tool definitions (names, descriptions, parameters, schemas) are visible in the provided source code. The four tools are mentioned in the metadata but have no explicit schema registration, implementation visibility, or MCP-compliant definition. Naming is verb-based (WebScraperTool, TelegramPosterTool, etc.), but full descriptions and parameter annotations cannot be verified from the code. The server has no tool registration mechanism visible (no tools/ endpoint, no list_tools implementation). This appears to be a standard REST API with predefined endpoints (/predict, /enhance, /queue) rather than an MCP tool server. Without visible tool definitions, schema details, and proper MCP registration, scores are capped per the rubric.
Tools (4)
LinkedInPosterToolwriteauth31/100
Tool for posting content to LinkedIn
TelegramPosterToolwriteauth31/100
Tool for posting messages to Telegram channels
TwitterPosterToolwriteauth31/100
Tool for posting tweets to Twitter/X
WebScraperToolread only36/100
Web scraping tool for extracting content from URLs
Not an MCP server. The codebase is a standard FastAPI HTTP service, not an MCP (Model Context Protocol) server. No MCP tool registration, no tools/ endpoint, no MCP-compliant protocol implementation visible.
No visible tool definitions or schemas. Tool names are inferred from metadata, but the actual tool implementations (including input/output schemas, descriptions, parameter types) are not present in the provided source code.
Missing input parameter descriptions. WebScraperTool has 'url' parameter; TelegramPosterTool has 'message', 'chat_id', 'bot_token'; TwitterPosterTool has 'text'; LinkedInPosterTool has 'commentary', 'image_urn'. None of these parameters have visible descriptions in the code.
Recommendations
Implement as a proper MCP server using the official MCP SDK (e.g., mcp.Server() in Python SDK). Provide a tools/ endpoint that returns proper MCP ToolDefinition objects with name, description, and inputSchema.
For each tool, write a complete description (50-200 characters) that answers: What does it do? When should the LLM call it? What does it return? Example for WebScraperTool: 'Fetches and extracts plain text content from a URL. Use this to gather article text, page content, or data before posting to social media. Returns extracted text and metadata.'
Add detailed descriptions to every input parameter. Example for TelegramPosterTool: message (string, 1-4096 chars): 'The message text to post. Markdown formatting is supported. Will be sent exactly as provided.'; chat_id (string): 'The Telegram channel ID (numeric or @handle). Must be a channel you have posting permissions for.'; bot_token: MUST BE MOVED to environment variable injection, NOT a parameter.
Move bot_token, API keys, and all credentials from tool parameters to server-side environment variable injection. At tool invocation time, fetch the token from os.environ or a secure vault, never from the LLM-provided parameters. Add descriptions noting: 'Uses pre-configured bot token from server environment.'
Implement structured error responses with classification and recovery hints. Example: Instead of returning {error: 'Connection timeout'}, return {error: 'Connection timeout while posting to Twitter', error_type: 'retryable', recovery_hint: 'Twitter API was unreachable. Retry in 30 seconds.', suggest_tool: 'retry_twitter_post_tool'}.
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Secrets exposed as parameters. TelegramPosterTool accepts 'bot_token' as a direct parameter. Use server-side secret injection via environment variables or vault.' This is a CRITICAL security issue.
No error handling or recovery guidance. The server has generic try/catch blocks returning error strings, but no structured error classification (retryable, user-fixable, fatal) or actionable recovery hints.
No confirmation or dry-run for destructive operations. TelegramPosterTool, TwitterPosterTool, and LinkedInPosterTool are write operations that modify external state. No dry-run, no confirmation step. Agents make mistakes, a confirm_before_execute pattern prevents catastrophic errors.'
No permission gates or audit trails. No visible checks for user authority before executing write operations. No logging of who called what tool, with which parameters, when, and what happened. Log who called what tool, with which parameters, at what time, and what happened.'
Tool composition issues: no clear output schema. The /predict and /enhance endpoints return unstructured responses. LLMs need to know what fields to expect so they can plan downstream tool calls and extract the right data.' No documentation of what these endpoints return.
Add dry-run mode to write tools. Add a 'dry_run' boolean parameter (default false) to TelegramPosterTool, TwitterPosterTool, LinkedInPosterTool. When true, return what WOULD be posted without actually posting. Example response: {status: 'dry_run', message: 'Would post to Telegram', preview: '...'} instead of actually sending.
Implement permission checks before executing write operations. Before posting, verify the calling user/agent has permission to post to that channel/account. Return a 403 Forbidden with guidance if not authorized.
Add comprehensive audit logging. Log every tool call with: timestamp, calling_user_id, tool_name, parameters (scrubbed of secrets), result status (success/failure), and any errors. Use structured logging (JSON) for downstream analysis.
Document output schemas for all tools. For WebScraperTool, specify: returns {content: string, url: string, title: string, extracted_at: ISO8601_timestamp}. For TwitterPosterTool: returns {status: string, tweet_id: string, url: string, posted_at: ISO8601_timestamp}. Include these in MCP ToolDefinition.
For tools accepting identifiers (chat_id, user_id), accept human-readable names too. E.g., TelegramPosterTool should accept both 'my-channel-name' and numeric IDs, resolving names to IDs internally. Add a description: 'Telegram channel ID or name (e.g., @my_channel or 123456789).'
Add pagination and limits to any tools returning lists. Cap results at 50 items by default with a limit parameter (1-100). Return total_count and next_cursor for efficient paging.
Implement rate limiting to prevent runaway agents. Add per-user/per-token rate limits (e.g., 10 posts per minute). Return 429 Too Many Requests with a Retry-After header and guidance: 'Rate limit exceeded. Retry after 60 seconds.'
Validate all inputs early and return actionable errors. Example: if TwitterPosterTool receives text > 280 chars, return 'Tweet too long (got 312 chars, max 280). Shorten your text and retry.' not 'Invalid input'.
If tools call external APIs, set explicit timeouts (e.g., 15 seconds). Return a timeout error with retry guidance: 'Twitter API did not respond within 15 seconds. Check your connection and retry.'
For multi-step operations (e.g., create media, then post), provide compensation tools to undo completed steps. If media upload succeeds but posting fails, offer a delete_media tool path.
Adopt tool annotations from the MCP spec: readOnlyHint for WebScraperTool (read-only operation), destructiveHint for TwitterPosterTool/TelegramPosterTool/LinkedInPosterTool (irreversible writes). This helps clients apply appropriate UI constraints and rate limiting.