
エージェントネイティブ
フルスタックフレームワーク
AI がコードをこぼしても、餃子は破れません。🥟
エンジニアリングの悩み、フレームワークに任せて。100+ MCP ツール · 実戦 Skills ワークフロー · ランタイム Guard。
コーディングエージェントが1日1万行、
誰が解決しますか?
構造的なガードレールなしでは、AI 生成コードはすぐに技術的負債の山になります。
機能の肥大化
AI エージェントが重複ユーティリティを作り、既存パターンを無視し、コードベースを肥大化させます。
→ negotiate + Skills で構造を統一
サイレント障害
生成された関数の奥深くに埋もれたロジックエラー。基本テストは通るが本番で失敗します。
→ ATE がテストを書いて自動ヒール
アーキテクチャドリフト
AI が境界を理解せずにコードを貼り付け、クリーンアーキテクチャが劣化します。
→ Guard が実行時に境界を強制
何が入っていますか?
同じ指示、3回目ですか?
スキーマ1ファイル。 API・型・テスト・検証を自動生成。 エージェントが外れたら Guard がランタイムで遮断。
アーキテクチャ、もう崩れていませんか?
レイヤー・命名・依存規則をランタイムで強制。 FSD・Clean・Hexagonal 6プリセット内蔵。 エージェントが外れたらその場で拒否。
// レイヤー違反検出
Agent "claude" blocked.
Reason: layer-violation: shared → features
アーキテクチャ保護済 ✅
API 30行が Filling 3行に。
Mandu.filling(contract, ctx => ctx.ok(data))。 ミドルウェアチェーンは .guard() で合成。 ctx 一つにセッション・CSRF・DB 全部。
エージェントは Mandu を理解します。
MCP 100+ ツールで構造・契約・規則すべて参照可能。 Claude/Codex が推測なしに直接実行。 プロンプトエンジニアリングの代わりにツール呼び出し。
テスト、まだ手で書いていますか?
ATE がルートから Playwright spec を自動生成。 L0〜L3 オラクルレベル選択(スモーク〜契約検証)。 失敗すると LLM が修正 diff を提案。
AI のミス、ワンクリックで戻す。
mandu change begin で AI 編集前のスナップショット。 ミスなら rollback、問題なければ commit。 ブランチなしでファイル単位の原子的な復元。
Next · Remix · Hono と何が違いますか?
| 機能 | Mandu 🥟 | Next.js | Remix | Hono |
|---|---|---|---|---|
| ランタイム | Bun-native | Node/Edge | Node/CF | Bun/Node/Deno |
| 型 ↔ API | スキーマ1ファイル → 型・OpenAPI・テスト派生 | 手動同期 | 手動同期 | Zod middleware 手動 |
| アーキテクチャ強制 | Guard ランタイム | ESLint | なし | なし |
| テスト自動化 | ATE 自動生成・ヒール | 手動 | 手動 | 手動 |
| エージェントインターフェース | MCP 100+ ツール内蔵 | Plugin | Plugin | Plugin |
| AI 編集ロールバック | change begin/commit/rollback | git 手動 | git 手動 | git 手動 |
| デプロイ先 | 4 edge + 7 deploy アダプタ | Vercel 優先 | Multi | Multi |
| DB クライアント | Bun.SQL (Postgres·MySQL·SQLite) | — | — | — |
| Auth / セッション | セッション·JWT·OAuth·メール内蔵 | サードパーティ | サードパーティ | サードパーティ |
ハンドラー6行、スキーマ8行。
30行1ファイルが2ファイル14行に。同じ /api/signup エンドポイント。
import { z } from "zod";
import { NextRequest, NextResponse } from "next/server";
import { db, hash, isRateLimited } from "@/lib";
const SignupSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
export async function POST(req: NextRequest) {
const csrf = req.headers.get("x-csrf-token");
if (csrf !== req.cookies.get("__csrf")?.value)
return NextResponse.json({ error: "csrf" }, { status: 403 });
if (await isRateLimited(req.ip))
return NextResponse.json({ error: "rate" }, { status: 429 });
const raw = await req.json().catch(() => null);
const parsed = SignupSchema.safeParse(raw);
if (!parsed.success)
return NextResponse.json({ error: parsed.error.flatten() }, { status: 400 });
try {
const user = await db.user.create({
data: {
email: parsed.data.email,
password: await hash(parsed.data.password),
},
});
return NextResponse.json({ id: user.id }, { status: 201 });
} catch (err) {
if ((err as any).code === "P2002")
return NextResponse.json({ error: "duplicate" }, { status: 409 });
return NextResponse.json({ error: "internal" }, { status: 500 });
}
}import { Mandu } from "@mandujs/core"; import { SignupContract } from "@/spec/contracts/signup.contract"; export default Mandu.filling(SignupContract, async (ctx) => ctx.ok(await ctx.db.user.create({ ...ctx.body })) ).guard("auth").rateLimit({ rpm: 10 });
import { defineContract } from "@mandujs/core/contract"; import { z } from "zod"; export const SignupContract = defineContract({ method: "POST", request: z.object({ email: z.string().email(), password: z.string().min(8) }), response: z.object({ id: z.string() }), });
1つのコマンドで7ヶ所。
プラットフォーム設定ファイルは Mandu が自動生成。wrangler.toml · vercel.json · Dockerfile · …
互換性あり
