Architecture
Project structure, tech stack, data model, and SaaS mode.
Tech stack
- Framework: Next.js 16 with App Router, React 19, Turbopack
- Auth: NextAuth v5 with GitHub OAuth
- Storage: AWS S3 SDK v3 (any S3-compatible service)
- UI: shadcn/ui + Tailwind CSS 4 + Lucide icons
- Docs: Fumadocs with MDX
- Fonts: Inter (sans) + Geist Mono (monospace)
- Editor: @uiw/react-md-editor for markdown with preview
- CLI: TypeScript with Commander.js, published as
intertoolon npm
Project structure
app/
├── (auth)/sign-in/ # Sign-in page
├── (main)/
│ ├── settings/ # Admin settings, members, tokens
│ ├── brand/ # Brand kit page
│ ├── browse/ # Browse & filter registry
│ ├── dashboard/ # User dashboard
│ ├── design-system/ # Design system reference
│ ├── publish/ # Publish wizard (upload + manual)
│ └── skills/[slug]/ # Skill detail, edit, versions
├── api/
│ ├── admin/settings/ # S3 config (GET/PUT/POST)
│ ├── audit-log/ # Admin audit log API
│ ├── cli-auth/ # CLI authentication flow
│ ├── import/ # GitHub repo import
│ ├── me/ # Current user info
│ ├── members/ # Member management
│ ├── orgs/ # Org management (SaaS mode)
│ ├── publish/ # Publish API (form + bearer auth)
│ ├── search/ # Search API
│ ├── skills/ # Skills CRUD API
│ └── tokens/ # API token management
├── docs/ # Fumadocs route handler
├── llms.txt/ # LLM-friendly docs index
├── llms-full.txt/ # Full LLM-friendly docs corpus
├── robots.ts # Public crawl rules
├── sitemap.ts # Public sitemap
└── opengraph-image.tsx # Dynamic social preview image
cli/
├── src/
│ ├── commands/ # CLI commands (install, publish, search, etc.)
│ ├── lib/ # API client, config, formatting
│ └── index.ts # CLI entry point
components/
├── command-palette.tsx # Cmd+K search
├── edit-skill-form.tsx # Edit skill form with versioning
├── filter-sidebar.tsx # Browse filters (type, category, sort)
├── header.tsx # App header with nav, search, user menu
├── footer.tsx # App footer
├── markdown-editor.tsx # Rich markdown editor
├── publish-wizard.tsx # Multi-step publish (upload + manual)
├── skill-card.tsx # Skill list card
├── skill-readme.tsx # Markdown renderer
├── install-command.tsx # Copy-to-clipboard install command
└── ui/ # shadcn/ui primitives
content/
└── docs/ # MDX documentation pages
lib/
├── api-auth.ts # API auth (session + bearer token)
├── audit-log.ts # Governance audit event storage
├── auth.ts # NextAuth v5 config (GitHub OAuth)
├── constants.ts # Type labels, colors, config
├── org.ts # Org slug resolution (SaaS mode)
├── rbac.ts # Role-based access control
├── registry.ts # S3-backed data layer
├── s3.ts # S3 client wrapper
├── seo.ts # Canonical origin, metadata, and JSON-LD helpers
├── settings.ts # Settings store (file + env + KV)
└── types.ts # TypeScript interfacesPublic discovery surface
Intertool is private by default, so search indexing focuses on public product and documentation pages. robots.txt allows /, /pricing, /brand, /docs/, /llms.txt, and /llms-full.txt, and disallows private registry, settings, auth, and API routes. sitemap.xml lists the canonical public pages. NEXT_PUBLIC_SITE_URL controls the absolute origin used in canonical metadata, Open Graph data, sitemaps, and LLM docs links.
The root layout emits global JSON-LD for the Intertool application, organization, website, and LLM documentation endpoints. Docs pages emit TechArticle and breadcrumb JSON-LD.
Data model
All skill data lives in your S3 bucket:
s3://your-bucket/
├── skills/{slug}/
│ ├── skill.json # current version
│ ├── files/ # optional package files
│ │ └── README.md
│ └── versions/
│ ├── 1.0.0.json # version snapshots
│ └── 1.0.1.json
├── mcp-servers/{slug}/skill.json
├── agent-tools/{slug}/skill.json
├── prompt-templates/{slug}/skill.json
├── _index.json # auto-rebuilt catalog
└── _categories.json # seeded on first setupSkill types
| Type | S3 folder | Description | Auto-detected from |
|---|---|---|---|
| Skill | skills/ | Claude Code skills | SKILL.md, skill.yaml |
| MCP Server | mcp-servers/ | Model Context Protocol servers | server.json |
| Agent Tool | agent-tools/ | Reusable tools for AI agents | skill.yaml |
| Prompt Template | prompt-templates/ | Shared prompt patterns | skill.yaml |
Access control
Intertool uses role-based access control (RBAC) with three roles:
| Role | Permissions |
|---|---|
| Owner | Full access: settings, members, tokens, publish, edit, delete, transfer ownership |
| Admin | Manage settings, members, tokens, and all registry items |
| Member | Publish and edit own items, browse and install all |
The first user, or the user specified in INTERTOOL_ADMIN, is assigned the owner role. New users are assigned the member role by default in self-hosted mode.
Governance
Registry items have a status lifecycle: review, published, or archived for org-visible workflows, with draft reserved for future server-side draft storage. Browse, search, CLI install, and API list endpoints only return published items.
Admins can enable publish_review_required in settings. When enabled, new member submissions are stored with review status and appear in /review. Owners and admins approve or archive them through PATCH /api/skills/:slug.
Audit events are written through lib/audit-log.ts for org creation, settings changes, member changes, submissions, status transitions, and deletions. Redis-backed deployments store events under audit:{org}, while local/self-hosted fallback stores best-effort events in registry/audit-log.json.
SaaS mode
Intertool supports multi-tenant SaaS mode with path-based organization routing. Each organization gets its own path (for example, intertool.sh/acme) with isolated settings and data stored in Upstash Redis.
SaaS mode is activated by setting INTERTOOL_MODE=saas and configuring Redis credentials.