Why low-level handlers
Decorator-based tools need their schemas at import time. Here the schemas only exist after Composio discovery, so the server implements list_tools and call_tool directly and maps schemas on the fly.
An MCP server that gives Claude and ChatGPT 36 allow-listed Instagram actions through Composio, built to keep working when OAuth is unfinished or the upstream is down.
Claude and ChatGPT cannot act on an Instagram Business account (posts, carousels, comments, DMs, insights) without Graph API OAuth and glue code for every endpoint. The server has to expose those actions safely, on a serverless runtime with a read-only filesystem, and stay usable when the OAuth connection is not finished.
01
FastMCP serves the MCP protocol over streamable HTTP on the port the serverless runtime provides.
02
If the Instagram account is not connected yet, the server starts the OAuth flow, logs the redirect URL, and waits up to five minutes. On timeout it boots anyway, so the utility tools still work.
03
A low-level list_tools handler maps Composio's JSON schemas straight into MCP tools, limited to an allow-list of 36 actions. If discovery fails, the last known list is served from cache.
04
Any tool name that is not a utility passes through as a Composio action. Discovery retries with backoff, but writes do not: retrying after an unclear error could publish the same post twice.
05
Every exception comes back as an MCP error result instead of breaking the session, and each call is counted in per-tool stats exposed by the health tool.
Decorator-based tools need their schemas at import time. Here the schemas only exist after Composio discovery, so the server implements list_tools and call_tool directly and maps schemas on the fly.
The serverless runtime ignores the Dockerfile and mounts a read-only home directory, so anything the server writes goes to a temporary directory and falls back to memory if that fails too.
Both the Composio session and discovery are limited to the same 36 actions, so a client cannot reach an Instagram endpoint that was not deliberately exposed.
Python · MCP (FastMCP) · Composio · OAuth 2.0 · Pydantic · structlog · Docker · Alpic