Ailab Rip App
FreeNot checkedA demo MCP server that exposes stock-quote tools to LLMs via FastMCP over streamable HTTP. It can be deployed to AWS ECS and integrated with ChatGPT as a custom
About
A demo MCP server that exposes stock-quote tools to LLMs via FastMCP over streamable HTTP. It can be deployed to AWS ECS and integrated with ChatGPT as a custom connector.
README
A foundational demo of a Model Context Protocol (MCP) app. A tiny FastMCP server exposes a stock-quote tool from a bundled JSON file, runs locally over streamable HTTP, deploys to AWS via ECS Express Mode, and plugs into ChatGPT as a Developer Mode custom connector.
The point is the walkthrough, not the depth. The code is short enough to read in one sitting.
What is MCP
The Model Context Protocol is an open standard for wiring LLMs to external tools and data. An MCP server exposes capabilities — most commonly tools (functions the model can call) — and an MCP client (ChatGPT, Claude, your own agent) discovers and invokes them over a transport such as stdio or streamable HTTP. This repo is an MCP server.
Prerequisites
- Python 3.10+
- uv for dependency management (
brew install uvorcurl -LsSf https://astral.sh/uv/install.sh | sh) - Docker (for the AWS deploy)
- AWS CLI v2 with a configured profile that can create ECR repos and ECS services
- Node.js (only for
npx @modelcontextprotocol/inspectorduring local verification) - A ChatGPT account that can enable Developer Mode — see the ChatGPT integration section
Repo tour
.
├── src/
│ ├── server.py # FastMCP server, two tools + widget resource
│ └── data/quotes.json # 10 hand-curated tickers
├── web/ # React + Vite widget (Apps SDK compatible)
│ ├── src/ # StockCard.tsx, main.tsx, styles.css
│ ├── dist/stock-card.js # built bundle (committed — server needs no npm)
│ └── package.json
├── tests/ # pytest + in-memory FastMCP Client
├── scripts/push_to_ecr.sh # build + push helper
├── Dockerfile # uv-based image, exposes 8000
├── pyproject.toml # uv-managed deps
└── uv.lock # locked deps (committed)
Install and test
uv sync # create .venv from uv.lock
uv run pytest # 4 tests, in-memory, ~40 ms
Run locally and verify with MCP Inspector
uv run python src/server.py
# → FastMCP banner shows http://0.0.0.0:8000/mcp
In another shell:
npx @modelcontextprotocol/inspector
In the Inspector UI: Transport = Streamable HTTP, URL =
http://localhost:8000/mcp, then invoke:
list_supported_symbols→ 10 tickersget_stock_quotewithsymbol="AAPL"→ the seeded dict +day_change_pctget_stock_quotewithsymbol="ZZZZ"→ a tool error naming the supported symbols
Deploy to AWS with ECS Express Mode
ECS Express Mode is AWS's newest single-command path for containerized services. It auto-provisions the ECS cluster, Fargate task, ALB with HTTPS, target group, security groups, and auto-scaling from one API call — exactly what a ChatGPT connector needs.
1. Build and push the image to ECR
./scripts/push_to_ecr.sh
# → prints IMAGE_URI=<account>.dkr.ecr.<region>.amazonaws.com/mcp-stock-quote:latest
Overridable env vars: AWS_REGION, AWS_PROFILE, ECR_REPO_NAME,
IMAGE_TAG. The script builds for linux/amd64 explicitly — required for
Fargate x86 tasks when the dev machine is Apple silicon.
2. Deploy to ECS Express (via glab_iac)
Infrastructure lives in the sibling glab_iac Terraform repo. Add a new ECS Express block that points to the ECR image you just pushed, then apply:
- In
glab_iac, add a new ECS Express service block. Set:image→ theIMAGE_URIprinted bypush_to_ecr.sh.container_port→8000(what the FastMCP server binds to).health_check_path→/health.
terraform planand review — Express Mode auto-provisions the cluster, Fargate task, ALB with HTTPS, target group, security groups, IAM roles, and auto-scaling.terraform apply. Wait until the service reportsRUNNINGand its ALB target group reports healthy (a few minutes).- Grab the public HTTPS URL from the Terraform output (or the ECS
console). Your MCP endpoint is
https://<generated-domain>/mcp.
Verify with MCP Inspector or a quick curl before wiring ChatGPT:
curl -s https://<generated-domain>/health # → {"status":"ok"}
Then integrate it as a custom connector — see the next section.
Region caveat: ECS Express Mode is new (announced late 2025) and not yet available in every AWS region. Check the ECS console in your region.
Integrate with ChatGPT (Developer Mode)
All quotes below come from OpenAI's custom MCP docs.
Requirements
- ChatGPT subscription — Developer Mode is a gated feature. OpenAI's developer docs don't spell out the tier list; the authoritative source is help.openai.com article 11487775. Historically: Plus, Pro, Business, Enterprise, Edu. Free tier cannot follow this section.
- Developer Mode toggled on —
"In ChatGPT, open Settings → Security and login and turn on Developer mode."
- Server transport — public HTTPS URL, streamable-HTTP transport, path
/mcp. ECS Express Mode + FastMCP's defaults give you all three.
For this demo we use no authentication. OpenAI's docs neither mandate nor explicitly forbid it — a personal Developer Mode server only you connect to works fine unauthenticated, and it keeps the demo focused on MCP itself. This is dev-only. Production connectors should use OAuth.
Add the connector
- ChatGPT → Menu → Plugins → Add (+).
- Paste
https://<ecs-express-domain>/mcp. - Leave authentication empty: No Auth (dev-only).
- Save.
- Connect.
- Check at Plugins (browse until you find yours).
Try it
Prompt ChatGPT:
Using the stock quote connector, what is AAPL's current price? @stock_mcp_app what is AAPL's current price?
The trace panel should show a call to list_supported_symbols and/or
get_stock_quote. Both tools are read-only, so no confirmation prompt
appears.
The widget (sharing UI back to ChatGPT)
Chapter one served pure JSON and let ChatGPT paint a paragraph. Chapter two
attaches a small React "stock card" to every get_stock_quote result so
ChatGPT renders it inline. Two pieces make this work:
The tool declares its template and a typed return. In
src/server.py:@mcp.tool(meta={"openai/outputTemplate": "ui://stock-card/v1.html"}) def get_stock_quote(symbol: str) -> Quote: ...Two things matter here: the
_metafield points at the widget resource, and theQuoteTypedDict return makes FastMCP emit anoutputSchema. Without that schema, ChatGPT filterswindow.openai.toolOutputdown to a handful of fields — the widget wouldn't see the price.The resource ships the widget. Same file:
@mcp.resource("ui://stock-card/v1.html", mime_type="text/html;profile=mcp-app") def stock_card_widget() -> str: return _WIDGET_HTML # <div id="root"></div> + inlined React bundleThe mime type
text/html;profile=mcp-appis what tells ChatGPT to render this inside a sandboxed iframe next to the assistant reply. The React bundle inweb/dist/stock-card.jsreadswindow.openai.toolOutput(found by walking up the frame chain to the host frame) and paints a price card.
Editing the widget. Only needed if you want to change the UI itself — the server ships the built bundle:
cd web
npm install
npm run build # -> web/dist/stock-card.js
The bundle is committed on purpose so uv run python src/server.py works
without a JS toolchain. Rebuild the container after any widget change so the
new bundle ships to ECS. In ChatGPT, hit Refresh on the connector (or
remove + re-add) so it picks up any schema changes, then start a new chat.
Gotchas we hit. Two Apps SDK details worth knowing:
- Vite's
libmode doesn't replaceprocess.env.NODE_ENV. Withoutdefine: { "process.env.NODE_ENV": '"production"' }invite.config.ts, the widget throwsReferenceError: process is not definedin the sandbox. window.openaiis only injected on the outer host frame. Widgets rendered in a nested iframe must walk up (window.parent,window.top) to reach it — seeweb/src/main.tsx.
Limitations and next steps
- Static data — real prices need something like yfinance; note its ToS.
- No auth — add OAuth via FastMCP's built-in auth providers before making the server public.
- No infrastructure-as-code — Express Mode is one CLI call. For repeatable environments, port to CloudFormation (aws-samples/sample-mcp-server-on-ecs) or CDK.
- Single-stage Docker image — split builder/runtime stages to shrink the image.
Links
- FastMCP docs — https://gofastmcp.com
- OpenAI custom MCP connectors — https://developers.openai.com/api/docs/mcp
- ECS Express Mode launch post — https://aws.amazon.com/blogs/aws/build-production-ready-applications-without-infrastructure-complexity-using-amazon-ecs-express-mode/
- Deploying MCP on ECS (AWS blog) — https://aws.amazon.com/blogs/containers/deploying-model-context-protocol-mcp-servers-on-amazon-ecs/
- uv — https://astral.sh/uv
Installing Ailab Rip App
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/gonzalogarcia-ai/start-with-mcp-appsFAQ
Is Ailab Rip App MCP free?
Yes, Ailab Rip App MCP is free — one-click install via Unyly at no cost.
Does Ailab Rip App need an API key?
No, Ailab Rip App runs without API keys or environment variables.
Is Ailab Rip App hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Ailab Rip App in Claude Desktop, Claude Code or Cursor?
Open Ailab Rip App on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectCompare Ailab Rip App with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
