推しアイデア
デプロイ先のインフラ構成が「運」できまるところです
―
デプロイ先のインフラ構成が「運」できまるところです
MCPの使い方を学びたくて、話題のAIエージェントで活用した。
自作MCPで一覧取得だけで終わらず、記事URLを指定して本文まで取得し実装の詳細を参照できるようにしたことで、AIの負担の減らした。
チャットで要望を伝えるだけでアプリをAIが生成し、ブラウザでその場プレビューし、気に入ったらワンクリックでデプロイできるWebアプリです。
フロントエンド: React + Vite + Tailwind CSS バックエンド: Express Claude API MCP :topaz.devを参照してアイデア検索、技術流用
ユーザーがチャットで作りたいアプリを伝える バックエンドが会話履歴、現在のコードをClaudeに渡し、ReactコンポーネントのJSXを生成/修正 生成されたJSXをBabelでブラウザ実行可能なHTMLに変換し、iframeでプレビュー表示
要望が曖昧な場合はClaudeが質問を返し、明確になってから生成する対話型の作り込みが可能
ユーザーが「何でもいいから作って」のように具体的なアイデアを持っていない場合、topaz.devの最新プロジェクト・レシピを取得し、Claudeがアイデア出しの材料として利用できる仕組みになっています。
topaz.dev(プロジェクト・レシピ共有サイト)をcheerioでスクレイピングし、3つのツールをClaudeに提供します。
用途 ツール1 get_trending_ideas 一覧ページを取得し、extractArticlesでカードのタイトル・タグ・URLを抜き出して上位8件を整形 「何でもいいから作って」と言われた時のアイデア出し
server.tool( "get_trending_ideas", "topaz.devの最新プロジェクト・レシピからアイデアと使用技術を取得します。", { type: z.enum(["projects", "recipes", "both"]).default("both"), }, async ({ type }) => { const targets = type === "both" ? ["projects", "recipes"] : [type]; const allArticles: string[] = []; for (const t of targets) { const html = await fetchHtml(`${BASE_URL}/${t}`); const $ = cheerio.load(html); const articles = extractArticles($, t).slice(0, 8); allArticles.push( articles .map((a) => `${a.title} | ${a.tags.join(", ")} | ${a.url}`) .join("\n") ); } return { content: [{ type: "text", text: allArticles.join("\n\n") }], }; } );
ツール2 search_by_technology 、type ?tags=クエリ付きURLを叩いて技術タグで絞り込み検索。該当なしならisError: trueを返す 「Reactで何か作って」など技術指定がある依頼
server.tool( "search_by_technology", "topaz.devで指定した技術タグのプロジェクト・レシピを検索します。", { tag: z.string(), type: z.enum(["projects", "recipes", "both"]).default("both"), }, async ({ tag, type }) => { const targets = type === "both" ? ["projects", "recipes"] : [type]; const allResults: string[] = []; for (const t of targets) { const url = `${BASE_URL}/${t}?tags=${encodeURIComponent(tag)}`; const html = await fetchHtml(url); const $ = cheerio.load(html); const articles = extractArticles($, t); if (articles.length === 0) continue; allResults.push( articles .map((a) => `${a.title} | ${a.tags.join(", ")} | ${a.url}`) .join("\n") ); } if (allResults.length === 0) { return { content: [{ type: "text", text: `「${tag}」が見つかりません` }], isError: true }; } return { content: [{ type: "text", text: allResults.join("\n\n") }], }; } );
ツール3 get_article_content 記事URLの本文をscript/style/nav除去のうえテキスト化、アイデアの実装詳細をさらに深掘りしたい時に(AIの負担を減らすためです。)
server.tool( "get_article_content", "topaz.devのプロジェクト・レシピURLを指定して本文を取得します。", { url: z.string().url(), }, async ({ url }) => { const html = await fetchHtml(url); const $ = cheerio.load(html); $("script, style, nav, footer, header").remove(); const content = $("main").text() || $("article").text() || $("body").text(); const cleaned = content.replace(/\s+/g, " ").trim(); return { content: [{ type: "text", text: cleaned.slice(0, 8000) }], }; } );
extractArticlesが共通のスクレイピングロジックで、a[href^="/projects/"]のようなリンクを起点にカード要素のテキストからタイトル1行目とタグリンク(?tags=)を抽出する、という素朴だが実用的なDOM解析になっています。
おおえ: ・ガチャ要素もっと増やしたかった!! ひかる: ・オーマイごっどanthropic