feat: initial commit - Jhonny Editor
- Adicionado estrutura completa do projeto - Configurado MCP server para Premiere Pro - Adicionado documentação e skills - Configurado Gitignore para o projeto
@@ -0,0 +1,41 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/versions
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# env files (can opt-in for committing if needed)
|
||||
.env*
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
@@ -0,0 +1,36 @@
|
||||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||
@@ -0,0 +1,218 @@
|
||||
import type { Metadata } from "next"
|
||||
import Link from "next/link"
|
||||
import { notFound } from "next/navigation"
|
||||
import { TrackedLink } from "@/components/ui/tracked-link"
|
||||
import { articleBySlug, articles } from "@/lib/articles"
|
||||
|
||||
type ArticlePageProps = {
|
||||
params: Promise<{ slug: string }>
|
||||
}
|
||||
|
||||
export const dynamic = "force-static"
|
||||
const socialImage = "/marketing/premiere-pro-mcp-social-square-v1.png"
|
||||
|
||||
const articleDateFormatter = new Intl.DateTimeFormat("en-US", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
timeZone: "UTC",
|
||||
year: "numeric",
|
||||
})
|
||||
|
||||
function formatArticleDate(date: string) {
|
||||
return articleDateFormatter.format(new Date(`${date}T00:00:00Z`))
|
||||
}
|
||||
|
||||
export function generateStaticParams() {
|
||||
return articles.map(({ slug }) => ({ slug }))
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: ArticlePageProps): Promise<Metadata> {
|
||||
const { slug } = await params
|
||||
const article = articleBySlug.get(slug)
|
||||
|
||||
if (!article) {
|
||||
return {}
|
||||
}
|
||||
|
||||
return {
|
||||
title: article.title,
|
||||
description: article.description,
|
||||
keywords: article.keywords,
|
||||
alternates: { canonical: `/blog/${article.slug}/` },
|
||||
openGraph: {
|
||||
title: article.title,
|
||||
description: article.description,
|
||||
url: `/blog/${article.slug}/`,
|
||||
type: "article",
|
||||
publishedTime: article.publishedAt,
|
||||
modifiedTime: article.modifiedAt,
|
||||
authors: ["MCP for Adobe Premiere Pro contributors"],
|
||||
images: [{ url: socialImage, width: 1254, height: 1254, alt: "Premiere Pro MCP — reviewable workflow automation" }],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: article.title,
|
||||
description: article.description,
|
||||
images: [socialImage],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default async function ArticlePage({ params }: ArticlePageProps) {
|
||||
const { slug } = await params
|
||||
const article = articleBySlug.get(slug)
|
||||
|
||||
if (!article) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
const relatedArticles = article.relatedSlugs
|
||||
? article.relatedSlugs
|
||||
.map((relatedSlug) => articleBySlug.get(relatedSlug))
|
||||
.filter((related): related is (typeof articles)[number] => Boolean(related))
|
||||
: articles.filter((candidate) => candidate.slug !== article.slug).slice(0, 2)
|
||||
const articleUrl = `https://premiere-pro-mcp.com/blog/${article.slug}/`
|
||||
const structuredData = {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "Article",
|
||||
"@id": `${articleUrl}#article`,
|
||||
headline: article.title,
|
||||
description: article.description,
|
||||
url: articleUrl,
|
||||
datePublished: article.publishedAt,
|
||||
dateModified: article.modifiedAt,
|
||||
inLanguage: "en-US",
|
||||
author: {
|
||||
"@type": "Organization",
|
||||
name: "MCP for Adobe Premiere Pro contributors",
|
||||
url: "https://github.com/leancoderkavy/premiere-pro-mcp",
|
||||
},
|
||||
publisher: { "@id": "https://premiere-pro-mcp.com/#organization" },
|
||||
mainEntityOfPage: articleUrl,
|
||||
keywords: article.keywords.join(", "),
|
||||
image: `https://premiere-pro-mcp.com${socialImage}`,
|
||||
},
|
||||
{
|
||||
"@type": "FAQPage",
|
||||
"@id": `${articleUrl}#faq`,
|
||||
mainEntity: article.faqs.map((faq) => ({
|
||||
"@type": "Question",
|
||||
name: faq.question,
|
||||
acceptedAnswer: { "@type": "Answer", text: faq.answer },
|
||||
})),
|
||||
},
|
||||
{
|
||||
"@type": "BreadcrumbList",
|
||||
"@id": `${articleUrl}#breadcrumb`,
|
||||
itemListElement: [
|
||||
{ "@type": "ListItem", position: 1, name: "MCP for Adobe Premiere Pro", item: "https://premiere-pro-mcp.com/" },
|
||||
{ "@type": "ListItem", position: 2, name: "Guides", item: "https://premiere-pro-mcp.com/blog/" },
|
||||
{ "@type": "ListItem", position: 3, name: article.title, item: articleUrl },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
|
||||
/>
|
||||
<main id="main-content" className="min-h-screen bg-black px-5 py-12 text-zinc-100 sm:py-20">
|
||||
<article className="mx-auto max-w-3xl">
|
||||
<nav aria-label="Breadcrumb" className="text-sm text-zinc-500">
|
||||
<Link href="/" className="hover:text-purple-200">MCP for Adobe Premiere Pro</Link>{" "}
|
||||
<span aria-hidden="true">/</span>{" "}
|
||||
<Link href="/blog/" className="hover:text-purple-200">Guides</Link>{" "}
|
||||
<span aria-hidden="true">/</span> <span className="text-zinc-400">{article.eyebrow}</span>
|
||||
</nav>
|
||||
|
||||
<header className="border-b border-zinc-800 pb-10 pt-10 sm:pb-14 sm:pt-14">
|
||||
<p className="font-mono text-sm font-medium uppercase tracking-[0.15em] text-purple-300">{article.eyebrow}</p>
|
||||
<h1 className="mt-5 text-balance text-4xl font-bold tracking-tight text-white sm:text-6xl">{article.title}</h1>
|
||||
<p className="mt-6 text-lg leading-8 text-zinc-400">{article.description}</p>
|
||||
<div className="mt-7 flex items-center gap-3 text-sm text-zinc-500">
|
||||
<time dateTime={article.publishedAt}>Published {formatArticleDate(article.publishedAt)}</time>
|
||||
<span aria-hidden="true">·</span>
|
||||
<span>{article.readingTime}</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div className="py-10 sm:py-14">
|
||||
{article.sections.map((section) => (
|
||||
<section key={section.heading} className="border-b border-zinc-900 py-9 first:pt-0 last:border-b-0">
|
||||
<h2 className="text-2xl font-semibold tracking-tight text-white sm:text-3xl">{section.heading}</h2>
|
||||
<div className="mt-5 space-y-5 text-[1.0625rem] leading-8 text-zinc-300">
|
||||
{section.paragraphs.map((paragraph) => <p key={paragraph}>{paragraph}</p>)}
|
||||
</div>
|
||||
{section.bullets ? (
|
||||
<ul className="mt-6 list-disc space-y-3 pl-5 leading-7 text-zinc-300 marker:text-purple-300">
|
||||
{section.bullets.map((item) => <li key={item}>{item}</li>)}
|
||||
</ul>
|
||||
) : null}
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<section className="border-y border-zinc-800 py-10" aria-labelledby="faq-heading">
|
||||
<h2 id="faq-heading" className="text-2xl font-semibold tracking-tight text-white">Questions editors ask</h2>
|
||||
<div className="mt-6 divide-y divide-zinc-800">
|
||||
{article.faqs.map((faq) => (
|
||||
<details key={faq.question} className="group py-5">
|
||||
<summary className="cursor-pointer list-none pr-8 font-medium text-zinc-100 marker:content-none group-open:text-purple-200">
|
||||
{faq.question}
|
||||
</summary>
|
||||
<p className="mt-3 leading-7 text-zinc-400">{faq.answer}</p>
|
||||
</details>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="py-10" aria-labelledby="resources-heading">
|
||||
<h2 id="resources-heading" className="text-2xl font-semibold tracking-tight text-white">Keep learning</h2>
|
||||
<ul className="mt-5 space-y-3">
|
||||
{article.resources.map((resource) => (
|
||||
<li key={resource.href}>
|
||||
<a href={resource.href} className="font-medium text-purple-200 hover:text-white">
|
||||
{resource.label} <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section className="border border-purple-300/40 bg-purple-300/10 p-7 sm:p-9" aria-labelledby="start-heading">
|
||||
<p className="font-mono text-xs font-medium uppercase tracking-[0.15em] text-purple-200">A practical next step</p>
|
||||
<h2 id="start-heading" className="mt-3 text-2xl font-semibold tracking-tight text-white">Start with a safe Premiere connection check.</h2>
|
||||
<p className="mt-3 max-w-2xl leading-7 text-zinc-300">
|
||||
Connect your assistant, verify the local bridge without changing a project, then inspect the active sequence before requesting a supported edit.
|
||||
</p>
|
||||
<TrackedLink
|
||||
href="/#install"
|
||||
trackingLocation={`guide:${article.slug}`}
|
||||
trackingDestination="safe_connection_check"
|
||||
className="mt-6 inline-flex bg-purple-300 px-5 py-3 font-medium text-black transition-colors hover:bg-white"
|
||||
>
|
||||
Run a safe connection check <span aria-hidden="true" className="ml-2">→</span>
|
||||
</TrackedLink>
|
||||
</section>
|
||||
|
||||
<aside className="border-t border-zinc-800 py-10" aria-labelledby="related-heading">
|
||||
<h2 id="related-heading" className="text-xl font-semibold text-white">Related guides</h2>
|
||||
<div className="mt-5 grid gap-4 sm:grid-cols-2">
|
||||
{relatedArticles.map((related) => (
|
||||
<Link key={related.slug} href={`/blog/${related.slug}/`} className="border border-zinc-800 p-5 transition-colors hover:border-purple-400/60">
|
||||
<p className="font-mono text-xs uppercase tracking-[0.12em] text-purple-300">{related.eyebrow}</p>
|
||||
<p className="mt-3 font-semibold text-zinc-100">{related.title}</p>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</aside>
|
||||
</article>
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import type { Metadata } from "next"
|
||||
import Link from "next/link"
|
||||
import { TrackedLink } from "@/components/ui/tracked-link"
|
||||
import { articles } from "@/lib/articles"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Premiere Pro AI Editing & Automation Guides",
|
||||
description:
|
||||
"Practical guides to AI-assisted video editing, Premiere Pro workflow automation, and using a local MCP server without giving up creative control.",
|
||||
alternates: { canonical: "/blog/" },
|
||||
openGraph: {
|
||||
title: "Premiere Pro AI Editing & Automation Guides",
|
||||
description:
|
||||
"Practical, local-first guides to AI-assisted video editing and Adobe Premiere Pro workflow automation.",
|
||||
url: "/blog/",
|
||||
type: "website",
|
||||
},
|
||||
}
|
||||
|
||||
const structuredData = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "CollectionPage",
|
||||
"@id": "https://premiere-pro-mcp.com/blog/#collection",
|
||||
name: "MCP for Adobe Premiere Pro Guides",
|
||||
description:
|
||||
"Practical guides to AI-assisted video editing, Premiere Pro automation, and local MCP workflows.",
|
||||
url: "https://premiere-pro-mcp.com/blog/",
|
||||
isPartOf: { "@id": "https://premiere-pro-mcp.com/#website" },
|
||||
mainEntity: {
|
||||
"@type": "ItemList",
|
||||
itemListElement: articles.map((article, index) => ({
|
||||
"@type": "ListItem",
|
||||
position: index + 1,
|
||||
url: `https://premiere-pro-mcp.com/blog/${article.slug}/`,
|
||||
name: article.title,
|
||||
})),
|
||||
},
|
||||
}
|
||||
|
||||
const articleDateFormatter = new Intl.DateTimeFormat("en-US", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
timeZone: "UTC",
|
||||
year: "numeric",
|
||||
})
|
||||
|
||||
function formatArticleDate(date: string) {
|
||||
return articleDateFormatter.format(new Date(`${date}T00:00:00Z`))
|
||||
}
|
||||
|
||||
export default function BlogPage() {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
|
||||
/>
|
||||
<main id="main-content" className="min-h-screen bg-black px-5 py-16 text-zinc-100 sm:py-24">
|
||||
<div className="mx-auto max-w-6xl">
|
||||
<nav aria-label="Breadcrumb" className="text-sm text-zinc-500">
|
||||
<Link href="/" className="hover:text-purple-200">MCP for Adobe Premiere Pro</Link>{" "}
|
||||
<span aria-hidden="true">/</span> Guides
|
||||
</nav>
|
||||
<header className="max-w-3xl border-b border-zinc-800 pb-12 pt-10 sm:pb-16">
|
||||
<p className="font-mono text-sm font-medium tracking-[0.16em] text-purple-300">MCP FOR ADOBE PREMIERE PRO GUIDES</p>
|
||||
<h1 className="mt-5 text-balance text-4xl font-bold tracking-tight text-white sm:text-6xl">
|
||||
Practical guides for AI-assisted Premiere workflows.
|
||||
</h1>
|
||||
<p className="mt-6 text-lg leading-8 text-zinc-400">
|
||||
Learn where an AI assistant can help, how structured MCP tools fit into Adobe Premiere Pro,
|
||||
and how to keep every workflow local-first, bounded, and reviewable.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<section className="grid gap-6 py-12 md:grid-cols-2" aria-label="MCP for Adobe Premiere Pro guides">
|
||||
{articles.map((article, index) => (
|
||||
<article key={article.slug} className="flex min-h-full flex-col border border-zinc-800 bg-zinc-950 p-6 transition-colors hover:border-purple-400/60 sm:p-7">
|
||||
<p className="font-mono text-xs font-medium uppercase tracking-[0.14em] text-purple-300">0{index + 1} · {article.eyebrow}</p>
|
||||
<h2 className="mt-5 text-2xl font-semibold tracking-tight text-white">
|
||||
<Link href={`/blog/${article.slug}/`} className="hover:text-purple-200">{article.title}</Link>
|
||||
</h2>
|
||||
<p className="mt-4 flex-1 leading-7 text-zinc-400">{article.description}</p>
|
||||
<div className="mt-7 flex items-center justify-between border-t border-zinc-800 pt-5 text-sm">
|
||||
<time dateTime={article.publishedAt} className="text-zinc-500">{formatArticleDate(article.publishedAt)}</time>
|
||||
<Link href={`/blog/${article.slug}/`} className="font-medium text-purple-200 hover:text-white">
|
||||
Read guide <span aria-hidden="true">→</span>
|
||||
</Link>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</section>
|
||||
|
||||
<section className="border-t border-zinc-800 py-12 sm:py-16">
|
||||
<p className="font-mono text-sm tracking-[0.14em] text-purple-300">READY TO TRY A BOUNDED WORKFLOW?</p>
|
||||
<h2 className="mt-4 text-3xl font-semibold tracking-tight text-white sm:text-4xl">Start with a read-only Premiere connection check.</h2>
|
||||
<p className="mt-4 max-w-2xl leading-7 text-zinc-400">
|
||||
Install the local server and connector, verify the live bridge without changing a project, then inspect your first sequence.
|
||||
</p>
|
||||
<TrackedLink
|
||||
href="/#install"
|
||||
trackingLocation="blog_hub"
|
||||
trackingDestination="safe_connection_check"
|
||||
className="mt-6 inline-flex border border-purple-300 bg-purple-300 px-5 py-3 font-medium text-black transition-colors hover:bg-white"
|
||||
>
|
||||
Run a safe connection check <span aria-hidden="true" className="ml-2">→</span>
|
||||
</TrackedLink>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
import type { Metadata } from "next"
|
||||
import Link from "next/link"
|
||||
import { product, safeFirstPrompt } from "@/lib/product"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "MCP for Adobe Premiere Pro Setup, Tools, Compatibility & Security",
|
||||
description: `Choose an AI assistant, connect MCP for Adobe Premiere Pro, explore ${product.coreToolCount} AI video editing tools, and understand Windows, macOS, CEP, UXP, and security support.`,
|
||||
alternates: { canonical: "/docs/" },
|
||||
openGraph: {
|
||||
title: "MCP for Adobe Premiere Pro Documentation",
|
||||
description: "Setup, capabilities, compatibility, architecture, and security for AI-assisted Adobe Premiere Pro editing.",
|
||||
url: "/docs/",
|
||||
type: "article",
|
||||
},
|
||||
}
|
||||
|
||||
const categories = [
|
||||
["Timeline editing", "Insert, overwrite, move, trim, split, ripple-delete, target tracks, and inspect sequence structure."],
|
||||
["Effects and color", "Apply effects, control Lumetri properties, add keyframes, use LUTs, and verify resulting values."],
|
||||
["Media and projects", "Import footage, organize bins, create sequences, inspect metadata, manage proxies, and save projects."],
|
||||
["Audio and captions", "Adjust verified audio levels, automate keyframes, mute tracks, create captions, and inspect audio state."],
|
||||
["Export", "Discover Adobe Media Encoder presets, export sequences and project items, and verify frame output on disk."],
|
||||
["Inspection and workflows", `The server registers ${product.coreToolCount} core tools. The default profile exposes ${product.defaultProfileToolCount}; a connected UXP panel exposes ${product.connectedUxpToolCount} capability-gated tools.`],
|
||||
]
|
||||
|
||||
const structuredData = {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "TechArticle",
|
||||
"@id": "https://premiere-pro-mcp.com/docs/#article",
|
||||
headline: "MCP for Adobe Premiere Pro setup, tools, compatibility, and security",
|
||||
description:
|
||||
"Installation and technical reference for connecting AI assistants to Adobe Premiere Pro with MCP for Adobe Premiere Pro.",
|
||||
url: "https://premiere-pro-mcp.com/docs/",
|
||||
dateModified: product.releaseDate,
|
||||
inLanguage: "en-US",
|
||||
about: { "@id": "https://premiere-pro-mcp.com/#software" },
|
||||
isPartOf: { "@id": "https://premiere-pro-mcp.com/#website" },
|
||||
},
|
||||
{
|
||||
"@type": "BreadcrumbList",
|
||||
"@id": "https://premiere-pro-mcp.com/docs/#breadcrumb",
|
||||
itemListElement: [
|
||||
{
|
||||
"@type": "ListItem",
|
||||
position: 1,
|
||||
name: product.name,
|
||||
item: "https://premiere-pro-mcp.com/",
|
||||
},
|
||||
{
|
||||
"@type": "ListItem",
|
||||
position: 2,
|
||||
name: "Documentation",
|
||||
item: "https://premiere-pro-mcp.com/docs/",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export default function DocsPage() {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
|
||||
/>
|
||||
<main id="main-content" className="min-h-screen bg-black px-5 py-16 text-zinc-100">
|
||||
<article className="mx-auto max-w-4xl">
|
||||
<nav aria-label="Breadcrumb" className="text-sm text-zinc-500">
|
||||
<Link href="/" className="hover:text-purple-300">MCP for Adobe Premiere Pro</Link> <span aria-hidden="true">/</span> Documentation
|
||||
</nav>
|
||||
|
||||
<header className="border-b border-zinc-800 pb-12 pt-12">
|
||||
<p className="font-mono text-sm text-purple-300">MCP FOR ADOBE PREMIERE PRO DOCUMENTATION</p>
|
||||
<h1 className="mt-4 text-balance text-4xl font-bold tracking-tight sm:text-6xl">AI editing tools for Adobe Premiere Pro</h1>
|
||||
<p className="mt-6 max-w-3xl text-lg leading-8 text-zinc-400">
|
||||
MCP for Adobe Premiere Pro is an open-source, local-first Model Context Protocol server that connects AI assistants to Adobe Premiere Pro through {product.coreToolCount} structured editing, inspection, automation, and export tools.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<section className="py-12" aria-labelledby="install-heading">
|
||||
<h2 id="install-heading" className="text-3xl font-semibold">Start without developer setup</h2>
|
||||
<p className="mt-5 max-w-3xl leading-8 text-zinc-400">The default route has two parts: your AI assistant gets a local server, and Premiere gets a separate connector. Claude Desktop is the recommended first route because the released bundle contains the server.</p>
|
||||
<ol className="mt-6 list-decimal space-y-3 pl-6 leading-7 text-zinc-300">
|
||||
<li><a className="font-medium text-purple-200 hover:text-white" href={product.downloads.claudeBundle}>Download the Claude Desktop bundle</a> and open it in Claude Desktop.</li>
|
||||
<li><a className="font-medium text-purple-200 hover:text-white" href={product.downloads.signedCepConnector}>Download the signed Premiere connector</a>. This is separate from the assistant bundle.</li>
|
||||
<li>Restart Claude Desktop and Premiere, then open a project.</li>
|
||||
<li>Send this read-only first prompt: <code className="rounded bg-zinc-900 px-2 py-1 text-purple-200">{safeFirstPrompt}</code></li>
|
||||
</ol>
|
||||
<p className="mt-6 leading-7 text-zinc-400">Cursor, VS Code / Copilot, and other MCP clients can use the supported local route too. A native one-click install for those clients is not currently shipped; use their MCP settings or the Advanced setup below.</p>
|
||||
<details className="mt-8 rounded-xl border border-zinc-800 bg-zinc-950 p-5">
|
||||
<summary className="cursor-pointer text-sm font-semibold text-zinc-100">Advanced: npm and manual configuration</summary>
|
||||
<p className="mt-4 text-sm leading-7 text-zinc-400">This route requires Node.js {product.nodeVersion}+ and is intended for clients without a native bundle.</p>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg bg-black p-4 text-sm text-emerald-300"><code>npm install -g premiere-pro-mcp{`\n`}premiere-pro-mcp --install-cep</code></pre>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg bg-black p-4 text-sm text-zinc-300"><code>{`{\n "mcpServers": {\n "premiere-pro": { "command": "premiere-pro-mcp" }\n }\n}`}</code></pre>
|
||||
</details>
|
||||
</section>
|
||||
|
||||
<section className="border-t border-zinc-800 py-12" aria-labelledby="tools-heading">
|
||||
<h2 id="tools-heading" className="text-3xl font-semibold">What can an AI assistant do in Premiere Pro?</h2>
|
||||
<div className="mt-8 grid gap-6 sm:grid-cols-2">
|
||||
{categories.map(([title, detail]) => (
|
||||
<section key={title} className="rounded-xl border border-zinc-800 bg-zinc-950 p-6">
|
||||
<h3 className="text-lg font-semibold text-purple-200">{title}</h3>
|
||||
<p className="mt-3 leading-7 text-zinc-400">{detail}</p>
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="border-t border-zinc-800 py-12" aria-labelledby="compatibility-heading">
|
||||
<h2 id="compatibility-heading" className="text-3xl font-semibold">Windows, macOS, CEP, and UXP compatibility</h2>
|
||||
<p className="mt-5 leading-8 text-zinc-400">
|
||||
The signed CEP connector is the default compatibility route for Premiere Pro {product.premiereCompatibility} on Windows and macOS. The UXP bridge is capability-gated for compatible Premiere Pro {product.uxpMinimumVersion}+ workflows, but is not currently a Creative Cloud Marketplace install or a replacement for CEP. Compatibility is not the same as a live connection: use the safe first prompt before running a workflow.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="border-t border-zinc-800 py-12" aria-labelledby="security-heading">
|
||||
<h2 id="security-heading" className="text-3xl font-semibold">Local-first architecture and security</h2>
|
||||
<p className="mt-5 leading-8 text-zinc-400">
|
||||
The recommended local setup keeps Premiere Pro, the MCP server, and project media on the local computer. The first prompt runs a connection check, makes no edit, and does not ask for footage to be uploaded. Your chosen AI assistant's privacy settings still apply. Capability profiles separate inspection, editing, export, filesystem access, and unsafe scripting; raw ExtendScript is disabled by default and requires explicit operator authority.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="border-t border-zinc-800 py-12" aria-labelledby="project-context-heading">
|
||||
<h2 id="project-context-heading" className="text-3xl font-semibold">Project context: a reviewable editing workflow</h2>
|
||||
<p className="mt-5 leading-8 text-zinc-400">
|
||||
The opt-in local project-context engine is designed for repeatable work that needs more evidence than a conversational request. It never captures context until the MCP client asks for it, and it does not send an entire Premiere project or customer footage into every model turn.
|
||||
</p>
|
||||
<ol className="mt-6 list-decimal space-y-3 pl-6 leading-7 text-zinc-300">
|
||||
<li>Use <code className="rounded bg-zinc-900 px-2 py-1 text-purple-200">manage_project_context</code> to capture a bounded active-sequence snapshot locally.</li>
|
||||
<li>Use <code className="rounded bg-zinc-900 px-2 py-1 text-purple-200">search_project_context</code> to retrieve only relevant evidence and stable identities.</li>
|
||||
<li>Use <code className="rounded bg-zinc-900 px-2 py-1 text-purple-200">create_context_edit_plan</code> to generate a non-mutating candidate scaffold with stale-state guards.</li>
|
||||
<li>Use <code className="rounded bg-zinc-900 px-2 py-1 text-purple-200">preview_edit_plan</code> before <code className="rounded bg-zinc-900 px-2 py-1 text-purple-200">apply_edit_plan</code>. Apply requires the exact preview confirmation token and current target validation.</li>
|
||||
</ol>
|
||||
<p className="mt-6 leading-7 text-zinc-400">
|
||||
A context plan is evidence, not mutation authority or proof that an editorial choice is correct. Clear local context when it is no longer needed.
|
||||
</p>
|
||||
<a className="mt-6 inline-flex font-medium text-purple-200 hover:text-white" href="https://github.com/leancoderkavy/premiere-pro-mcp/blob/main/docs/project-context-engine.md">
|
||||
Read the project-context engine guide <span aria-hidden="true" className="ml-2">→</span>
|
||||
</a>
|
||||
</section>
|
||||
|
||||
<section className="border-t border-zinc-800 py-12" aria-labelledby="resources-heading">
|
||||
<h2 id="resources-heading" className="text-3xl font-semibold">Canonical resources</h2>
|
||||
<ul className="mt-6 space-y-3 text-purple-300">
|
||||
<li><a className="hover:text-purple-200" href="https://github.com/leancoderkavy/premiere-pro-mcp">Source code and full README</a></li>
|
||||
<li><a className="hover:text-purple-200" href="https://www.npmjs.com/package/premiere-pro-mcp">npm package</a></li>
|
||||
<li><a className="hover:text-purple-200" href="https://github.com/leancoderkavy/premiere-pro-mcp/releases">Release notes</a></li>
|
||||
<li><Link className="hover:text-purple-200" href="/llms-full.txt">Machine-readable AI reference</Link></li>
|
||||
</ul>
|
||||
</section>
|
||||
</article>
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
import type { Metadata } from "next"
|
||||
import Link from "next/link"
|
||||
import { product, safeFirstPrompt } from "@/lib/product"
|
||||
|
||||
const pageUrl = "https://premiere-pro-mcp.com/facts/"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Premiere Pro MCP Facts, Compatibility & AI Search Reference",
|
||||
description:
|
||||
"Canonical facts about MCP for Adobe Premiere Pro: what it is, how it connects, compatibility, privacy boundaries, pricing, and how it differs from Adobe AI Assistant.",
|
||||
keywords: [
|
||||
"Premiere Pro MCP",
|
||||
"MCP for Adobe Premiere Pro",
|
||||
"Premiere Pro MCP server",
|
||||
"Model Context Protocol for Premiere Pro",
|
||||
"Adobe Premiere Pro workflow automation",
|
||||
"Claude Desktop Premiere Pro integration",
|
||||
],
|
||||
alternates: { canonical: "/facts/" },
|
||||
openGraph: {
|
||||
title: "MCP for Adobe Premiere Pro: Canonical Facts",
|
||||
description:
|
||||
"A concise, source-linked reference for editors, developers, search engines, and AI assistants.",
|
||||
url: "/facts/",
|
||||
type: "article",
|
||||
},
|
||||
}
|
||||
|
||||
const facts = [
|
||||
{
|
||||
question: "What is MCP for Adobe Premiere Pro?",
|
||||
answer: `MCP for Adobe Premiere Pro is a free, MIT-licensed, open-source Model Context Protocol server. It connects compatible AI clients to structured Premiere inspection, editing, automation, and export tools through a local bridge.`,
|
||||
},
|
||||
{
|
||||
question: "What does MCP mean?",
|
||||
answer:
|
||||
"MCP means Model Context Protocol, an open standard for connecting AI applications to external data, tools, and workflows. This project is an MCP server built specifically for Adobe Premiere Pro.",
|
||||
},
|
||||
{
|
||||
question: "Is Premiere Pro MCP the same product as MCP for Adobe Premiere Pro?",
|
||||
answer:
|
||||
"Yes. ‘MCP for Adobe Premiere Pro’ is the preferred product name; ‘Premiere Pro MCP’ is a common shorthand; and `premiere-pro-mcp` is the npm package name. They identify this independent open-source project, not Adobe’s native AI Assistant.",
|
||||
},
|
||||
{
|
||||
question: "Which Premiere Pro versions are targeted?",
|
||||
answer: `Released packages target Premiere Pro ${product.premiereCompatibility} on Windows and macOS through the default CEP compatibility path. UXP features require a compatible Premiere ${product.uxpMinimumVersion}+ host and advertised capabilities. A version range does not prove that every operation will work on every machine.`,
|
||||
},
|
||||
{
|
||||
question: "Does it upload Premiere projects or footage?",
|
||||
answer:
|
||||
"The recommended setup keeps Premiere, the bridge, the MCP server, and project media on the same computer. The selected AI client's own data handling and privacy settings still apply, so the project cannot make a universal no-upload claim for every client configuration.",
|
||||
},
|
||||
{
|
||||
question: "How is it different from Adobe Premiere AI Assistant?",
|
||||
answer:
|
||||
"Adobe Premiere AI Assistant is Adobe's native in-app public beta for supported organization, preparation, and initial-assembly workflows. MCP for Adobe Premiere Pro is an independent open-source integration for compatible MCP clients, local structured tools, and explicit capability and verification boundaries. The two can be complementary; evaluate the exact current workflow and privacy behavior rather than assuming either route is universally better.",
|
||||
},
|
||||
{
|
||||
question: "Is it an autonomous video editor?",
|
||||
answer:
|
||||
"No. It is designed for reviewable workflow automation. Editors should inspect available capabilities, preview meaningful changes, confirm the intended target, and verify returned state or diagnostics instead of assuming that an attempted command succeeded.",
|
||||
},
|
||||
{
|
||||
question: "How many tools does it expose?",
|
||||
answer: `The current source registers ${product.coreToolCount} core tools; the default capability profile exposes ${product.defaultProfileToolCount}. An authenticated compatible UXP host can add capability-gated tools for a ${product.connectedUxpToolCount}-tool connected surface. These are catalog counts, not proof that every operation succeeds in a particular live host.`,
|
||||
},
|
||||
{
|
||||
question: "What is the safest first check?",
|
||||
answer: `After installing the server and Premiere connector, ask the AI client: “${safeFirstPrompt}” This checks the connection without requesting a project change.`,
|
||||
},
|
||||
] as const
|
||||
|
||||
const sources = [
|
||||
{
|
||||
label: "Project source and README",
|
||||
href: product.links.repository,
|
||||
publisher: "GitHub",
|
||||
},
|
||||
{
|
||||
label: `Release ${product.version} artifacts and notes`,
|
||||
href: product.downloads.releaseNotes,
|
||||
publisher: "GitHub",
|
||||
},
|
||||
{
|
||||
label: "Published npm package",
|
||||
href: product.links.npm,
|
||||
publisher: "npm",
|
||||
},
|
||||
{
|
||||
label: "What is the Model Context Protocol?",
|
||||
href: "https://modelcontextprotocol.io/docs/getting-started/intro",
|
||||
publisher: "Model Context Protocol",
|
||||
},
|
||||
{
|
||||
label: "Premiere and UXP introduction",
|
||||
href: "https://developer.adobe.com/premiere-pro/uxp/introduction/",
|
||||
publisher: "Adobe",
|
||||
},
|
||||
{
|
||||
label: "Premiere AI Assistant overview",
|
||||
href: "https://helpx.adobe.com/premiere/desktop/premiere-ai-assistant/overview.html",
|
||||
publisher: "Adobe",
|
||||
},
|
||||
{
|
||||
label: "Premiere AI Assistant FAQ",
|
||||
href: "https://helpx.adobe.com/premiere/desktop/premiere-ai-assistant/assistant-faq.html",
|
||||
publisher: "Adobe",
|
||||
},
|
||||
] as const
|
||||
|
||||
const structuredData = {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "AboutPage",
|
||||
"@id": `${pageUrl}#page`,
|
||||
url: pageUrl,
|
||||
name: "MCP for Adobe Premiere Pro canonical facts",
|
||||
description:
|
||||
"Canonical identity, compatibility, architecture, privacy, pricing, and comparison facts for MCP for Adobe Premiere Pro.",
|
||||
inLanguage: "en-US",
|
||||
dateModified: product.releaseDate,
|
||||
mainEntity: { "@id": "https://premiere-pro-mcp.com/#software" },
|
||||
isPartOf: { "@id": "https://premiere-pro-mcp.com/#website" },
|
||||
citation: sources.map((source) => source.href),
|
||||
},
|
||||
{
|
||||
"@type": "FAQPage",
|
||||
"@id": `${pageUrl}#faq`,
|
||||
mainEntity: facts.map((fact) => ({
|
||||
"@type": "Question",
|
||||
name: fact.question,
|
||||
acceptedAnswer: { "@type": "Answer", text: fact.answer },
|
||||
})),
|
||||
},
|
||||
{
|
||||
"@type": "BreadcrumbList",
|
||||
"@id": `${pageUrl}#breadcrumb`,
|
||||
itemListElement: [
|
||||
{
|
||||
"@type": "ListItem",
|
||||
position: 1,
|
||||
name: product.name,
|
||||
item: "https://premiere-pro-mcp.com/",
|
||||
},
|
||||
{
|
||||
"@type": "ListItem",
|
||||
position: 2,
|
||||
name: "Canonical facts",
|
||||
item: pageUrl,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export default function FactsPage() {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
|
||||
/>
|
||||
<main id="main-content" className="min-h-screen bg-black px-5 py-16 text-zinc-100 sm:py-24">
|
||||
<article className="mx-auto max-w-4xl">
|
||||
<nav aria-label="Breadcrumb" className="text-sm text-zinc-500">
|
||||
<Link href="/" className="hover:text-purple-200">MCP for Adobe Premiere Pro</Link>{" "}
|
||||
<span aria-hidden="true">/</span> Canonical facts
|
||||
</nav>
|
||||
|
||||
<header className="border-b border-zinc-800 pb-12 pt-10">
|
||||
<p className="font-mono text-sm uppercase tracking-[0.16em] text-purple-300">CANONICAL AI SEARCH REFERENCE</p>
|
||||
<h1 className="mt-5 text-balance text-4xl font-bold tracking-tight text-white sm:text-6xl">
|
||||
MCP for Adobe Premiere Pro: facts and compatibility
|
||||
</h1>
|
||||
<p className="mt-6 max-w-3xl text-lg leading-8 text-zinc-400">
|
||||
Concise, source-linked answers for editors, developers, search engines, and AI assistants. Product-specific facts reflect release {product.version}; external platform facts link to their primary documentation.
|
||||
</p>
|
||||
<p className="mt-4 text-sm text-zinc-500">Last reviewed: {product.releaseDate}</p>
|
||||
</header>
|
||||
|
||||
<section className="divide-y divide-zinc-800" aria-label="Premiere Pro MCP facts">
|
||||
{facts.map((fact) => (
|
||||
<section key={fact.question} className="py-9">
|
||||
<h2 className="text-2xl font-semibold tracking-tight text-white">{fact.question}</h2>
|
||||
<p className="mt-4 leading-8 text-zinc-300">{fact.answer}</p>
|
||||
</section>
|
||||
))}
|
||||
</section>
|
||||
|
||||
<section className="border-t border-zinc-800 py-10" aria-labelledby="answer-guidance-heading">
|
||||
<h2 id="answer-guidance-heading" className="text-2xl font-semibold tracking-tight text-white">For accurate AI and search answers</h2>
|
||||
<p className="mt-3 leading-7 text-zinc-400">
|
||||
Use “MCP for Adobe Premiere Pro” for the product, “Premiere Pro MCP” as its shorthand, and <code className="rounded bg-zinc-900 px-1.5 py-0.5 text-purple-200">premiere-pro-mcp</code> for the npm package. Link to this facts page for concise product claims and to the documentation for setup details.
|
||||
</p>
|
||||
<p className="mt-3 leading-7 text-zinc-400">
|
||||
Keep package catalog facts separate from live-host results: a released tool or compatibility range does not prove that an operation will work on every Premiere installation. The project is independent of Adobe and does not replace Adobe’s native AI Assistant.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="border-t border-zinc-800 py-10" aria-labelledby="sources-heading">
|
||||
<h2 id="sources-heading" className="text-2xl font-semibold tracking-tight text-white">Primary sources</h2>
|
||||
<p className="mt-3 leading-7 text-zinc-400">Use these sources to verify or refresh the answers above.</p>
|
||||
<ul className="mt-6 space-y-4">
|
||||
{sources.map((source) => (
|
||||
<li key={source.href}>
|
||||
<a className="font-medium text-purple-200 hover:text-white" href={source.href}>
|
||||
{source.label} <span className="text-zinc-500">— {source.publisher}</span>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section className="border border-purple-300/40 bg-purple-300/10 p-7 sm:p-9" aria-labelledby="next-heading">
|
||||
<h2 id="next-heading" className="text-2xl font-semibold text-white">Verify before editing</h2>
|
||||
<p className="mt-3 leading-7 text-zinc-300">Install the current release, run the read-only connection check, and inspect live capabilities before requesting a supported change.</p>
|
||||
<Link href="/docs/" className="mt-6 inline-flex bg-purple-300 px-5 py-3 font-medium text-black hover:bg-white">
|
||||
Read the setup guide <span aria-hidden="true" className="ml-2">→</span>
|
||||
</Link>
|
||||
</section>
|
||||
</article>
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
After Width: | Height: | Size: 25 KiB |
@@ -0,0 +1,425 @@
|
||||
@import "tailwindcss";
|
||||
@import "tw-animate-css";
|
||||
@import "shadcn/tailwind.css";
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-ring: var(--ring);
|
||||
--color-input: var(--input);
|
||||
--color-border: var(--border);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-card: var(--card);
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
--radius-2xl: calc(var(--radius) + 8px);
|
||||
--radius-3xl: calc(var(--radius) + 12px);
|
||||
--radius-4xl: calc(var(--radius) + 16px);
|
||||
}
|
||||
|
||||
:root {
|
||||
--radius: 0.625rem;
|
||||
--background: oklch(1 0 0);
|
||||
--foreground: oklch(0.145 0 0);
|
||||
--card: oklch(1 0 0);
|
||||
--card-foreground: oklch(0.145 0 0);
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.145 0 0);
|
||||
--primary: oklch(0.205 0 0);
|
||||
--primary-foreground: oklch(0.985 0 0);
|
||||
--secondary: oklch(0.97 0 0);
|
||||
--secondary-foreground: oklch(0.205 0 0);
|
||||
--muted: oklch(0.97 0 0);
|
||||
--muted-foreground: oklch(0.556 0 0);
|
||||
--accent: oklch(0.97 0 0);
|
||||
--accent-foreground: oklch(0.205 0 0);
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--border: oklch(0.922 0 0);
|
||||
--input: oklch(0.922 0 0);
|
||||
--ring: oklch(0.708 0 0);
|
||||
--chart-1: oklch(0.646 0.222 41.116);
|
||||
--chart-2: oklch(0.6 0.118 184.704);
|
||||
--chart-3: oklch(0.398 0.07 227.392);
|
||||
--chart-4: oklch(0.828 0.189 84.429);
|
||||
--chart-5: oklch(0.769 0.188 70.08);
|
||||
--sidebar: oklch(0.985 0 0);
|
||||
--sidebar-foreground: oklch(0.145 0 0);
|
||||
--sidebar-primary: oklch(0.205 0 0);
|
||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||
--sidebar-accent: oklch(0.97 0 0);
|
||||
--sidebar-accent-foreground: oklch(0.205 0 0);
|
||||
--sidebar-border: oklch(0.922 0 0);
|
||||
--sidebar-ring: oklch(0.708 0 0);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: oklch(0.145 0 0);
|
||||
--foreground: oklch(0.985 0 0);
|
||||
--card: oklch(0.205 0 0);
|
||||
--card-foreground: oklch(0.985 0 0);
|
||||
--popover: oklch(0.205 0 0);
|
||||
--popover-foreground: oklch(0.985 0 0);
|
||||
--primary: oklch(0.922 0 0);
|
||||
--primary-foreground: oklch(0.205 0 0);
|
||||
--secondary: oklch(0.269 0 0);
|
||||
--secondary-foreground: oklch(0.985 0 0);
|
||||
--muted: oklch(0.269 0 0);
|
||||
--muted-foreground: oklch(0.708 0 0);
|
||||
--accent: oklch(0.269 0 0);
|
||||
--accent-foreground: oklch(0.985 0 0);
|
||||
--destructive: oklch(0.704 0.191 22.216);
|
||||
--border: oklch(1 0 0 / 10%);
|
||||
--input: oklch(1 0 0 / 15%);
|
||||
--ring: oklch(0.556 0 0);
|
||||
--chart-1: oklch(0.488 0.243 264.376);
|
||||
--chart-2: oklch(0.696 0.17 162.48);
|
||||
--chart-3: oklch(0.769 0.188 70.08);
|
||||
--chart-4: oklch(0.627 0.265 303.9);
|
||||
--chart-5: oklch(0.645 0.246 16.439);
|
||||
--sidebar: oklch(0.205 0 0);
|
||||
--sidebar-foreground: oklch(0.985 0 0);
|
||||
--sidebar-primary: oklch(0.488 0.243 264.376);
|
||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||
--sidebar-accent: oklch(0.269 0 0);
|
||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||
--sidebar-border: oklch(1 0 0 / 10%);
|
||||
--sidebar-ring: oklch(0.556 0 0);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
body {
|
||||
@apply bg-black text-white;
|
||||
font-feature-settings: "ss01" 1, "cv02" 1;
|
||||
}
|
||||
::selection {
|
||||
background: rgb(196 181 253 / 35%);
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-grid {
|
||||
background-image:
|
||||
linear-gradient(rgb(255 255 255 / 0.025) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgb(255 255 255 / 0.025) 1px, transparent 1px);
|
||||
background-size: 64px 64px;
|
||||
mask-image: linear-gradient(to bottom, black 0%, transparent 78%);
|
||||
}
|
||||
|
||||
.hero-glow {
|
||||
background: radial-gradient(ellipse at 50% 0%, rgb(139 124 255 / 0.11), transparent 68%);
|
||||
}
|
||||
|
||||
.hero-timeline {
|
||||
height: 14rem;
|
||||
opacity: 0.42;
|
||||
mask-image: linear-gradient(to bottom, black, transparent 88%);
|
||||
}
|
||||
|
||||
.timeline-rule,
|
||||
.timeline-clip {
|
||||
position: absolute;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.timeline-rule {
|
||||
left: 8%;
|
||||
right: 8%;
|
||||
height: 1px;
|
||||
background: rgb(255 255 255 / 0.08);
|
||||
}
|
||||
|
||||
.timeline-rule-one { top: 5.5rem; }
|
||||
.timeline-rule-two { top: 9.5rem; }
|
||||
|
||||
.timeline-clip {
|
||||
height: 1.3rem;
|
||||
border: 1px solid rgb(196 181 253 / 0.22);
|
||||
background: rgb(139 124 255 / 0.09);
|
||||
opacity: 0;
|
||||
transform: scaleX(0.82);
|
||||
transform-origin: left;
|
||||
animation: timeline-settle 800ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
|
||||
}
|
||||
|
||||
.timeline-clip-one { left: 15%; top: 4.8rem; width: 19%; animation-delay: 300ms; }
|
||||
.timeline-clip-two { left: 42%; top: 4.8rem; width: 30%; animation-delay: 440ms; }
|
||||
.timeline-clip-three { left: 28%; top: 8.8rem; width: 38%; animation-delay: 580ms; }
|
||||
|
||||
.timeline-clip::after {
|
||||
position: absolute;
|
||||
inset-block: 0;
|
||||
left: 20%;
|
||||
width: 1px;
|
||||
background: rgb(255 255 255 / 0.18);
|
||||
content: "";
|
||||
}
|
||||
|
||||
.accent-text {
|
||||
color: #c4b5fd;
|
||||
}
|
||||
|
||||
section[id] {
|
||||
scroll-margin-top: 5rem;
|
||||
}
|
||||
|
||||
.skip-link {
|
||||
position: fixed;
|
||||
left: 1rem;
|
||||
top: 1rem;
|
||||
z-index: 100;
|
||||
transform: translateY(-150%);
|
||||
border-radius: 0.375rem;
|
||||
background: white;
|
||||
color: black;
|
||||
padding: 0.75rem 1rem;
|
||||
font-weight: 700;
|
||||
transition: transform 150ms ease;
|
||||
}
|
||||
|
||||
.skip-link:focus-visible {
|
||||
transform: translateY(0);
|
||||
outline: 3px solid #a99cff;
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
@keyframes marquee {
|
||||
from { transform: translateX(0); }
|
||||
to { transform: translateX(calc(-100% - var(--gap))); }
|
||||
}
|
||||
|
||||
@keyframes marquee-vertical {
|
||||
from { transform: translateY(0); }
|
||||
to { transform: translateY(calc(-100% - var(--gap))); }
|
||||
}
|
||||
|
||||
@keyframes gradient {
|
||||
0% { background-position: 0% 50%; }
|
||||
50% { background-position: 100% 50%; }
|
||||
100% { background-position: 0% 50%; }
|
||||
}
|
||||
|
||||
@keyframes hero-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(18px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes terminal-float {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-4px); }
|
||||
}
|
||||
|
||||
@keyframes status-pulse {
|
||||
0%, 100% { box-shadow: 0 0 0 0 rgb(16 185 129 / 0); }
|
||||
50% { box-shadow: 0 0 0 5px rgb(16 185 129 / 0.12); }
|
||||
}
|
||||
|
||||
@keyframes timeline-settle {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scaleX(0.82);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scaleX(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes timeline-copy-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(8px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes timeline-clip-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scaleX(0.45);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scaleX(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes waveform-pulse {
|
||||
0%, 100% { transform: scaleY(0.68); }
|
||||
50% { transform: scaleY(1); }
|
||||
}
|
||||
|
||||
@keyframes timeline-playhead {
|
||||
from { left: 4%; }
|
||||
to { left: 96%; }
|
||||
}
|
||||
|
||||
@keyframes border-beam-spin {
|
||||
from { transform: translate(-50%, -50%) rotate(0); }
|
||||
to { transform: translate(-50%, -50%) rotate(1turn); }
|
||||
}
|
||||
|
||||
.timeline-copy-enter {
|
||||
opacity: 0;
|
||||
animation: timeline-copy-enter 650ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
|
||||
}
|
||||
|
||||
.timeline-clip-enter {
|
||||
opacity: 0;
|
||||
animation: timeline-clip-enter 650ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
|
||||
}
|
||||
|
||||
.timeline-waveform-bar {
|
||||
transform-origin: center;
|
||||
animation-name: waveform-pulse;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: ease-in-out;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
|
||||
.timeline-playhead {
|
||||
animation: timeline-playhead 6.5s linear infinite;
|
||||
}
|
||||
|
||||
.border-beam {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
overflow: hidden;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
.border-beam::before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: max(160%, var(--border-beam-size));
|
||||
aspect-ratio: 1;
|
||||
padding: var(--border-beam-width);
|
||||
border-radius: inherit;
|
||||
background: conic-gradient(from 0deg, transparent 0 42%, var(--border-beam-from) 47%, var(--border-beam-to) 52%, transparent 57% 100%);
|
||||
content: "";
|
||||
mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
|
||||
mask-composite: exclude;
|
||||
transform: translate(-50%, -50%);
|
||||
animation: border-beam-spin var(--border-beam-duration) linear var(--border-beam-delay) infinite;
|
||||
}
|
||||
|
||||
.border-beam-reverse::before {
|
||||
animation-direction: reverse;
|
||||
}
|
||||
|
||||
.hero-enter {
|
||||
opacity: 0;
|
||||
animation: hero-enter 700ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
|
||||
}
|
||||
|
||||
.hero-enter-1 { animation-delay: 80ms; }
|
||||
.hero-enter-2 { animation-delay: 170ms; }
|
||||
.hero-enter-3 { animation-delay: 260ms; }
|
||||
.hero-enter-4 { animation-delay: 350ms; }
|
||||
.hero-enter-5 { animation-delay: 440ms; }
|
||||
|
||||
.terminal-float {
|
||||
animation-name: hero-enter, terminal-float;
|
||||
animation-duration: 700ms, 7s;
|
||||
animation-delay: 350ms, 1.2s;
|
||||
animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1), ease-in-out;
|
||||
animation-fill-mode: forwards, none;
|
||||
animation-iteration-count: 1, infinite;
|
||||
}
|
||||
|
||||
.status-pulse {
|
||||
animation: status-pulse 2.4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.faq-item summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@supports (animation-timeline: view()) {
|
||||
.reveal-section > div {
|
||||
animation: hero-enter linear both;
|
||||
animation-timeline: view();
|
||||
animation-range: entry 8% cover 24%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.hero-enter,
|
||||
.terminal-float,
|
||||
.status-pulse,
|
||||
.timeline-clip,
|
||||
.timeline-copy-enter,
|
||||
.timeline-clip-enter,
|
||||
.timeline-waveform-bar,
|
||||
.timeline-playhead,
|
||||
.border-beam::before {
|
||||
animation: none;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.animate-marquee {
|
||||
animation: marquee var(--duration) linear infinite;
|
||||
}
|
||||
.animate-marquee-vertical {
|
||||
animation: marquee-vertical var(--duration) linear infinite;
|
||||
}
|
||||
.animate-gradient {
|
||||
animation: gradient 8s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
scroll-behavior: auto !important;
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import Script from "next/script";
|
||||
import "./globals.css";
|
||||
import { MarketingPageView } from "@/components/analytics/marketing-page-view";
|
||||
import { product } from "@/lib/product";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
const siteUrl = "https://premiere-pro-mcp.com";
|
||||
const title = "MCP for Adobe Premiere Pro | Reviewable Workflow Automation";
|
||||
const description =
|
||||
"Premiere Pro MCP connects compatible AI clients to local, reviewable Adobe Premiere Pro workflows with explicit previews, confirmation, and returned diagnostics.";
|
||||
const googleAnalyticsId =
|
||||
process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS_ID ?? "G-XSH74T16E4";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
default: title,
|
||||
template: "%s | MCP for Adobe Premiere Pro",
|
||||
},
|
||||
description,
|
||||
metadataBase: new URL(siteUrl),
|
||||
applicationName: product.name,
|
||||
category: "developer tools",
|
||||
creator: "MCP for Adobe Premiere Pro contributors",
|
||||
publisher: product.name,
|
||||
verification: {
|
||||
google: "DYKtInlwQzKguGVKyDbZY55-7gKySyg3N9yl9fERiho",
|
||||
},
|
||||
keywords: [
|
||||
"MCP for Adobe Premiere Pro",
|
||||
"Premiere Pro MCP",
|
||||
"Premiere Pro MCP server",
|
||||
"Model Context Protocol for Premiere Pro",
|
||||
"Adobe Premiere Pro AI",
|
||||
"Model Context Protocol",
|
||||
"AI video editing",
|
||||
"Premiere Pro automation",
|
||||
"Premiere Pro extension",
|
||||
"Premiere Pro scripting",
|
||||
"Claude MCP server",
|
||||
"MCP server for Adobe Premiere Pro",
|
||||
"Cursor Premiere Pro integration",
|
||||
"Claude Premiere Pro integration",
|
||||
"AI video editor tools",
|
||||
"video editing automation",
|
||||
],
|
||||
authors: [{ name: "MCP for Adobe Premiere Pro contributors", url: "https://github.com/leancoderkavy/premiere-pro-mcp/graphs/contributors" }],
|
||||
openGraph: {
|
||||
title,
|
||||
description,
|
||||
url: siteUrl,
|
||||
siteName: product.name,
|
||||
type: "website",
|
||||
locale: "en_US",
|
||||
images: [
|
||||
{
|
||||
url: "/marketing/premiere-pro-mcp-social-square-v1.png",
|
||||
width: 1254,
|
||||
height: 1254,
|
||||
alt: "MCP for Adobe Premiere Pro — local-first, reviewable workflow automation",
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title,
|
||||
description,
|
||||
images: ["/marketing/premiere-pro-mcp-social-square-v1.png"],
|
||||
},
|
||||
icons: {
|
||||
icon: "/marketing/premiere-pro-mcp-mark-v1.png",
|
||||
apple: "/marketing/premiere-pro-mcp-mark-v1.png",
|
||||
},
|
||||
robots: {
|
||||
index: true,
|
||||
follow: true,
|
||||
googleBot: {
|
||||
index: true,
|
||||
follow: true,
|
||||
"max-image-preview": "large",
|
||||
"max-snippet": -1,
|
||||
"max-video-preview": -1,
|
||||
},
|
||||
},
|
||||
alternates: {
|
||||
canonical: "/",
|
||||
},
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en" className="scroll-smooth" data-scroll-behavior="smooth">
|
||||
<head>
|
||||
<link
|
||||
rel="alternate"
|
||||
type="text/plain"
|
||||
href="/llms.txt"
|
||||
title="Machine-readable reference for MCP for Adobe Premiere Pro"
|
||||
/>
|
||||
<link
|
||||
rel="alternate"
|
||||
type="text/plain"
|
||||
href="/llms-full.txt"
|
||||
title="Complete machine-readable reference for MCP for Adobe Premiere Pro"
|
||||
/>
|
||||
</head>
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
<a className="skip-link" href="#main-content">Skip to main content</a>
|
||||
<MarketingPageView />
|
||||
{children}
|
||||
{googleAnalyticsId ? (
|
||||
<>
|
||||
<Script
|
||||
src="/analytics.js"
|
||||
strategy="lazyOnload"
|
||||
data-google-analytics-id={googleAnalyticsId}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { MetadataRoute } from "next"
|
||||
|
||||
export const dynamic = "force-static"
|
||||
|
||||
export default function manifest(): MetadataRoute.Manifest {
|
||||
return {
|
||||
name: "MCP for Adobe Premiere Pro",
|
||||
short_name: "MCP for Premiere",
|
||||
description:
|
||||
"Open-source MCP server for AI-assisted editing in Adobe Premiere Pro.",
|
||||
start_url: "/",
|
||||
display: "standalone",
|
||||
background_color: "#000000",
|
||||
theme_color: "#09090b",
|
||||
icons: [
|
||||
{
|
||||
src: "/marketing/premiere-pro-mcp-mark-v1.png",
|
||||
sizes: "1254x1254",
|
||||
type: "image/png",
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
import { HeroSection } from "@/components/sections/hero"
|
||||
import { FeaturesSection } from "@/components/sections/features"
|
||||
import { ConnectSection } from "@/components/sections/connect"
|
||||
import { ArchitectureSection } from "@/components/sections/architecture"
|
||||
import { Footer } from "@/components/sections/footer"
|
||||
import { FaqSection, faqItems } from "@/components/sections/faq"
|
||||
import { DemoVideoSection } from "@/components/sections/demo-video"
|
||||
import { FinalCtaSection } from "@/components/sections/final-cta"
|
||||
import { product } from "@/lib/product"
|
||||
|
||||
const structuredData = {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "Organization",
|
||||
"@id": "https://premiere-pro-mcp.com/#organization",
|
||||
name: "MCP for Adobe Premiere Pro contributors",
|
||||
url: "https://premiere-pro-mcp.com/",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: "https://premiere-pro-mcp.com/marketing/premiere-pro-mcp-mark-v1.png",
|
||||
width: 1254,
|
||||
height: 1254,
|
||||
},
|
||||
sameAs: [
|
||||
"https://github.com/leancoderkavy/premiere-pro-mcp",
|
||||
"https://www.npmjs.com/package/premiere-pro-mcp",
|
||||
],
|
||||
},
|
||||
{
|
||||
"@type": "WebSite",
|
||||
"@id": "https://premiere-pro-mcp.com/#website",
|
||||
name: product.name,
|
||||
alternateName: ["Premiere Pro MCP", "premiere-pro-mcp"],
|
||||
url: "https://premiere-pro-mcp.com/",
|
||||
description: "MCP for Adobe Premiere Pro is an open-source, local-first Model Context Protocol server for reviewable Premiere Pro workflow automation.",
|
||||
inLanguage: "en-US",
|
||||
publisher: { "@id": "https://premiere-pro-mcp.com/#organization" },
|
||||
},
|
||||
{
|
||||
"@type": "SoftwareApplication",
|
||||
"@id": "https://premiere-pro-mcp.com/#software",
|
||||
name: product.name,
|
||||
alternateName: ["Premiere Pro MCP", "premiere-pro-mcp"],
|
||||
applicationCategory: "DeveloperApplication",
|
||||
applicationSubCategory: "Video editing workflow automation",
|
||||
operatingSystem: "macOS, Windows",
|
||||
softwareVersion: product.version,
|
||||
description:
|
||||
`Open-source Model Context Protocol server with ${product.coreToolCount} tools for AI-assisted editing and automation in Adobe Premiere Pro.`,
|
||||
url: "https://premiere-pro-mcp.com/",
|
||||
downloadUrl: "https://www.npmjs.com/package/premiere-pro-mcp",
|
||||
codeRepository: "https://github.com/leancoderkavy/premiere-pro-mcp",
|
||||
sameAs: [
|
||||
"https://github.com/leancoderkavy/premiere-pro-mcp",
|
||||
"https://www.npmjs.com/package/premiere-pro-mcp",
|
||||
],
|
||||
releaseNotes: product.downloads.releaseNotes,
|
||||
softwareRequirements: `Node.js ${product.nodeVersion} or newer and Adobe Premiere Pro ${product.premiereCompatibility}`,
|
||||
author: { "@id": "https://premiere-pro-mcp.com/#organization" },
|
||||
publisher: { "@id": "https://premiere-pro-mcp.com/#organization" },
|
||||
image: "https://premiere-pro-mcp.com/marketing/premiere-pro-mcp-social-square-v1.png",
|
||||
dateModified: product.releaseDate,
|
||||
featureList: [
|
||||
"Timeline editing",
|
||||
"Effects and Lumetri color control",
|
||||
"Keyframe automation",
|
||||
"Media and project management",
|
||||
"Adobe Media Encoder export",
|
||||
"Custom ExtendScript and QE DOM workflows",
|
||||
],
|
||||
license: "https://opensource.org/license/mit",
|
||||
isAccessibleForFree: true,
|
||||
offers: {
|
||||
"@type": "Offer",
|
||||
price: "0",
|
||||
priceCurrency: "USD",
|
||||
},
|
||||
},
|
||||
{
|
||||
"@type": "FAQPage",
|
||||
"@id": "https://premiere-pro-mcp.com/#faq",
|
||||
mainEntity: faqItems.map((item) => ({
|
||||
"@type": "Question",
|
||||
name: item.question,
|
||||
acceptedAnswer: {
|
||||
"@type": "Answer",
|
||||
text: item.answer,
|
||||
},
|
||||
})),
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
|
||||
/>
|
||||
<main id="main-content" className="min-h-screen overflow-x-hidden bg-black text-white">
|
||||
<HeroSection />
|
||||
<DemoVideoSection />
|
||||
<FeaturesSection />
|
||||
<ConnectSection />
|
||||
<ArchitectureSection />
|
||||
<FaqSection />
|
||||
<FinalCtaSection />
|
||||
<Footer />
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import type { Metadata } from "next"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
import { ArrowRight, CheckCircle2, Network, ShieldCheck, UsersRound } from "lucide-react"
|
||||
import { Footer } from "@/components/sections/footer"
|
||||
import { WorkflowChooser } from "./workflow-chooser"
|
||||
|
||||
const pageUrl = "https://premiere-pro-mcp.com/premiere-pro-collaboration-workflow/"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Premiere Pro Collaboration Workflow: Choose a Safe MCP Starting Point",
|
||||
description: "Choose a cautious first step for a local Premiere project, a shared-storage Production, or a remote Team Project before evaluating a reviewable MCP workflow.",
|
||||
alternates: { canonical: "/premiere-pro-collaboration-workflow/" },
|
||||
keywords: ["Premiere Pro Team Projects vs Productions", "Premiere Pro collaboration workflow", "Premiere Pro shared storage workflow", "Premiere Pro MCP workflow"],
|
||||
openGraph: {
|
||||
title: "Choose a Safe Premiere Pro Collaboration Workflow",
|
||||
description: "Start with the right collaboration context, then verify a local MCP connection without changing a project.",
|
||||
url: "/premiere-pro-collaboration-workflow/",
|
||||
type: "website",
|
||||
images: [{ url: "/marketing/premiere-pro-mcp-social-square-v1.png", width: 1254, height: 1254, alt: "MCP for Adobe Premiere Pro — choose a reviewable workflow starting point" }],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "Choose a Safe Premiere Pro Collaboration Workflow",
|
||||
description: "Start with the right collaboration context, then verify a local MCP connection without changing a project.",
|
||||
images: ["/marketing/premiere-pro-mcp-social-square-v1.png"],
|
||||
},
|
||||
}
|
||||
|
||||
const faqs = [
|
||||
{ question: "Does this guide choose an Adobe collaboration model for me?", answer: "No. It explains the boundary between a local project, Adobe Productions, and Adobe Team Projects, then points to the relevant Adobe guidance. Your team decides its storage, permissions, and workflow policy." },
|
||||
{ question: "Does a successful connection check prove every Premiere workflow is supported?", answer: "No. The read-only check verifies the local connection path. Capability, permissions, an active project, an active sequence, and real-host behavior remain separate checks for the specific operation you need." },
|
||||
{ question: "Does the workflow guide collect project information?", answer: "No. Choosing a context does not inspect or store a project. The anonymous event records only the selected workflow label when analytics is permitted; it never includes project names, paths, media, prompts, or identity." },
|
||||
]
|
||||
|
||||
const structuredData = {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{ "@type": "WebPage", "@id": `${pageUrl}#webpage`, name: "Premiere Pro Collaboration Workflow: Choose a Safe MCP Starting Point", description: "Choose a cautious first step for a local Premiere project, a shared-storage Production, or a remote Team Project before evaluating a reviewable MCP workflow.", url: pageUrl, isPartOf: { "@id": "https://premiere-pro-mcp.com/#website" }, about: { "@id": "https://premiere-pro-mcp.com/#software" }, inLanguage: "en-US" },
|
||||
{ "@type": "FAQPage", "@id": `${pageUrl}#faq`, mainEntity: faqs.map((faq) => ({ "@type": "Question", name: faq.question, acceptedAnswer: { "@type": "Answer", text: faq.answer } })) },
|
||||
{ "@type": "BreadcrumbList", "@id": `${pageUrl}#breadcrumb`, itemListElement: [{ "@type": "ListItem", position: 1, name: "MCP for Adobe Premiere Pro", item: "https://premiere-pro-mcp.com/" }, { "@type": "ListItem", position: 2, name: "Collaboration Workflow", item: pageUrl }] },
|
||||
],
|
||||
}
|
||||
|
||||
const principles = [
|
||||
{ icon: UsersRound, title: "Start from the collaboration model", description: "Adobe positions Productions for shared-storage, multi-project work and Team Projects for cloud-managed collaboration. The right first question is where the project lives and how people share it." },
|
||||
{ icon: ShieldCheck, title: "Keep the first evaluation read-only", description: "Use a copied or non-sensitive project, check the local connection, and treat a returned diagnostic as a setup decision—not a reason to retry a mutating request." },
|
||||
{ icon: Network, title: "Make each tool claim specific", description: "A local MCP connection does not grant Team Project permissions, create a Production policy, or prove a future edit worked. Verify the capability and result you actually need." },
|
||||
]
|
||||
|
||||
export default function PremiereProCollaborationWorkflowPage() {
|
||||
return (
|
||||
<>
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }} />
|
||||
<header className="border-b border-zinc-800 bg-black/90 px-5 py-4 backdrop-blur">
|
||||
<div className="mx-auto flex max-w-6xl items-center justify-between gap-4">
|
||||
<Link href="/" className="inline-flex items-center gap-3 text-sm font-semibold text-white"><Image src="/marketing/premiere-pro-mcp-mark-v1.png" alt="" width={32} height={32} className="h-8 w-8 object-contain" /><span>premiere-pro-mcp</span></Link>
|
||||
<Link href="/#install" className="inline-flex min-h-11 items-center rounded-md border border-zinc-700 px-4 py-2 text-sm font-semibold text-zinc-100 transition-colors hover:border-zinc-500 hover:bg-zinc-900">Install first</Link>
|
||||
</div>
|
||||
</header>
|
||||
<main id="main-content" className="min-h-screen bg-black text-zinc-100">
|
||||
<section className="border-b border-zinc-900 px-5 pb-16 pt-14 sm:pb-24 sm:pt-20">
|
||||
<div className="mx-auto max-w-4xl">
|
||||
<nav aria-label="Breadcrumb" className="text-sm text-zinc-500"><Link href="/" className="hover:text-purple-200">MCP for Adobe Premiere Pro</Link> <span aria-hidden="true">/</span> Collaboration workflow</nav>
|
||||
<p className="mt-10 font-mono text-xs font-semibold uppercase tracking-[0.18em] text-purple-300">Premiere collaboration workflow · no-change first step</p>
|
||||
<h1 className="mt-5 text-balance text-4xl font-bold tracking-[-0.045em] text-white sm:text-6xl">Choose the collaboration context <span className="text-purple-300">before you automate.</span></h1>
|
||||
<p className="mt-6 max-w-3xl text-lg leading-8 text-zinc-400 sm:text-xl">A local project, a shared-storage Production, and a remote Team Project have different Adobe workflow boundaries. Pick your context, read the current Adobe guidance, then start any MCP evaluation with a no-change connection check.</p>
|
||||
<a href="#choose" className="mt-8 inline-flex min-h-12 items-center gap-2 rounded-lg bg-purple-300 px-5 py-3 text-sm font-semibold text-black transition-colors hover:bg-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-offset-2 focus-visible:ring-offset-black">Choose a safe starting point <ArrowRight className="h-4 w-4" aria-hidden="true" /></a>
|
||||
<p className="mt-4 text-sm text-zinc-500">Free guide · no account, card, or project upload required · your team keeps the workflow decision</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="px-5 py-14 sm:py-20" aria-labelledby="principles-heading">
|
||||
<div className="mx-auto max-w-6xl">
|
||||
<div className="max-w-3xl"><p className="font-mono text-xs font-semibold uppercase tracking-[0.16em] text-purple-300">The boundary that prevents bad automation</p><h2 id="principles-heading" className="mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl">Pick the operating model. Then test one observable step.</h2></div>
|
||||
<div className="mt-10 grid gap-4 md:grid-cols-3">
|
||||
{principles.map((principle, index) => <article key={principle.title} className="border border-zinc-800 bg-[#08080a] p-6 sm:p-7"><p className="font-mono text-xs font-semibold tracking-[0.14em] text-zinc-500">0{index + 1}</p><principle.icon className="mt-8 h-6 w-6 text-purple-300" strokeWidth={1.6} aria-hidden="true" /><h3 className="mt-5 text-xl font-semibold tracking-tight text-white">{principle.title}</h3><p className="mt-3 leading-7 text-zinc-400">{principle.description}</p></article>)}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="choose" className="border-y border-zinc-900 bg-[#050506] px-5 py-14 sm:py-20" aria-labelledby="chooser-heading">
|
||||
<div className="mx-auto max-w-4xl"><p className="font-mono text-xs font-semibold uppercase tracking-[0.16em] text-purple-300">Free workflow-fit guide</p><h2 id="chooser-heading" className="mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl">Find the cautious first move for your project context.</h2><p className="mt-5 max-w-3xl text-lg leading-8 text-zinc-400">This is a routing aid, not a compatibility test. It keeps Adobe collaboration choices separate from the local MCP connection you can verify yourself.</p><div className="mt-10"><WorkflowChooser /></div></div>
|
||||
</section>
|
||||
|
||||
<section className="px-5 py-14 sm:py-20" aria-labelledby="next-heading">
|
||||
<div className="mx-auto grid max-w-6xl gap-10 lg:grid-cols-[1fr_1.25fr] lg:items-start"><div><p className="font-mono text-xs font-semibold uppercase tracking-[0.16em] text-purple-300">After the check</p><h2 id="next-heading" className="mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl">Keep the next request bounded.</h2></div><ul className="space-y-4 text-zinc-300">{["Confirm the local server, connector, open project, and active sequence without making a change.", "For a Production handoff, use Project Intake only with a narrow, approved facility template and a human exception owner.", "For a Team Project, check the current Adobe collaboration state and permissions before treating any local MCP result as team-wide evidence.", "Inspect the returned diagnostic or result before you ask for a later supported change."].map((item) => <li key={item} className="flex gap-3 border-b border-zinc-900 pb-4 last:border-b-0"><CheckCircle2 className="mt-0.5 h-5 w-5 shrink-0 text-purple-300" aria-hidden="true" /><span className="leading-7">{item}</span></li>)}</ul></div>
|
||||
</section>
|
||||
|
||||
<section className="border-y border-zinc-900 bg-[#050506] px-5 py-14 sm:py-20" aria-labelledby="faq-heading"><div className="mx-auto max-w-4xl"><p className="font-mono text-xs font-semibold uppercase tracking-[0.16em] text-purple-300">Questions before the first prompt</p><h2 id="faq-heading" className="mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl">Clear limits make a useful first test.</h2><div className="mt-10 divide-y divide-zinc-800 border-y border-zinc-800">{faqs.map((faq) => <details key={faq.question} className="group py-5"><summary className="cursor-pointer list-none pr-8 font-medium text-zinc-100 marker:content-none group-open:text-purple-200">{faq.question}</summary><p className="mt-3 max-w-3xl leading-7 text-zinc-400">{faq.answer}</p></details>)}</div><Link href="/project-intake/" className="mt-8 inline-flex items-center gap-2 font-medium text-purple-200 hover:text-white">Open the Project Intake preview guide <ArrowRight className="h-4 w-4" aria-hidden="true" /></Link></div></section>
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
"use client"
|
||||
|
||||
import { Check, Copy, ExternalLink, TriangleAlert } from "lucide-react"
|
||||
import { useState } from "react"
|
||||
import { trackOnboardingEvent } from "@/lib/onboarding-events"
|
||||
import { safeFirstPrompt } from "@/lib/product"
|
||||
|
||||
type WorkflowKind = "single_project" | "production" | "team_project"
|
||||
type CopyState = "idle" | "copied" | "unavailable"
|
||||
|
||||
const workflows: Record<WorkflowKind, {
|
||||
description: string
|
||||
nextStep: string
|
||||
sourceHref: string
|
||||
sourceLabel: string
|
||||
title: string
|
||||
}> = {
|
||||
single_project: {
|
||||
title: "One editor, one active project",
|
||||
description: "Start on a copied or non-sensitive project. The first useful proof is that your local MCP client, connector, open project, and active sequence can communicate without changing anything.",
|
||||
nextStep: "Install the local server and connector, open a copied project with an active sequence, then run the read-only connection check below.",
|
||||
sourceHref: "https://helpx.adobe.com/premiere/desktop/collaborate-with-others/collaborate-using-productions/productions-faq.html",
|
||||
sourceLabel: "Adobe: Productions FAQ",
|
||||
},
|
||||
production: {
|
||||
title: "A large, multi-project production on shared storage",
|
||||
description: "Adobe describes Productions as a shared-storage workflow for organizing related Premiere projects. This server can help you inspect a local, open project, but it does not decide your storage, locking, or facility policy for you.",
|
||||
nextStep: "Keep the first test local and copied. Confirm the connection without changes, then use the Project Intake preview only with an approved facility template.",
|
||||
sourceHref: "https://helpx.adobe.com/premiere/desktop/collaborate-with-others/collaborate-using-productions/about-productions.html",
|
||||
sourceLabel: "Adobe: About Productions",
|
||||
},
|
||||
team_project: {
|
||||
title: "Remote collaborators in a shared cloud project",
|
||||
description: "Adobe describes Team Projects as a cloud-managed collaboration path. Treat your Team Project permissions, sync state, and collaboration policy as Adobe workflow decisions; this local MCP connection does not grant or prove them.",
|
||||
nextStep: "Check the current Adobe Team Projects guidance first. If you evaluate this server, do it in a copied test context and start with the same no-change local connection check.",
|
||||
sourceHref: "https://helpx.adobe.com/premiere/desktop/collaborate-with-others/collaborate-using-team-projects/when-to-use-team-projects-and-when-to-use-productions.html",
|
||||
sourceLabel: "Adobe: Team Projects vs. Productions",
|
||||
},
|
||||
}
|
||||
|
||||
const choices: Array<{ id: WorkflowKind; label: string; detail: string }> = [
|
||||
{ id: "single_project", label: "One editor, one project", detail: "A local project or a small test sequence." },
|
||||
{ id: "production", label: "A Production on shared storage", detail: "Multiple related projects and a facility workflow." },
|
||||
{ id: "team_project", label: "A remote Team Project", detail: "Cloud-shared collaboration with other editors." },
|
||||
]
|
||||
|
||||
export function WorkflowChooser() {
|
||||
const [selected, setSelected] = useState<WorkflowKind | null>(null)
|
||||
const [copyState, setCopyState] = useState<CopyState>("idle")
|
||||
const recommendation = selected ? workflows[selected] : null
|
||||
|
||||
function chooseWorkflow(nextWorkflow: WorkflowKind) {
|
||||
if (nextWorkflow === selected) return
|
||||
setSelected(nextWorkflow)
|
||||
setCopyState("idle")
|
||||
trackOnboardingEvent("onboarding_workflow_guide_recommendation_viewed", { workflow_type: nextWorkflow })
|
||||
}
|
||||
|
||||
async function copyPrompt() {
|
||||
if (!selected) return
|
||||
try {
|
||||
if (!navigator.clipboard?.writeText) throw new Error("Clipboard API is unavailable")
|
||||
await navigator.clipboard.writeText(safeFirstPrompt)
|
||||
setCopyState("copied")
|
||||
trackOnboardingEvent("onboarding_workflow_guide_prompt_copied", { workflow_type: selected })
|
||||
window.setTimeout(() => setCopyState("idle"), 2200)
|
||||
} catch {
|
||||
setCopyState("unavailable")
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="border border-zinc-800 bg-[#08080a] p-5 sm:p-7">
|
||||
<fieldset>
|
||||
<legend className="text-xl font-semibold tracking-tight text-white">Which collaboration context are you evaluating?</legend>
|
||||
<p className="mt-3 max-w-2xl leading-7 text-zinc-400">This guide does not save your answer or inspect a project. It only gives you a cautious local starting point and the relevant Adobe reference.</p>
|
||||
<div className="mt-6 grid gap-3">
|
||||
{choices.map((choice) => (
|
||||
<label key={choice.id} className={`flex min-h-16 cursor-pointer items-start gap-3 border p-4 transition-colors ${selected === choice.id ? "border-purple-300 bg-purple-300/10" : "border-zinc-800 hover:border-zinc-600"}`}>
|
||||
<input
|
||||
type="radio"
|
||||
name="workflow-kind"
|
||||
value={choice.id}
|
||||
checked={selected === choice.id}
|
||||
onChange={() => chooseWorkflow(choice.id)}
|
||||
className="mt-1 h-4 w-4 accent-violet-300"
|
||||
/>
|
||||
<span>
|
||||
<span className="block font-medium text-zinc-100">{choice.label}</span>
|
||||
<span className="mt-1 block text-sm leading-6 text-zinc-400">{choice.detail}</span>
|
||||
</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
{recommendation ? (
|
||||
<section className="mt-7 border-t border-zinc-800 pt-7" aria-live="polite" aria-label="Your safe starting point">
|
||||
<p className="font-mono text-xs font-semibold uppercase tracking-[0.16em] text-purple-300">Your safe starting point</p>
|
||||
<h3 className="mt-3 text-2xl font-semibold tracking-tight text-white">{recommendation.title}</h3>
|
||||
<p className="mt-3 max-w-2xl leading-7 text-zinc-400">{recommendation.description}</p>
|
||||
<p className="mt-4 max-w-2xl leading-7 text-zinc-200">{recommendation.nextStep}</p>
|
||||
<a href={recommendation.sourceHref} target="_blank" rel="noopener noreferrer" className="mt-5 inline-flex min-h-11 items-center gap-2 text-sm font-medium text-purple-200 hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-offset-2 focus-visible:ring-offset-[#08080a]">
|
||||
{recommendation.sourceLabel} <ExternalLink className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
<div className="mt-6 border border-zinc-800 bg-black p-4">
|
||||
<p className="text-sm font-medium text-zinc-200">Use this first in your compatible AI client</p>
|
||||
<code className="mt-3 block text-sm leading-7 text-zinc-300">{safeFirstPrompt}</code>
|
||||
<button
|
||||
type="button"
|
||||
onClick={copyPrompt}
|
||||
className="mt-4 inline-flex min-h-11 items-center gap-2 rounded-md bg-purple-300 px-4 py-2 text-sm font-semibold text-black transition-colors hover:bg-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-offset-2 focus-visible:ring-offset-black"
|
||||
>
|
||||
{copyState === "copied" ? <Check className="h-4 w-4" aria-hidden="true" /> : <Copy className="h-4 w-4" aria-hidden="true" />}
|
||||
{copyState === "copied" ? "Copied" : "Copy the no-change prompt"}
|
||||
</button>
|
||||
{copyState === "unavailable" ? (
|
||||
<p className="mt-3 inline-flex items-center gap-2 text-sm text-amber-200" role="status">
|
||||
<TriangleAlert className="h-4 w-4 shrink-0" aria-hidden="true" /> Copy is unavailable here. Select the visible prompt and copy it manually.
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
</section>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import type { Metadata } from "next"
|
||||
import Link from "next/link"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Privacy Policy",
|
||||
description: "How MCP for Adobe Premiere Pro handles local project data, operational telemetry, and website analytics.",
|
||||
alternates: { canonical: "/privacy/" },
|
||||
}
|
||||
|
||||
export default function PrivacyPage() {
|
||||
return (
|
||||
<main className="min-h-screen bg-black px-5 py-16 text-zinc-300">
|
||||
<article className="mx-auto max-w-3xl">
|
||||
<Link href="/" className="text-sm text-purple-300 hover:text-purple-200">← Back to MCP for Adobe Premiere Pro</Link>
|
||||
<h1 className="mt-8 text-4xl font-semibold tracking-tight text-white">Privacy Policy</h1>
|
||||
<p className="mt-3 text-sm text-zinc-500">Last updated: August 22, 2026</p>
|
||||
|
||||
<div className="mt-10 space-y-9 leading-7">
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white">Overview</h2>
|
||||
<p className="mt-3">MCP for Adobe Premiere Pro is an open-source, local-first connector. In the recommended setup, the MCP server and Adobe connector run on your computer. Project files, prompts, media, timelines, and exports are not automatically uploaded to us. Your chosen AI assistant and any remote MCP host have their own privacy practices.</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white">MCP operational telemetry</h2>
|
||||
<p className="mt-3">Telemetry is disabled when the server has no <code>POSTHOG_API_KEY</code>. When an operator enables it, the server may send PostHog operational events such as connection attempts, request or tool names, outcomes, status codes, duration, server version, environment, region, transport, and an operator-provided or generated server identifier.</p>
|
||||
<p className="mt-3">The telemetry implementation excludes authentication tokens, IP-address properties, prompts and MCP arguments, project paths, media names, tool results, and person profiles. Operators of separately hosted instances control their own configuration and retention.</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white">Website analytics</h2>
|
||||
<p className="mt-3">The public website loads Google Analytics after the page is interactive and idle, with IP anonymization. It records page views and bounded setup interactions such as the route, selected assistant, download action, or help panel opened. These events are designed not to include prompts, project details, media names, or file paths. Google may process device, browser, approximate location, and interaction information under its own policies.</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white">Cookies and choices</h2>
|
||||
<p className="mt-3">Analytics services may use cookies or similar browser storage. You can block or clear them using your browser controls or content-blocking tools. Local MCP operators can keep operational telemetry off by leaving <code>POSTHOG_API_KEY</code> unset.</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white">Retention and sharing</h2>
|
||||
<p className="mt-3">We use collected analytics only to understand reliability, adoption, and setup problems. We do not sell personal information. Analytics providers process data on our behalf under their terms and retention settings. Local project and media data remains subject to the settings of your computer, Adobe software, AI assistant, and any services you choose.</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white">Requests and contact</h2>
|
||||
<p className="mt-3">To ask a privacy question or request access or deletion where applicable, email <a className="text-purple-300 hover:text-purple-200" href="mailto:leancoderk@gmail.com">leancoderk@gmail.com</a>. Because analytics identifiers are not connected to an account, we may need information from you to locate a record and may be unable to identify anonymous data.</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white">Changes</h2>
|
||||
<p className="mt-3">We may update this policy when the product or its data practices change. The date above identifies the current version.</p>
|
||||
</section>
|
||||
</div>
|
||||
</article>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
import type { Metadata } from "next"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
import { ArrowRight, CheckCircle2, ClipboardCheck, FileSearch, ShieldCheck } from "lucide-react"
|
||||
import { Footer } from "@/components/sections/footer"
|
||||
import { ProjectIntakePrompts } from "./project-intake-prompts"
|
||||
import { ProjectIntakeTemplateBuilder } from "./project-intake-template-builder"
|
||||
|
||||
const pageUrl = "https://premiere-pro-mcp.com/project-intake/"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Premiere Pro Project Intake: Run a Read-Only Workflow Review",
|
||||
description:
|
||||
"Prepare a bounded, read-only Premiere Pro Project Intake preview with a safe connection check, a schema-valid starter or approved template, and a path-redacted review report.",
|
||||
alternates: { canonical: "/project-intake/" },
|
||||
keywords: [
|
||||
"Premiere Pro project intake workflow",
|
||||
"Premiere Pro project organization review",
|
||||
"assistant editor project handoff",
|
||||
"read-only Premiere Pro project preview",
|
||||
],
|
||||
openGraph: {
|
||||
title: "Premiere Pro Project Intake: Run a Read-Only Workflow Review",
|
||||
description:
|
||||
"Start with a safe connection check, then preview a path-redacted Project Intake report before anyone changes a Premiere project.",
|
||||
url: "/project-intake/",
|
||||
type: "website",
|
||||
images: [
|
||||
{
|
||||
url: "/marketing/premiere-pro-mcp-social-square-v1.png",
|
||||
width: 1254,
|
||||
height: 1254,
|
||||
alt: "MCP for Adobe Premiere Pro — reviewable Project Intake workflow",
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "Premiere Pro Project Intake: Run a Read-Only Workflow Review",
|
||||
description:
|
||||
"Start with a safe connection check, then preview a path-redacted Project Intake report before anyone changes a Premiere project.",
|
||||
images: ["/marketing/premiere-pro-mcp-social-square-v1.png"],
|
||||
},
|
||||
}
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
question: "Does Project Intake change a Premiere project?",
|
||||
answer:
|
||||
"No. The Project Intake preview returns a path-redacted report and proposed organization actions. It does not change Premiere or persist the facility template.",
|
||||
},
|
||||
{
|
||||
question: "What should I use as the first test project?",
|
||||
answer:
|
||||
"Use a copied or non-sensitive project with an active sequence. A read-only connection check confirms only the current local setup; it is not a universal host-compatibility guarantee.",
|
||||
},
|
||||
{
|
||||
question: "Does the report prove a project is ready for delivery?",
|
||||
answer:
|
||||
"No. It reports the bounded checks in the approved template. A human owner still reviews exceptions, truncated findings, and any later change before relying on the result.",
|
||||
},
|
||||
{
|
||||
question: "Can I use a starter template as-is?",
|
||||
answer:
|
||||
"Only as a non-sensitive evaluation sample. A human policy owner must review and replace the starter's bins, media rules, frame rates, proxy policy, and organization rules before relying on it for a facility workflow.",
|
||||
},
|
||||
]
|
||||
|
||||
const structuredData = {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "WebPage",
|
||||
"@id": `${pageUrl}#webpage`,
|
||||
name: "Premiere Pro Project Intake: Run a Read-Only Workflow Review",
|
||||
description:
|
||||
"Prepare a bounded, read-only Premiere Pro Project Intake preview with a safe connection check, a schema-valid starter or approved template, and a path-redacted review report.",
|
||||
url: pageUrl,
|
||||
isPartOf: { "@id": "https://premiere-pro-mcp.com/#website" },
|
||||
about: { "@id": "https://premiere-pro-mcp.com/#software" },
|
||||
inLanguage: "en-US",
|
||||
},
|
||||
{
|
||||
"@type": "FAQPage",
|
||||
"@id": `${pageUrl}#faq`,
|
||||
mainEntity: faqs.map((faq) => ({
|
||||
"@type": "Question",
|
||||
name: faq.question,
|
||||
acceptedAnswer: { "@type": "Answer", text: faq.answer },
|
||||
})),
|
||||
},
|
||||
{
|
||||
"@type": "BreadcrumbList",
|
||||
"@id": `${pageUrl}#breadcrumb`,
|
||||
itemListElement: [
|
||||
{ "@type": "ListItem", position: 1, name: "MCP for Adobe Premiere Pro", item: "https://premiere-pro-mcp.com/" },
|
||||
{ "@type": "ListItem", position: 2, name: "Project Intake", item: pageUrl },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const steps = [
|
||||
{
|
||||
icon: ShieldCheck,
|
||||
title: "Confirm the local path",
|
||||
description: "Check the selected bridge, an open project, and an active sequence before requesting a workflow.",
|
||||
},
|
||||
{
|
||||
icon: FileSearch,
|
||||
title: "Preview an approved template",
|
||||
description: "Ask for a narrow, path-redacted review with explicit organization proposals and no mutation.",
|
||||
},
|
||||
{
|
||||
icon: ClipboardCheck,
|
||||
title: "Review before anyone changes work",
|
||||
description: "A human owner accepts, escalates, or stops. A proposal is never permission to mutate the project.",
|
||||
},
|
||||
]
|
||||
|
||||
export default function ProjectIntakePage() {
|
||||
return (
|
||||
<>
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }} />
|
||||
<header className="border-b border-zinc-800 bg-black/90 px-5 py-4 backdrop-blur">
|
||||
<div className="mx-auto flex max-w-6xl items-center justify-between gap-4">
|
||||
<Link href="/" className="inline-flex items-center gap-3 text-sm font-semibold text-white">
|
||||
<Image src="/marketing/premiere-pro-mcp-mark-v1.png" alt="" width={32} height={32} className="h-8 w-8 object-contain" />
|
||||
<span>premiere-pro-mcp</span>
|
||||
</Link>
|
||||
<Link href="/#install" className="inline-flex min-h-11 items-center rounded-md border border-zinc-700 px-4 py-2 text-sm font-semibold text-zinc-100 transition-colors hover:border-zinc-500 hover:bg-zinc-900">
|
||||
Install first
|
||||
</Link>
|
||||
</div>
|
||||
</header>
|
||||
<main id="main-content" className="min-h-screen bg-black text-zinc-100">
|
||||
<section className="border-b border-zinc-900 px-5 pb-16 pt-14 sm:pb-24 sm:pt-20">
|
||||
<div className="mx-auto max-w-4xl">
|
||||
<nav aria-label="Breadcrumb" className="text-sm text-zinc-500">
|
||||
<Link href="/" className="hover:text-purple-200">MCP for Adobe Premiere Pro</Link> <span aria-hidden="true">/</span> Project Intake
|
||||
</nav>
|
||||
<p className="mt-10 font-mono text-xs font-semibold uppercase tracking-[0.18em] text-purple-300">Project Intake · preview-only workflow</p>
|
||||
<h1 className="mt-5 max-w-4xl text-balance text-4xl font-bold tracking-[-0.045em] text-white sm:text-6xl">
|
||||
Turn a project handoff into a <span className="text-purple-300">reviewable intake.</span>
|
||||
</h1>
|
||||
<p className="mt-6 max-w-3xl text-lg leading-8 text-zinc-400 sm:text-xl">
|
||||
For assistant editors and post leads who need to inspect an open Premiere project against an approved template before anyone reorganizes it.
|
||||
</p>
|
||||
<a href="#try" className="mt-8 inline-flex min-h-12 items-center gap-2 rounded-lg bg-purple-300 px-5 py-3 text-sm font-semibold text-black transition-colors hover:bg-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-offset-2 focus-visible:ring-offset-black">
|
||||
Copy the safe first prompt <ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
<p className="mt-4 text-sm text-zinc-500">Free, local-first setup · no account or card required · use a copied test project first</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="px-5 py-14 sm:py-20" aria-labelledby="workflow-heading">
|
||||
<div className="mx-auto max-w-6xl">
|
||||
<div className="max-w-3xl">
|
||||
<p className="font-mono text-xs font-semibold uppercase tracking-[0.16em] text-purple-300">What the workflow does</p>
|
||||
<h2 id="workflow-heading" className="mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl">A clear decision before a project changes.</h2>
|
||||
<p className="mt-5 text-lg leading-8 text-zinc-400">The review gives a supervisor and assistant editor a common record of what the template checked, what needs attention, and what must remain a human decision.</p>
|
||||
</div>
|
||||
<div className="mt-10 grid gap-4 md:grid-cols-3">
|
||||
{steps.map((step, index) => (
|
||||
<article key={step.title} className="border border-zinc-800 bg-[#08080a] p-6 sm:p-7">
|
||||
<p className="font-mono text-xs font-semibold tracking-[0.14em] text-zinc-500">0{index + 1}</p>
|
||||
<step.icon className="mt-8 h-6 w-6 text-purple-300" strokeWidth={1.6} aria-hidden="true" />
|
||||
<h3 className="mt-5 text-xl font-semibold tracking-tight text-white">{step.title}</h3>
|
||||
<p className="mt-3 leading-7 text-zinc-400">{step.description}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="try" className="border-y border-zinc-900 bg-[#050506] px-5 py-14 sm:py-20" aria-labelledby="try-heading">
|
||||
<div className="mx-auto max-w-4xl">
|
||||
<p className="font-mono text-xs font-semibold uppercase tracking-[0.16em] text-purple-300">Try the read-only path</p>
|
||||
<h2 id="try-heading" className="mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl">Copy the safe prompt. Then choose a starter policy.</h2>
|
||||
<p className="mt-5 max-w-3xl text-lg leading-8 text-zinc-400">The first prompt checks the connection only. Then choose a schema-valid starter policy or use your approved template for a path-redacted intake preview.</p>
|
||||
<div className="mt-10"><ProjectIntakePrompts /></div>
|
||||
<div id="starter-template"><ProjectIntakeTemplateBuilder /></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="px-5 py-14 sm:py-20" aria-labelledby="boundary-heading">
|
||||
<div className="mx-auto grid max-w-6xl gap-10 lg:grid-cols-[1fr_1.25fr] lg:items-start">
|
||||
<div>
|
||||
<p className="font-mono text-xs font-semibold uppercase tracking-[0.16em] text-purple-300">Before you rely on it</p>
|
||||
<h2 id="boundary-heading" className="mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl">A report is evidence, not an editorial approval.</h2>
|
||||
</div>
|
||||
<ul className="space-y-4 text-zinc-300">
|
||||
{[
|
||||
"Use a copied or non-sensitive project while you evaluate a new client, connector, or template.",
|
||||
"Starter templates deliberately omit approved media paths. Add any path policy only after a human owner reviews and approves it.",
|
||||
"Start with deterministic organization rules: expected bins, allowed labels, naming patterns, and allowlisted metadata.",
|
||||
"Review every finding and exception with a human owner. A proposed action is not permission to apply it.",
|
||||
"Keep preview, structural verification, playback review, and exported-frame verification as separate evidence classes.",
|
||||
].map((item) => (
|
||||
<li key={item} className="flex gap-3 border-b border-zinc-900 pb-4 last:border-b-0">
|
||||
<CheckCircle2 className="mt-0.5 h-5 w-5 shrink-0 text-purple-300" aria-hidden="true" />
|
||||
<span className="leading-7">{item}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="border-y border-zinc-900 bg-[#050506] px-5 py-14 sm:py-20" aria-labelledby="faq-heading">
|
||||
<div className="mx-auto max-w-4xl">
|
||||
<p className="font-mono text-xs font-semibold uppercase tracking-[0.16em] text-purple-300">Questions before a handoff</p>
|
||||
<h2 id="faq-heading" className="mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl">Straight answers about the preview boundary.</h2>
|
||||
<div className="mt-10 divide-y divide-zinc-800 border-y border-zinc-800">
|
||||
{faqs.map((faq) => (
|
||||
<details key={faq.question} className="group py-5">
|
||||
<summary className="cursor-pointer list-none pr-8 font-medium text-zinc-100 marker:content-none group-open:text-purple-200">{faq.question}</summary>
|
||||
<p className="mt-3 max-w-3xl leading-7 text-zinc-400">{faq.answer}</p>
|
||||
</details>
|
||||
))}
|
||||
</div>
|
||||
<Link href="/blog/premiere-pro-project-intake-checklist/" className="mt-8 inline-flex items-center gap-2 font-medium text-purple-200 hover:text-white">
|
||||
Read the full Project Intake checklist <ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
"use client"
|
||||
|
||||
import { Check, Copy, TriangleAlert } from "lucide-react"
|
||||
import { useState } from "react"
|
||||
import { trackOnboardingEvent } from "@/lib/onboarding-events"
|
||||
import { projectIntakePreviewPrompt, safeFirstPrompt } from "@/lib/product"
|
||||
|
||||
type CopyState = "idle" | "copied" | "unavailable"
|
||||
|
||||
type PromptCardProps = {
|
||||
description: string
|
||||
label: string
|
||||
prompt: string
|
||||
promptKind: "safe_check" | "intake_preview"
|
||||
title: string
|
||||
}
|
||||
|
||||
function PromptCard({ description, label, prompt, promptKind, title }: PromptCardProps) {
|
||||
const [copyState, setCopyState] = useState<CopyState>("idle")
|
||||
|
||||
async function copyPrompt() {
|
||||
try {
|
||||
if (!navigator.clipboard?.writeText) throw new Error("Clipboard API is unavailable")
|
||||
await navigator.clipboard.writeText(prompt)
|
||||
setCopyState("copied")
|
||||
trackOnboardingEvent("onboarding_project_intake_prompt_copied", { prompt_kind: promptKind })
|
||||
window.setTimeout(() => setCopyState("idle"), 2200)
|
||||
} catch {
|
||||
setCopyState("unavailable")
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<article className="rounded-xl border border-zinc-800 bg-[#08080a] p-5 sm:p-6">
|
||||
<p className="font-mono text-xs font-semibold uppercase tracking-[0.15em] text-purple-300">{label}</p>
|
||||
<h3 className="mt-3 text-xl font-semibold tracking-tight text-white">{title}</h3>
|
||||
<p className="mt-3 max-w-2xl leading-7 text-zinc-400">{description}</p>
|
||||
<code className="mt-5 block overflow-x-auto rounded-lg border border-zinc-800 bg-black px-4 py-4 text-sm leading-7 text-zinc-200 whitespace-pre-wrap">{prompt}</code>
|
||||
<div className="mt-4 flex flex-col items-start gap-3 sm:flex-row sm:items-center">
|
||||
<button
|
||||
type="button"
|
||||
onClick={copyPrompt}
|
||||
className="inline-flex min-h-11 items-center gap-2 rounded-md border border-purple-300 bg-purple-300 px-4 py-2 text-sm font-semibold text-black transition-colors hover:bg-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-offset-2 focus-visible:ring-offset-[#08080a]"
|
||||
>
|
||||
{copyState === "copied" ? <Check className="h-4 w-4" aria-hidden="true" /> : <Copy className="h-4 w-4" aria-hidden="true" />}
|
||||
<span>{copyState === "copied" ? "Copied" : "Copy prompt"}</span>
|
||||
</button>
|
||||
{copyState === "unavailable" ? (
|
||||
<p className="inline-flex items-center gap-2 text-sm text-amber-200" role="status">
|
||||
<TriangleAlert className="h-4 w-4 shrink-0" aria-hidden="true" />
|
||||
Copy is unavailable here. Select the visible prompt and copy it manually.
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
export function ProjectIntakePrompts() {
|
||||
return (
|
||||
<div className="grid gap-5" aria-label="Project Intake prompts">
|
||||
<PromptCard
|
||||
label="Step 1 · Read-only"
|
||||
title="Confirm the local connection"
|
||||
description="Open a copied or non-sensitive project and an active sequence in Premiere. This check does not change the project."
|
||||
prompt={safeFirstPrompt}
|
||||
promptKind="safe_check"
|
||||
/>
|
||||
<PromptCard
|
||||
label="Existing policy · Preview only"
|
||||
title="Request the intake review"
|
||||
description="Use an approved intake template. The result is a path-redacted report and proposed organization actions—not permission to organize the project."
|
||||
prompt={projectIntakePreviewPrompt}
|
||||
promptKind="intake_preview"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
"use client"
|
||||
|
||||
import { Check, Copy, ShieldCheck, TriangleAlert } from "lucide-react"
|
||||
import { useState } from "react"
|
||||
import { trackOnboardingEvent } from "@/lib/onboarding-events"
|
||||
import {
|
||||
formatProjectIntakeStarterRequest,
|
||||
projectIntakeStarterTemplates,
|
||||
type ProjectIntakeStarterTemplate,
|
||||
} from "@/lib/project-intake-starter-templates"
|
||||
|
||||
type CopyState = "idle" | "copied" | "unavailable"
|
||||
|
||||
export function ProjectIntakeTemplateBuilder() {
|
||||
const [selected, setSelected] = useState<ProjectIntakeStarterTemplate | null>(null)
|
||||
const [copyState, setCopyState] = useState<CopyState>("idle")
|
||||
|
||||
function selectTemplate(starter: ProjectIntakeStarterTemplate) {
|
||||
setSelected(starter)
|
||||
setCopyState("idle")
|
||||
trackOnboardingEvent("onboarding_project_intake_template_selected", { template_kind: starter.key })
|
||||
}
|
||||
|
||||
async function copyRequest() {
|
||||
if (!selected) return
|
||||
try {
|
||||
if (!navigator.clipboard?.writeText) throw new Error("Clipboard API is unavailable")
|
||||
await navigator.clipboard.writeText(formatProjectIntakeStarterRequest(selected))
|
||||
setCopyState("copied")
|
||||
trackOnboardingEvent("onboarding_project_intake_template_copied", { template_kind: selected.key })
|
||||
window.setTimeout(() => setCopyState("idle"), 2200)
|
||||
} catch {
|
||||
setCopyState("unavailable")
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mt-10 border border-zinc-800 bg-[#08080a] p-5 sm:p-7">
|
||||
<fieldset>
|
||||
<legend className="text-xl font-semibold tracking-tight text-white">Choose a no-sensitive-data starter policy</legend>
|
||||
<p className="mt-3 max-w-3xl leading-7 text-zinc-400">Each sample is valid for <code>preview_project_intake</code>, has no approved media paths, and requests a preview only. A policy owner must review and replace its bins, media rules, and checks before real use.</p>
|
||||
<div className="mt-6 grid gap-3">
|
||||
{projectIntakeStarterTemplates.map((starter) => {
|
||||
const isSelected = selected?.key === starter.key
|
||||
return (
|
||||
<label
|
||||
key={starter.key}
|
||||
className={`block cursor-pointer rounded-lg border p-4 transition-colors focus-within:outline-none focus-within:ring-2 focus-within:ring-purple-300 ${isSelected ? "border-purple-300 bg-purple-300/10" : "border-zinc-800 bg-black hover:border-zinc-600"}`}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
name="project-intake-starter-template"
|
||||
value={starter.key}
|
||||
checked={isSelected}
|
||||
onChange={() => selectTemplate(starter)}
|
||||
className="sr-only"
|
||||
/>
|
||||
<span className="flex items-start gap-3">
|
||||
<span className={`mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border ${isSelected ? "border-purple-300 bg-purple-300 text-black" : "border-zinc-600"}`} aria-hidden="true">
|
||||
{isSelected ? <Check className="h-3.5 w-3.5" strokeWidth={3} /> : null}
|
||||
</span>
|
||||
<span>
|
||||
<span className="block font-semibold text-white">{starter.label}</span>
|
||||
<span className="mt-1 block leading-6 text-zinc-400">{starter.description}</span>
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
{selected ? (
|
||||
<section className="mt-7 border-t border-zinc-800 pt-7" aria-live="polite" aria-labelledby="starter-request-heading">
|
||||
<div className="flex items-start gap-3">
|
||||
<ShieldCheck className="mt-0.5 h-5 w-5 shrink-0 text-purple-300" aria-hidden="true" />
|
||||
<div>
|
||||
<h3 id="starter-request-heading" className="font-semibold text-white">{selected.label} request</h3>
|
||||
<ul className="mt-3 space-y-1 text-sm leading-6 text-zinc-400">
|
||||
{selected.checks.map((check) => <li key={check}>• {check}</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<pre className="mt-5 overflow-x-auto rounded-lg border border-zinc-800 bg-black p-4 text-sm leading-6 text-zinc-200"><code>{formatProjectIntakeStarterRequest(selected)}</code></pre>
|
||||
<div className="mt-4 flex flex-col items-start gap-3 sm:flex-row sm:items-center">
|
||||
<button
|
||||
type="button"
|
||||
onClick={copyRequest}
|
||||
className="inline-flex min-h-11 items-center gap-2 rounded-md border border-purple-300 bg-purple-300 px-4 py-2 text-sm font-semibold text-black transition-colors hover:bg-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-offset-2 focus-visible:ring-offset-[#08080a]"
|
||||
>
|
||||
{copyState === "copied" ? <Check className="h-4 w-4" aria-hidden="true" /> : <Copy className="h-4 w-4" aria-hidden="true" />}
|
||||
<span>{copyState === "copied" ? "Copied" : "Copy starter request"}</span>
|
||||
</button>
|
||||
{copyState === "unavailable" ? (
|
||||
<p className="inline-flex items-center gap-2 text-sm text-amber-200" role="status">
|
||||
<TriangleAlert className="h-4 w-4 shrink-0" aria-hidden="true" />
|
||||
Copy is unavailable here. Select the visible request and copy it manually.
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
</section>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { MetadataRoute } from "next"
|
||||
|
||||
export const dynamic = "force-static"
|
||||
|
||||
const aiCrawlerUserAgents = [
|
||||
"OAI-SearchBot",
|
||||
"ChatGPT-User",
|
||||
"GPTBot",
|
||||
"ClaudeBot",
|
||||
"Claude-SearchBot",
|
||||
"PerplexityBot",
|
||||
"Google-Extended",
|
||||
"Applebot-Extended",
|
||||
"Meta-ExternalAgent",
|
||||
"Meta-ExternalFetcher",
|
||||
]
|
||||
|
||||
export default function robots(): MetadataRoute.Robots {
|
||||
return {
|
||||
rules: [
|
||||
{
|
||||
userAgent: "*",
|
||||
allow: "/",
|
||||
disallow: ["/mcp", "/health"],
|
||||
},
|
||||
{
|
||||
userAgent: aiCrawlerUserAgents,
|
||||
allow: "/",
|
||||
disallow: ["/mcp", "/health"],
|
||||
},
|
||||
],
|
||||
sitemap: "https://premiere-pro-mcp.com/sitemap.xml",
|
||||
host: "https://premiere-pro-mcp.com",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import type { MetadataRoute } from "next"
|
||||
import { articles } from "@/lib/articles"
|
||||
import { product } from "@/lib/product"
|
||||
|
||||
export const dynamic = "force-static"
|
||||
|
||||
const siteUrl = "https://premiere-pro-mcp.com"
|
||||
const latestArticleDate = new Date(
|
||||
`${articles.reduce((latest, article) => article.modifiedAt > latest ? article.modifiedAt : latest, articles[0].modifiedAt)}T00:00:00Z`,
|
||||
)
|
||||
const productContentDate = new Date(`${product.releaseDate}T00:00:00Z`)
|
||||
|
||||
export default function sitemap(): MetadataRoute.Sitemap {
|
||||
return [
|
||||
{
|
||||
url: `${siteUrl}/`,
|
||||
lastModified: productContentDate,
|
||||
changeFrequency: "weekly",
|
||||
priority: 1,
|
||||
},
|
||||
{
|
||||
url: `${siteUrl}/docs/`,
|
||||
lastModified: productContentDate,
|
||||
changeFrequency: "weekly",
|
||||
priority: 0.8,
|
||||
},
|
||||
{
|
||||
url: `${siteUrl}/project-intake/`,
|
||||
lastModified: new Date("2026-08-26T00:00:00Z"),
|
||||
changeFrequency: "weekly",
|
||||
priority: 0.9,
|
||||
},
|
||||
{
|
||||
url: `${siteUrl}/premiere-pro-collaboration-workflow/`,
|
||||
lastModified: new Date("2026-08-27T00:00:00Z"),
|
||||
changeFrequency: "weekly",
|
||||
priority: 0.9,
|
||||
},
|
||||
{
|
||||
url: `${siteUrl}/blog/`,
|
||||
lastModified: latestArticleDate,
|
||||
changeFrequency: "weekly",
|
||||
priority: 0.9,
|
||||
},
|
||||
...articles.map((article) => ({
|
||||
url: `${siteUrl}/blog/${article.slug}/`,
|
||||
lastModified: new Date(`${article.modifiedAt}T00:00:00Z`),
|
||||
changeFrequency: "monthly" as const,
|
||||
priority: 0.8,
|
||||
})),
|
||||
{
|
||||
url: `${siteUrl}/facts/`,
|
||||
lastModified: productContentDate,
|
||||
changeFrequency: "weekly",
|
||||
priority: 0.9,
|
||||
},
|
||||
{
|
||||
url: `${siteUrl}/changelog/`,
|
||||
lastModified: productContentDate,
|
||||
changeFrequency: "monthly",
|
||||
priority: 0.7,
|
||||
},
|
||||
{
|
||||
url: `${siteUrl}/privacy/`,
|
||||
lastModified: latestArticleDate,
|
||||
changeFrequency: "yearly",
|
||||
priority: 0.5,
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "new-york",
|
||||
"rsc": true,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "",
|
||||
"css": "app/globals.css",
|
||||
"baseColor": "neutral",
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
},
|
||||
"iconLibrary": "lucide",
|
||||
"rtl": false,
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
"ui": "@/components/ui",
|
||||
"lib": "@/lib",
|
||||
"hooks": "@/hooks"
|
||||
},
|
||||
"registries": {}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
"use client"
|
||||
|
||||
import { useEffect, useRef } from "react"
|
||||
import { usePathname } from "next/navigation"
|
||||
import { trackOnboardingEvent } from "@/lib/onboarding-events"
|
||||
|
||||
/**
|
||||
* Records bounded, anonymous page views for acquisition measurement. It sends
|
||||
* no prompt, project, media, identity, or file-path data and respects DNT/GPC.
|
||||
*/
|
||||
export function MarketingPageView() {
|
||||
const pathname = usePathname()
|
||||
const lastTrackedPath = useRef<string | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (lastTrackedPath.current === pathname) return
|
||||
lastTrackedPath.current = pathname
|
||||
trackOnboardingEvent("marketing_viewed")
|
||||
}, [pathname])
|
||||
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import { AlertTriangle, ArrowDown, CheckCircle2, FileCode2, PlugZap, TerminalSquare } from "lucide-react"
|
||||
import Image from "next/image"
|
||||
import { product } from "@/lib/product"
|
||||
|
||||
const bridgeSteps = [
|
||||
{
|
||||
icon: TerminalSquare,
|
||||
title: "Your AI calls a tool",
|
||||
description: "Claude, Cursor, Windsurf, or another MCP client sends a structured request to the local server.",
|
||||
},
|
||||
{
|
||||
icon: FileCode2,
|
||||
title: "The bridge runs it in Premiere",
|
||||
description: "A versioned helper library and small ES3 script pass through a private shared temp directory.",
|
||||
},
|
||||
{
|
||||
icon: PlugZap,
|
||||
title: "Premiere returns a result",
|
||||
description: "The CEP bridge executes the command and sends structured data, confirmation, or diagnostics back to the client.",
|
||||
},
|
||||
]
|
||||
|
||||
const diagnostics = [
|
||||
{
|
||||
icon: CheckCircle2,
|
||||
title: "Automatic bridge startup",
|
||||
description: "The CEP bridge creates its temp directory and starts polling when Premiere activates.",
|
||||
},
|
||||
{
|
||||
icon: AlertTriangle,
|
||||
title: "Modal-stall diagnostics",
|
||||
description: "In-flight heartbeats help distinguish an open Premiere dialog from a disconnected bridge.",
|
||||
},
|
||||
]
|
||||
|
||||
export function ArchitectureSection() {
|
||||
return (
|
||||
<section id="how-it-works" className="reveal-section border-y border-zinc-900 bg-[#050506] px-5 py-24 md:py-32">
|
||||
<div className="mx-auto max-w-6xl">
|
||||
<figure className="mb-16 overflow-hidden rounded-xl border border-white/10 bg-black">
|
||||
<Image
|
||||
src="/marketing/premiere-pro-mcp-workflow-v1.png"
|
||||
alt="Local-first workflow: an AI assistant sends a request through the MCP bridge to Premiere, which returns a verified result."
|
||||
width={1672}
|
||||
height={941}
|
||||
sizes="(max-width: 768px) 100vw, 1152px"
|
||||
className="h-auto w-full"
|
||||
/>
|
||||
<figcaption className="border-t border-zinc-800 px-5 py-4 text-sm leading-6 text-zinc-400">
|
||||
The recommended path keeps the assistant, MCP bridge, Premiere, and project media on the same computer. A verified result still depends on a live host connection.
|
||||
</figcaption>
|
||||
</figure>
|
||||
<div className="grid gap-16 lg:grid-cols-2 lg:gap-20">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold tracking-tight text-white md:text-4xl">How the bridge <span className="text-purple-400">works</span></h2>
|
||||
<p className="mt-4 max-w-xl text-base leading-7 text-zinc-400">
|
||||
A local-first file bridge keeps the control path inspectable and avoids exposing your project media to the MCP server.
|
||||
</p>
|
||||
<div className="mt-10">
|
||||
{bridgeSteps.map((step, index) => (
|
||||
<div key={step.title} className="relative flex gap-5 pb-9 last:pb-0">
|
||||
{index < bridgeSteps.length - 1 && <span className="absolute left-[19px] top-10 h-[calc(100%-2rem)] w-px bg-zinc-800" aria-hidden="true" />}
|
||||
<span className="relative z-10 grid h-10 w-10 shrink-0 place-items-center rounded-md border border-zinc-800 bg-zinc-950 text-purple-400">
|
||||
<step.icon className="h-5 w-5" strokeWidth={1.6} />
|
||||
</span>
|
||||
<div>
|
||||
<h3 className="text-base font-semibold text-zinc-100">{step.title}</h3>
|
||||
<p className="mt-2 text-sm leading-6 text-zinc-500">{step.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold tracking-tight text-white md:text-4xl">Compatibility & <span className="text-purple-400">diagnostics</span></h2>
|
||||
<p className="mt-4 max-w-xl text-base leading-7 text-zinc-400">
|
||||
The signed CEP connector is the default route for Premiere Pro {product.premiereCompatibility} on macOS and Windows. A modern UXP bridge adds capability-gated workflows on compatible newer hosts.
|
||||
</p>
|
||||
<div className="mt-10 space-y-4">
|
||||
{diagnostics.map((item) => (
|
||||
<article key={item.title} className="flex gap-4 rounded-xl border border-zinc-800 bg-zinc-950 p-5">
|
||||
<item.icon className="mt-0.5 h-6 w-6 shrink-0 text-purple-300" strokeWidth={1.5} />
|
||||
<div>
|
||||
<h3 className="text-base font-semibold text-zinc-100">{item.title}</h3>
|
||||
<p className="mt-2 text-sm leading-6 text-zinc-500">{item.description}</p>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-6 rounded-xl border border-amber-500/20 bg-amber-500/[0.04] p-5">
|
||||
<p className="text-sm leading-6 text-zinc-400">
|
||||
<span className="font-semibold text-amber-200">Know the boundary:</span> UXP is capability-gated for compatible newer Premiere workflows; it is not yet the default installer or a replacement for CEP. Premiere’s undocumented QE DOM is powerful but imperfect, so results should be verified before you rely on them.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-16 flex flex-col gap-4 rounded-xl border border-zinc-800 bg-black px-5 py-5 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<p className="text-sm font-medium text-zinc-200">Need the full tool list, schemas, or troubleshooting guide?</p>
|
||||
<p className="mt-1 text-sm text-zinc-500">The README documents every setup path and known security boundary.</p>
|
||||
</div>
|
||||
<a
|
||||
href="https://github.com/leancoderkavy/premiere-pro-mcp#readme"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex shrink-0 items-center gap-2 text-sm font-semibold text-purple-300 transition-colors hover:text-purple-200"
|
||||
>
|
||||
Read the documentation <ArrowDown className="h-4 w-4 -rotate-90" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import {
|
||||
ArrowUpRight,
|
||||
Check,
|
||||
CheckCircle2,
|
||||
ChevronDown,
|
||||
CircleHelp,
|
||||
Copy,
|
||||
Download,
|
||||
ExternalLink,
|
||||
Laptop,
|
||||
LockKeyhole,
|
||||
MonitorCog,
|
||||
ShieldCheck,
|
||||
Sparkles,
|
||||
} from "lucide-react"
|
||||
|
||||
import { product, safeFirstPrompt } from "@/lib/product"
|
||||
import { trackOnboardingEvent } from "@/lib/onboarding-events"
|
||||
|
||||
type AssistantRoute = {
|
||||
id: "claude" | "cursor" | "vscode" | "other"
|
||||
name: string
|
||||
shortDescription: string
|
||||
availability: string
|
||||
primaryAction: string
|
||||
href: string
|
||||
detail: string
|
||||
status: "recommended" | "guided" | "advanced"
|
||||
}
|
||||
|
||||
const assistantRoutes: AssistantRoute[] = [
|
||||
{
|
||||
id: "claude",
|
||||
name: "Claude Desktop",
|
||||
shortDescription: "Download the self-contained desktop bundle.",
|
||||
availability: "Recommended for the easiest start",
|
||||
primaryAction: "Download Claude Desktop bundle",
|
||||
href: product.downloads.claudeBundle,
|
||||
detail:
|
||||
"Open the downloaded bundle in Claude Desktop. It includes the local server, so this path does not ask you to install Node just to connect Claude.",
|
||||
status: "recommended",
|
||||
},
|
||||
{
|
||||
id: "cursor",
|
||||
name: "Cursor",
|
||||
shortDescription: "Use Cursor’s MCP settings to add the local connector.",
|
||||
availability: "Guided route",
|
||||
primaryAction: "Read the Cursor setup guide",
|
||||
href: product.links.readme,
|
||||
detail:
|
||||
"A one-click Cursor installer is not currently shipped. The guide explains the supported local route; manual configuration stays in Advanced setup below.",
|
||||
status: "guided",
|
||||
},
|
||||
{
|
||||
id: "vscode",
|
||||
name: "VS Code / Copilot",
|
||||
shortDescription: "Connect through your editor’s MCP settings.",
|
||||
availability: "Guided route",
|
||||
primaryAction: "Read the VS Code setup guide",
|
||||
href: product.links.readme,
|
||||
detail:
|
||||
"A VS Code Marketplace install is not currently shipped. Use the guide for the supported local route, or see Advanced setup if your editor asks for a server command.",
|
||||
status: "guided",
|
||||
},
|
||||
{
|
||||
id: "other",
|
||||
name: "Another assistant",
|
||||
shortDescription: "Use any MCP-compatible desktop client.",
|
||||
availability: "Advanced route",
|
||||
primaryAction: "Open compatibility guide",
|
||||
href: product.links.readme,
|
||||
detail:
|
||||
"If your assistant supports local MCP servers, it can use MCP for Adobe Premiere Pro. Its setup may require its own settings screen or the manual configuration in Advanced setup.",
|
||||
status: "advanced",
|
||||
},
|
||||
]
|
||||
|
||||
function CopyButton({ text, label }: { text: string; label: string }) {
|
||||
const [copied, setCopied] = useState(false)
|
||||
|
||||
async function copy() {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text)
|
||||
setCopied(true)
|
||||
trackOnboardingEvent("onboarding_safe_prompt_copied")
|
||||
window.setTimeout(() => setCopied(false), 1800)
|
||||
} catch {
|
||||
setCopied(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={copy}
|
||||
className="inline-flex min-h-11 shrink-0 items-center gap-2 rounded-md border border-zinc-700 bg-zinc-900 px-3 py-2 text-sm font-medium text-zinc-200 transition-colors hover:border-zinc-500 hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-offset-2 focus-visible:ring-offset-[#08080a]"
|
||||
aria-label={label}
|
||||
>
|
||||
{copied ? <Check className="h-4 w-4 text-emerald-300" aria-hidden="true" /> : <Copy className="h-4 w-4" aria-hidden="true" />}
|
||||
<span aria-live="polite">{copied ? "Copied" : "Copy prompt"}</span>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
function statusClasses(status: AssistantRoute["status"]) {
|
||||
if (status === "recommended") return "border-purple-400/50 bg-purple-500/[0.08] text-purple-100"
|
||||
if (status === "guided") return "border-zinc-700 bg-zinc-950 text-zinc-200"
|
||||
return "border-zinc-800 bg-zinc-950/50 text-zinc-300"
|
||||
}
|
||||
|
||||
export function ConnectSection() {
|
||||
const [activeId, setActiveId] = useState<AssistantRoute["id"]>("claude")
|
||||
const [advancedOpen, setAdvancedOpen] = useState(false)
|
||||
const [recoveryOpen, setRecoveryOpen] = useState(false)
|
||||
const activeRoute = assistantRoutes.find((route) => route.id === activeId) ?? assistantRoutes[0]
|
||||
|
||||
function selectRoute(route: AssistantRoute) {
|
||||
setActiveId(route.id)
|
||||
trackOnboardingEvent("onboarding_assistant_selected", { assistant: route.id })
|
||||
}
|
||||
|
||||
function trackDownload(route: AssistantRoute) {
|
||||
trackOnboardingEvent("onboarding_download_started", { route: route.id })
|
||||
}
|
||||
|
||||
return (
|
||||
<section id="install" className="reveal-section bg-black px-5 py-24 md:py-32" aria-labelledby="setup-heading">
|
||||
<div className="mx-auto max-w-6xl">
|
||||
<div className="max-w-3xl">
|
||||
<h2 id="setup-heading" className="text-balance text-3xl font-bold tracking-tight text-white md:text-5xl">
|
||||
Connect the <span className="text-violet-300">assistant you already use.</span>
|
||||
</h2>
|
||||
<p className="mt-5 text-lg leading-8 text-zinc-400">
|
||||
Pick your client. The first step only checks that it can reach Premiere; it makes no edits.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-12 grid gap-3 sm:grid-cols-2 lg:grid-cols-4" role="list" aria-label="AI assistant setup routes">
|
||||
{assistantRoutes.map((route) => {
|
||||
const selected = activeId === route.id
|
||||
return (
|
||||
<button
|
||||
key={route.id}
|
||||
type="button"
|
||||
onClick={() => selectRoute(route)}
|
||||
aria-pressed={selected}
|
||||
className={`group flex min-h-52 flex-col rounded-xl border p-5 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-offset-4 focus-visible:ring-offset-black ${
|
||||
selected ? statusClasses(route.status) : "border-zinc-800 bg-[#08080a] text-zinc-300 hover:border-zinc-600 hover:bg-zinc-950"
|
||||
}`}
|
||||
>
|
||||
<span className="flex items-center justify-between gap-3">
|
||||
{route.status === "recommended" ? <Sparkles className="h-5 w-5 text-purple-300" aria-hidden="true" /> : <Laptop className="h-5 w-5 text-zinc-400" aria-hidden="true" />}
|
||||
<span className="text-xs font-semibold uppercase tracking-[0.14em] text-zinc-500">{route.availability}</span>
|
||||
</span>
|
||||
<span className="mt-7 text-lg font-semibold text-white">{route.name}</span>
|
||||
<span className="mt-3 text-sm leading-6 text-zinc-400">{route.shortDescription}</span>
|
||||
{selected ? <CheckCircle2 className="mt-auto h-5 w-5 text-purple-300" aria-label={`${route.name} selected`} /> : <span className="mt-auto h-5 w-5 rounded-full border border-zinc-700" aria-hidden="true" />}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="mt-6 grid gap-6 border-y border-zinc-800 py-7 lg:grid-cols-[minmax(0,1fr)_auto] lg:items-center">
|
||||
<div>
|
||||
<p className="text-sm font-semibold text-zinc-100">{activeRoute.name}</p>
|
||||
<p className="mt-2 max-w-3xl text-sm leading-6 text-zinc-400">{activeRoute.detail}</p>
|
||||
</div>
|
||||
<a
|
||||
href={activeRoute.href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={() => trackDownload(activeRoute)}
|
||||
className="inline-flex min-h-12 items-center justify-center gap-2 rounded-lg bg-gradient-to-r from-[#8b7cff] to-[#ef76b9] px-5 text-sm font-semibold text-white shadow-[0_12px_40px_rgba(139,124,255,0.2)] transition-transform hover:-translate-y-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-200 focus-visible:ring-offset-4 focus-visible:ring-offset-black"
|
||||
>
|
||||
{activeRoute.id === "claude" ? <Download className="h-4 w-4" aria-hidden="true" /> : <ExternalLink className="h-4 w-4" aria-hidden="true" />}
|
||||
{activeRoute.primaryAction}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="mt-14 grid gap-12 lg:grid-cols-[minmax(0,1fr)_22rem]">
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-white">Set up in four steps.</h3>
|
||||
<ol className="mt-8 grid gap-7 sm:grid-cols-2">
|
||||
<li className="border-t border-purple-400/35 pt-5">
|
||||
<span className="font-mono text-sm text-purple-300">01</span>
|
||||
<h4 className="mt-4 text-base font-semibold text-zinc-100">Install the Premiere connector</h4>
|
||||
<p className="mt-2 text-sm leading-6 text-zinc-400">This separate CEP connector is what lets your assistant talk to Premiere. Open the download with a trusted ZXP installer; if your computer has none, use the npm installer under Advanced setup.</p>
|
||||
<a
|
||||
href={product.downloads.signedCepConnector}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={() => trackOnboardingEvent("onboarding_download_started", { route: "cep_connector" })}
|
||||
className="mt-4 inline-flex min-h-11 items-center gap-2 text-sm font-semibold text-purple-200 transition-colors hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-offset-2 focus-visible:ring-offset-black"
|
||||
>
|
||||
<Download className="h-4 w-4" aria-hidden="true" /> Download connector package <ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</li>
|
||||
<li className="border-t border-zinc-800 pt-5">
|
||||
<span className="font-mono text-sm text-purple-300">02</span>
|
||||
<h4 className="mt-4 text-base font-semibold text-zinc-100">Connect {activeRoute.name}</h4>
|
||||
<p className="mt-2 text-sm leading-6 text-zinc-400">Finish the route above, then fully close and reopen both your assistant and Premiere.</p>
|
||||
</li>
|
||||
<li className="border-t border-zinc-800 pt-5">
|
||||
<span className="font-mono text-sm text-purple-300">03</span>
|
||||
<h4 className="mt-4 text-base font-semibold text-zinc-100">Run a safe check</h4>
|
||||
<p className="mt-2 text-sm leading-6 text-zinc-400">Open a project and use the read-only prompt below. It runs the connection check and makes no changes.</p>
|
||||
</li>
|
||||
<li className="border-t border-zinc-800 pt-5">
|
||||
<span className="font-mono text-sm text-purple-300">04</span>
|
||||
<h4 className="mt-4 text-base font-semibold text-zinc-100">Ready to edit</h4>
|
||||
<p className="mt-2 text-sm leading-6 text-zinc-400">Once the connection check passes, try a preview before applying any edits.</p>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<div className="mt-10 rounded-xl border border-purple-400/30 bg-purple-500/[0.06] p-5 sm:p-6">
|
||||
<div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
|
||||
<div>
|
||||
<p className="flex items-center gap-2 text-sm font-semibold text-purple-100"><ShieldCheck className="h-4 w-4" aria-hidden="true" /> Safe first prompt</p>
|
||||
<p className="mt-3 max-w-2xl font-mono text-sm leading-7 text-zinc-100">{safeFirstPrompt}</p>
|
||||
</div>
|
||||
<CopyButton text={safeFirstPrompt} label="Copy the safe first prompt" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<aside className="space-y-5" aria-label="Setup help and privacy">
|
||||
<div className="rounded-xl border border-zinc-800 bg-[#08080a] p-5">
|
||||
<p className="flex items-center gap-2 text-sm font-semibold text-zinc-100"><MonitorCog className="h-4 w-4 text-violet-200" aria-hidden="true" /> Compatibility details</p>
|
||||
<p className="mt-3 text-sm leading-6 text-zinc-400">The signed CEP connector is the default compatibility route for Premiere Pro {product.premiereCompatibility} on Windows and macOS.</p>
|
||||
<p className="mt-3 text-sm leading-6 text-zinc-400">The modern UXP bridge is capability-gated for compatible Premiere {product.uxpMinimumVersion}+ workflows. It is not a Creative Cloud Marketplace install and does not replace CEP in the default path.</p>
|
||||
<a href="/docs/#compatibility-heading" className="mt-4 inline-flex min-h-11 items-center gap-2 text-sm font-semibold text-purple-200 transition-colors hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-offset-2 focus-visible:ring-offset-[#08080a]">
|
||||
See compatibility details <ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-zinc-800 bg-[#08080a] p-5">
|
||||
<p className="flex items-center gap-2 text-sm font-semibold text-zinc-100"><LockKeyhole className="h-4 w-4 text-purple-300" aria-hidden="true" /> What the first check shares</p>
|
||||
<p className="mt-3 text-sm leading-6 text-zinc-400">The prompt runs a connection check; it makes no edits and does not ask for footage to be uploaded.</p>
|
||||
<p className="mt-3 text-sm leading-6 text-zinc-500">Your assistant's own privacy settings still apply. If site analytics is enabled, setup clicks record only a route and action—not prompts, media, project names, or file paths.</p>
|
||||
</div>
|
||||
|
||||
<details
|
||||
className="group rounded-xl border border-zinc-800 bg-[#08080a] p-5"
|
||||
open={recoveryOpen}
|
||||
onToggle={(event) => {
|
||||
const open = event.currentTarget.open
|
||||
setRecoveryOpen(open)
|
||||
if (open) trackOnboardingEvent("onboarding_recovery_opened")
|
||||
}}
|
||||
>
|
||||
<summary className="flex min-h-8 cursor-pointer list-none items-center justify-between gap-4 text-sm font-semibold text-zinc-100 marker:content-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300">
|
||||
<span className="flex items-center gap-2"><CircleHelp className="h-4 w-4 text-purple-300" aria-hidden="true" /> Need help connecting?</span>
|
||||
<ChevronDown className="h-4 w-4 text-zinc-400 transition-transform group-open:rotate-180" aria-hidden="true" />
|
||||
</summary>
|
||||
<ol className="mt-4 list-decimal space-y-3 pl-5 text-sm leading-6 text-zinc-400">
|
||||
<li>Quit and reopen both Premiere and your assistant.</li>
|
||||
<li>Open a project and make sure an active sequence is selected.</li>
|
||||
<li>In Premiere, look for <span className="text-zinc-200">Window → Extensions → MCP for Adobe Premiere Pro</span>.</li>
|
||||
<li>Use the safe prompt again. If it still fails, share the connection state—not your project media—with support.</li>
|
||||
</ol>
|
||||
<a href={product.links.issues} target="_blank" rel="noopener noreferrer" className="mt-5 inline-flex min-h-11 items-center gap-2 text-sm font-semibold text-purple-200 hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-offset-2 focus-visible:ring-offset-[#08080a]">
|
||||
Get connection help <ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</details>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<details
|
||||
className="group mt-14 border-t border-zinc-800 pt-6"
|
||||
open={advancedOpen}
|
||||
onToggle={(event) => {
|
||||
const open = event.currentTarget.open
|
||||
setAdvancedOpen(open)
|
||||
if (open) trackOnboardingEvent("onboarding_advanced_opened")
|
||||
}}
|
||||
>
|
||||
<summary className="flex min-h-11 cursor-pointer list-none items-center justify-between gap-5 text-sm font-semibold text-zinc-300 marker:content-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300">
|
||||
<span>Advanced setup for npm, manual configuration, and other MCP clients</span>
|
||||
<ChevronDown className="h-4 w-4 text-zinc-500 transition-transform group-open:rotate-180" aria-hidden="true" />
|
||||
</summary>
|
||||
<div className="mt-5 grid gap-6 rounded-xl border border-zinc-800 bg-[#08080a] p-5 lg:grid-cols-2 lg:p-7">
|
||||
<div>
|
||||
<h3 className="text-base font-semibold text-white">Install from npm</h3>
|
||||
<p className="mt-2 text-sm leading-6 text-zinc-400">Use this route if your assistant does not support a native bundle. It requires Node.js {product.nodeVersion}+.</p>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg border border-zinc-800 bg-black p-4 text-xs leading-6 text-emerald-300"><code>npm install -g premiere-pro-mcp{`\n`}premiere-pro-mcp --install-cep</code></pre>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-base font-semibold text-white">Manual server configuration</h3>
|
||||
<p className="mt-2 text-sm leading-6 text-zinc-400">Only use this when your client asks for a command. Keep Premiere, the connector, and the client on the same computer.</p>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg border border-zinc-800 bg-black p-4 text-xs leading-6 text-zinc-300"><code>{`{\n "mcpServers": {\n "premiere-pro": {\n "command": "premiere-pro-mcp"\n }\n }\n}`}</code></pre>
|
||||
</div>
|
||||
<div className="lg:col-span-2">
|
||||
<a href={product.links.readme} target="_blank" rel="noopener noreferrer" className="inline-flex min-h-11 items-center gap-2 text-sm font-semibold text-purple-200 transition-colors hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-offset-2 focus-visible:ring-offset-[#08080a]">
|
||||
Read the full technical guide <ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
"use client"
|
||||
|
||||
import { Clapperboard, Film, WandSparkles } from "lucide-react"
|
||||
import Image from "next/image"
|
||||
import { useState } from "react"
|
||||
import { product } from "@/lib/product"
|
||||
import { trackOnboardingEvent } from "@/lib/onboarding-events"
|
||||
|
||||
const outcomes = [
|
||||
{ icon: Film, label: "Timeline", detail: "B-roll inserted on V2" },
|
||||
{ icon: WandSparkles, label: "Finish", detail: "Grade and title applied" },
|
||||
{ icon: Clapperboard, label: "Delivery", detail: "ProRes export queued" },
|
||||
]
|
||||
|
||||
export function DemoVideoSection() {
|
||||
const [isPlaying, setIsPlaying] = useState(false)
|
||||
|
||||
function startDemo() {
|
||||
setIsPlaying(true)
|
||||
trackOnboardingEvent("marketing_demo_played", { demo: "illustrated_workflow" })
|
||||
}
|
||||
|
||||
return (
|
||||
<section id="demo" className="reveal-section overflow-hidden border-y border-zinc-900 bg-[#050506] px-5 py-24 md:py-32">
|
||||
<div className="mx-auto max-w-6xl">
|
||||
<div className="grid items-end gap-8 md:grid-cols-[1fr_auto]">
|
||||
<div className="max-w-3xl">
|
||||
<p className="font-mono text-xs font-semibold uppercase tracking-[0.18em] text-purple-300">Illustrated product walkthrough</p>
|
||||
<h2 className="mt-4 text-balance text-4xl font-bold tracking-[-0.035em] text-white md:text-6xl">
|
||||
From prompt to an explicit result.
|
||||
</h2>
|
||||
</div>
|
||||
<p className="max-w-sm text-sm leading-7 text-zinc-400 md:text-right">
|
||||
See the intended request-to-result flow. This animation is not a recording of a live Premiere host session.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="demo-video-shell relative mt-14 overflow-hidden rounded-2xl border border-white/10 bg-black shadow-[0_38px_100px_rgba(0,0,0,0.58)]">
|
||||
{isPlaying ? (
|
||||
<video
|
||||
className="aspect-video w-full bg-[#060608]"
|
||||
controls
|
||||
autoPlay
|
||||
muted
|
||||
loop
|
||||
playsInline
|
||||
preload="metadata"
|
||||
poster="/premiere-pro-mcp-demo-poster.png"
|
||||
aria-label="MCP for Adobe Premiere Pro inserts B-roll, applies a color grade and title, then queues a ProRes export"
|
||||
>
|
||||
<source src="/premiere-pro-mcp-demo.mp4" type="video/mp4" />
|
||||
Your browser does not support embedded video. The demo shows an AI request becoming a structured Premiere Pro edit.
|
||||
</video>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
onClick={startDemo}
|
||||
className="group relative block aspect-video w-full overflow-hidden bg-[#060608] text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-inset"
|
||||
aria-label="Play the illustrated MCP for Adobe Premiere Pro workflow walkthrough"
|
||||
>
|
||||
<Image
|
||||
src="/premiere-pro-mcp-demo-poster.png"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
fill
|
||||
sizes="(max-width: 768px) 100vw, 1152px"
|
||||
className="h-full w-full object-cover opacity-85 transition duration-300 group-hover:scale-[1.01] group-hover:opacity-100"
|
||||
loading="lazy"
|
||||
/>
|
||||
<span className="absolute inset-0 grid place-items-center bg-black/20">
|
||||
<span className="rounded-full border border-white/30 bg-black/75 px-5 py-3 text-sm font-semibold text-white shadow-lg backdrop-blur transition group-hover:border-purple-300 group-hover:bg-black/90">
|
||||
Play illustrated walkthrough
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
)}
|
||||
<span className="pointer-events-none absolute right-[3%] top-[4%] rounded bg-[#09090d] px-2 py-1 font-mono text-[9px] text-zinc-400 sm:text-[11px]">
|
||||
LOCAL BRIDGE · {product.coreToolCount} TOOLS
|
||||
</span>
|
||||
<div className="pointer-events-none absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-purple-300/60 to-transparent" aria-hidden="true" />
|
||||
</div>
|
||||
|
||||
<div className="mt-8 grid border-t border-zinc-800 sm:grid-cols-3">
|
||||
{outcomes.map((outcome) => (
|
||||
<div key={outcome.label} className="flex items-center gap-4 border-b border-zinc-800 py-5 sm:border-b-0 sm:border-r sm:px-6 first:sm:pl-0 last:sm:border-r-0">
|
||||
<outcome.icon className="h-5 w-5 shrink-0 text-purple-300" strokeWidth={1.6} />
|
||||
<div>
|
||||
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-zinc-500">{outcome.label}</p>
|
||||
<p className="mt-1 text-sm text-zinc-200">{outcome.detail}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
import { Captions, Check, Layers3, Play, Sparkles } from "lucide-react"
|
||||
|
||||
const clips = [
|
||||
{ label: "Interview_A", start: "2%", width: "31%", color: "bg-[#6557c8]", delay: "80ms" },
|
||||
{ label: "B-roll_City", start: "35%", width: "25%", color: "bg-[#7b66d9]", delay: "180ms" },
|
||||
{ label: "Product_Closeup", start: "62%", width: "36%", color: "bg-[#8f72e8]", delay: "280ms" },
|
||||
] as const
|
||||
|
||||
const brollClips = [
|
||||
{ label: "B-roll_01", start: "14%", width: "23%", delay: "320ms" },
|
||||
{ label: "B-roll_02", start: "44%", width: "28%", delay: "400ms" },
|
||||
] as const
|
||||
|
||||
const waveform = [8, 14, 10, 19, 12, 23, 16, 9, 18, 25, 13, 21, 10, 17, 24, 12, 20, 15, 9, 18, 13, 22, 11, 16]
|
||||
|
||||
export function EditingTimeline() {
|
||||
return (
|
||||
<div
|
||||
className="hero-enter hero-enter-4 mx-auto mt-10 max-w-4xl overflow-hidden rounded-xl border border-zinc-800 bg-[#08080a] shadow-[0_24px_64px_rgba(0,0,0,0.4)] md:mt-14"
|
||||
aria-label="Illustrated Premiere Pro editing workflow"
|
||||
>
|
||||
<div className="flex h-11 items-center border-b border-zinc-800 bg-[#111114] px-4">
|
||||
<div className="flex gap-1.5" aria-hidden="true">
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-red-500/75" />
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-amber-400/75" />
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-emerald-500/75" />
|
||||
</div>
|
||||
<span className="ml-4 font-mono text-[11px] text-zinc-500">Sequence 01 · Premiere Pro</span>
|
||||
<span className="status-pulse ml-auto inline-flex items-center gap-1.5 rounded-full border border-emerald-400/20 bg-emerald-400/8 px-2.5 py-1 text-[10px] font-medium text-emerald-300">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-emerald-400" />
|
||||
MCP connected
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-[0.72fr_1.28fr]">
|
||||
<div className="relative min-h-44 overflow-hidden bg-[#050506] p-4 md:min-h-72 md:border-r md:p-5">
|
||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_60%_28%,rgba(139,124,255,0.12),transparent_43%)]" />
|
||||
<div className="relative flex h-full flex-col">
|
||||
<div className="flex items-center justify-between font-mono text-[11px] uppercase tracking-[0.16em] text-zinc-500">
|
||||
<span>Program</span>
|
||||
<span>00:00:08:12</span>
|
||||
</div>
|
||||
|
||||
<div className="my-auto py-4 md:py-6">
|
||||
<div className="timeline-copy-enter mx-auto max-w-[15rem]">
|
||||
<p className="text-balance text-center text-xl font-semibold leading-tight tracking-[-0.03em] text-white md:text-2xl">
|
||||
Keep the creative call.
|
||||
<span className="block text-violet-200">Automate the repeatable work.</span>
|
||||
</p>
|
||||
<div className="mx-auto mt-5 h-px w-16 bg-violet-300/60" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="hidden items-center justify-center gap-4 text-zinc-500 md:flex" aria-hidden="true">
|
||||
<span className="font-mono text-[10px]">1/2</span>
|
||||
<span className="grid h-7 w-7 place-items-center rounded-full bg-zinc-800 text-zinc-200">
|
||||
<Play className="ml-0.5 h-3 w-3 fill-current" />
|
||||
</span>
|
||||
<span className="font-mono text-[10px]">Fit</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="hidden min-w-0 bg-[#0b0b0e] md:block" aria-hidden="true">
|
||||
<div className="flex h-10 items-center justify-between border-b border-zinc-800 px-3">
|
||||
<div className="flex items-center gap-2 text-[10px] text-zinc-500">
|
||||
<Layers3 className="h-3.5 w-3.5 text-violet-300" />
|
||||
<span className="font-medium text-zinc-300">Timeline</span>
|
||||
<span>1080p · 23.976 fps</span>
|
||||
</div>
|
||||
<span className="timeline-copy-enter inline-flex items-center gap-1 rounded bg-violet-300/10 px-2 py-1 text-[9px] text-violet-100" style={{ animationDelay: "750ms" }}>
|
||||
<Sparkles className="h-3 w-3" />
|
||||
B-roll matched
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="relative p-3 pl-12">
|
||||
<div className="absolute inset-y-3 left-0 w-10 border-r border-zinc-800 bg-[#0d0d10]">
|
||||
{["V2", "V1", "A1"].map((track) => (
|
||||
<div key={track} className="flex h-12 items-center justify-center border-b border-zinc-800 font-mono text-[9px] text-zinc-600">
|
||||
{track}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="relative overflow-hidden">
|
||||
<div className="mb-1 flex h-4 justify-between border-b border-zinc-800 font-mono text-[8px] text-zinc-700">
|
||||
<span>00:00</span>
|
||||
<span>00:05</span>
|
||||
<span>00:10</span>
|
||||
<span>00:15</span>
|
||||
</div>
|
||||
|
||||
<div className="relative h-12 border-b border-zinc-800/80">
|
||||
{brollClips.map((clip) => (
|
||||
<div
|
||||
key={clip.label}
|
||||
className="timeline-clip-enter absolute top-1 flex h-9 origin-left items-center overflow-hidden rounded-sm border border-pink-300/20 bg-[#874c78] px-2 text-[9px] text-pink-100"
|
||||
style={{ left: clip.start, width: clip.width, animationDelay: clip.delay }}
|
||||
>
|
||||
<Captions className="mr-1.5 h-3 w-3 shrink-0 opacity-60" />
|
||||
<span className="truncate">{clip.label}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="relative h-12 border-b border-zinc-800/80">
|
||||
{clips.map((clip) => (
|
||||
<div
|
||||
key={clip.label}
|
||||
className={`timeline-clip-enter absolute top-1 flex h-9 origin-left items-center overflow-hidden rounded-sm border border-white/10 px-2 text-[9px] text-violet-100 ${clip.color}`}
|
||||
style={{ left: clip.start, width: clip.width, animationDelay: clip.delay }}
|
||||
>
|
||||
<Sparkles className="mr-1.5 h-3 w-3 shrink-0 opacity-60" />
|
||||
<span className="truncate">{clip.label}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="relative flex h-12 items-center gap-[3px] overflow-hidden border-b border-zinc-800/80 bg-emerald-500/[0.03] px-1">
|
||||
{waveform.map((height, index) => (
|
||||
<span
|
||||
key={`${height}-${index}`}
|
||||
className="timeline-waveform-bar min-w-[2px] flex-1 rounded-full bg-emerald-400/45"
|
||||
style={{ height, animationDelay: `${index * 25}ms`, animationDuration: `${1.2 + (index % 4) * 0.16}s` }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="timeline-playhead pointer-events-none absolute bottom-0 top-3 z-20 w-px bg-[#f2a7d2] shadow-[0_0_10px_rgba(242,167,210,0.65)]" style={{ left: "4%" }}>
|
||||
<span className="absolute -left-[3px] -top-1 h-0 w-0 border-l-[3px] border-r-[3px] border-t-[5px] border-l-transparent border-r-transparent border-t-[#f2a7d2]" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="timeline-copy-enter flex items-center justify-between border-t border-zinc-800 bg-[#0f0f12] px-4 py-2.5 text-[10px]" style={{ animationDelay: "900ms" }}>
|
||||
<span className="inline-flex items-center gap-1.5 text-zinc-500">
|
||||
<Check className="h-3 w-3 text-emerald-400" />
|
||||
3 edits applied and verified
|
||||
</span>
|
||||
<span className="font-mono text-zinc-600">ProRes 422</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import { ArrowUpRight } from "lucide-react"
|
||||
import { product } from "@/lib/product"
|
||||
|
||||
export const faqItems = [
|
||||
{
|
||||
question: "What is MCP for Adobe Premiere Pro?",
|
||||
answer:
|
||||
"MCP for Adobe Premiere Pro is an open-source Model Context Protocol server that gives compatible AI clients a structured set of tools for editing timelines, applying effects, managing media, and exporting from Adobe Premiere Pro.",
|
||||
},
|
||||
{
|
||||
question: "Which Premiere Pro versions and operating systems are supported?",
|
||||
answer:
|
||||
`The signed CEP connector is the default route for Adobe Premiere Pro ${product.premiereCompatibility} on macOS and Windows, including Apple Silicon and Intel Macs. The UXP bridge adds capability-gated workflows on compatible Premiere ${product.uxpMinimumVersion}+ hosts; it is not the default installer.`,
|
||||
},
|
||||
{
|
||||
question: "Does MCP for Adobe Premiere Pro upload my footage?",
|
||||
answer:
|
||||
"The recommended setup is local-first. Premiere Pro, the connector, and the MCP server run on your machine, and the bridge exchanges commands and structured results rather than automatically uploading project media. Your AI assistant’s separate privacy settings still apply.",
|
||||
},
|
||||
{
|
||||
question: "Which AI clients can connect to it?",
|
||||
answer:
|
||||
"Claude Desktop has a released self-contained bundle and is the recommended starting point. Cursor, VS Code / Copilot, Windsurf, and other MCP-compatible clients can use the local server route. A native one-click installer for every client is not currently shipped.",
|
||||
},
|
||||
{
|
||||
question: "Can I use the MCP server remotely?",
|
||||
answer:
|
||||
"A remote HTTP transport is available, but it requires authentication and a working connection back to the local Premiere Pro bridge. For most editors, the local setup is simpler and safer.",
|
||||
},
|
||||
]
|
||||
|
||||
export function FaqSection() {
|
||||
return (
|
||||
<section id="faq" className="reveal-section bg-black px-5 py-24 md:py-32">
|
||||
<div className="mx-auto grid max-w-6xl gap-14 lg:grid-cols-[0.7fr_1.3fr] lg:gap-20">
|
||||
<div>
|
||||
<h2 className="text-balance text-3xl font-bold tracking-tight text-white md:text-5xl">
|
||||
MCP for Adobe Premiere Pro <span className="text-purple-400">FAQ</span>
|
||||
</h2>
|
||||
<p className="mt-5 max-w-md text-base leading-7 text-zinc-400">
|
||||
Straight answers about compatibility, privacy, AI clients, and remote access.
|
||||
</p>
|
||||
<a
|
||||
href="https://github.com/leancoderkavy/premiere-pro-mcp#readme"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="mt-7 inline-flex items-center gap-2 text-sm font-semibold text-purple-300 transition-colors hover:text-purple-200"
|
||||
>
|
||||
Read the complete documentation <ArrowUpRight className="h-4 w-4" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="divide-y divide-zinc-800 border-y border-zinc-800">
|
||||
{faqItems.map((item) => (
|
||||
<details key={item.question} className="faq-item group py-6">
|
||||
<summary className="flex cursor-pointer list-none items-start justify-between gap-6 text-base font-semibold text-zinc-100 marker:content-none">
|
||||
{item.question}
|
||||
<span className="mt-0.5 text-xl font-light leading-none text-purple-300 transition-transform duration-300 group-open:rotate-45" aria-hidden="true">
|
||||
+
|
||||
</span>
|
||||
</summary>
|
||||
<p className="max-w-2xl pt-4 text-sm leading-7 text-zinc-400">{item.answer}</p>
|
||||
</details>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import { Code2, FolderOpen, KeyRound, Scissors, SlidersHorizontal, Upload } from "lucide-react"
|
||||
|
||||
const capabilities = [
|
||||
{
|
||||
icon: Scissors,
|
||||
title: "Edit timelines with intent",
|
||||
description: "Insert, overwrite, trim, split, move, ripple-delete, roll, slide, and slip across sequences and tracks.",
|
||||
},
|
||||
{
|
||||
icon: SlidersHorizontal,
|
||||
title: "Apply repeatable finishing work",
|
||||
description: "Apply effects, adjust Lumetri parameters, load LUTs, stabilize clips, and automate repetitive grading steps.",
|
||||
},
|
||||
{
|
||||
icon: KeyRound,
|
||||
title: "Control keyframes and motion",
|
||||
description: "Add, update, and inspect keyframes with interpolation controls for repeatable animation work.",
|
||||
},
|
||||
{
|
||||
icon: FolderOpen,
|
||||
title: "Organize project structure",
|
||||
description: "Import footage, manage bins, create sequences from presets, inspect metadata, and work with proxies.",
|
||||
},
|
||||
{
|
||||
icon: Upload,
|
||||
title: "Prepare exports with explicit settings",
|
||||
description: "Queue sequences and project items through Adobe Media Encoder using the presets you choose.",
|
||||
},
|
||||
{
|
||||
icon: Code2,
|
||||
title: "Use documented extension seams",
|
||||
description: "Use the structured MCP surface or run custom ExtendScript and QE DOM workflows when you need deeper control.",
|
||||
},
|
||||
]
|
||||
|
||||
export function FeaturesSection() {
|
||||
return (
|
||||
<section id="features" className="reveal-section border-y border-zinc-900 bg-[#050506] px-5 py-24 md:py-32">
|
||||
<div className="mx-auto max-w-6xl">
|
||||
<div className="max-w-2xl">
|
||||
<h2 className="text-balance text-3xl font-bold tracking-tight text-white md:text-5xl">
|
||||
A narrower interface for <span className="text-violet-300">predictable edit work.</span>
|
||||
</h2>
|
||||
<p className="mt-5 text-lg leading-8 text-zinc-400">
|
||||
Give an MCP-compatible client structured operations instead of asking it to infer state from Premiere's interface.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-16 grid gap-x-8 gap-y-12 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{capabilities.map((capability) => (
|
||||
<article key={capability.title} className="group border-t border-zinc-800 pt-6">
|
||||
<capability.icon className="h-6 w-6 text-violet-300 transition-transform duration-200 group-hover:-translate-y-0.5 motion-reduce:transform-none" strokeWidth={1.6} />
|
||||
<h3 className="mt-6 text-lg font-semibold text-zinc-100">{capability.title}</h3>
|
||||
<p className="mt-3 text-sm leading-7 text-zinc-400">{capability.description}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { ArrowRight, Github, ShieldCheck } from "lucide-react"
|
||||
import { TrackedLink } from "@/components/ui/tracked-link"
|
||||
import { product } from "@/lib/product"
|
||||
|
||||
export function FinalCtaSection() {
|
||||
return (
|
||||
<section className="reveal-section border-t border-zinc-900 bg-[#050506] px-5 py-20 md:py-28">
|
||||
<div className="mx-auto max-w-6xl">
|
||||
<div className="grid items-end gap-10 border-b border-zinc-800 pb-12 lg:grid-cols-[1fr_auto]">
|
||||
<div className="max-w-3xl">
|
||||
<p className="font-mono text-xs font-semibold uppercase tracking-[0.18em] text-violet-200">
|
||||
Free · open source · local-first
|
||||
</p>
|
||||
<h2 className="mt-4 text-balance text-4xl font-bold tracking-[-0.04em] text-white md:text-6xl">
|
||||
Start with a connection you can verify.
|
||||
</h2>
|
||||
<p className="mt-5 max-w-2xl text-lg leading-8 text-zinc-400">
|
||||
Connect your assistant, verify the local bridge without making changes, then preview the first edit before you apply it.
|
||||
</p>
|
||||
</div>
|
||||
<TrackedLink
|
||||
href="#install"
|
||||
trackingLocation="final_cta"
|
||||
trackingDestination="safe_connection_check"
|
||||
className="inline-flex min-h-12 items-center justify-center gap-2 rounded-md bg-violet-200 px-6 text-sm font-semibold text-black transition-colors hover:bg-white"
|
||||
>
|
||||
Choose your assistant
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</TrackedLink>
|
||||
</div>
|
||||
<div className="flex flex-col gap-3 pt-6 text-sm text-zinc-500 sm:flex-row sm:items-center sm:gap-8">
|
||||
<span className="inline-flex items-center gap-2">
|
||||
<ShieldCheck className="h-4 w-4 text-violet-200" />
|
||||
Your media stays local
|
||||
</span>
|
||||
<a
|
||||
href="https://github.com/leancoderkavy/premiere-pro-mcp"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-2 transition-colors hover:text-white"
|
||||
>
|
||||
<Github className="h-4 w-4" />
|
||||
MIT licensed on GitHub
|
||||
</a>
|
||||
<span>Premiere Pro {product.premiereCompatibility} · macOS and Windows</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { Github, Package } from "lucide-react"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
<footer className="bg-black px-5 py-12">
|
||||
<div className="mx-auto max-w-6xl">
|
||||
<div className="grid gap-10 border-b border-zinc-900 pb-10 md:grid-cols-[1fr_auto_auto] md:gap-16">
|
||||
<div className="max-w-sm">
|
||||
<div className="flex items-center gap-3">
|
||||
<Image
|
||||
src="/marketing/premiere-pro-mcp-mark-v1.png"
|
||||
alt=""
|
||||
width={32}
|
||||
height={32}
|
||||
className="h-8 w-8 object-contain"
|
||||
/>
|
||||
<span className="text-sm font-semibold text-white">premiere-pro-mcp</span>
|
||||
</div>
|
||||
<p className="mt-4 text-sm leading-6 text-zinc-500">Open-source, local-first structured AI control for supported Adobe Premiere Pro workflows.</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs font-semibold uppercase tracking-[0.16em] text-zinc-600">Product</p>
|
||||
<div className="mt-4 flex flex-col gap-3 text-sm text-zinc-400">
|
||||
<Link href="/#demo" className="hover:text-white">Demo</Link>
|
||||
<Link href="/#features" className="hover:text-white">Features</Link>
|
||||
<Link href="/#how-it-works" className="hover:text-white">How it works</Link>
|
||||
<Link href="/#install" className="hover:text-white">Install</Link>
|
||||
<Link href="/#faq" className="hover:text-white">FAQ</Link>
|
||||
<Link href="/premiere-pro-collaboration-workflow/" className="hover:text-white">Workflow fit guide</Link>
|
||||
<Link href="/project-intake/" className="hover:text-white">Project Intake</Link>
|
||||
<Link href="/facts/" className="hover:text-white">Canonical facts</Link>
|
||||
<Link href="/blog/" className="hover:text-white">Guides</Link>
|
||||
<a href="/docs/" className="hover:text-white">Documentation</a>
|
||||
<a href="/changelog/" className="hover:text-white">Changelog</a>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs font-semibold uppercase tracking-[0.16em] text-zinc-600">Resources</p>
|
||||
<div className="mt-4 flex flex-col gap-3 text-sm text-zinc-400">
|
||||
<a href="https://github.com/leancoderkavy/premiere-pro-mcp" target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-2 hover:text-white"><Github className="h-4 w-4" /> GitHub</a>
|
||||
<a href="https://www.npmjs.com/package/premiere-pro-mcp" target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-2 hover:text-white"><Package className="h-4 w-4" /> npm package</a>
|
||||
<a href="https://github.com/leancoderkavy/premiere-pro-mcp/blob/main/SECURITY.md" target="_blank" rel="noopener noreferrer" className="hover:text-white">Security</a>
|
||||
<a href="/privacy/" className="hover:text-white">Privacy</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2 pt-6 text-xs text-zinc-600 sm:flex-row sm:items-center sm:justify-between">
|
||||
<p>© 2026 premiere-pro-mcp contributors. MIT licensed.</p>
|
||||
<p>Not affiliated with Adobe Inc. Adobe Premiere Pro is a trademark of Adobe Inc.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
import { Github, Monitor, Package, ShieldCheck } from "lucide-react"
|
||||
import Image from "next/image"
|
||||
import { MobileNav } from "@/components/sections/mobile-nav"
|
||||
import { WorkflowProof } from "@/components/sections/workflow-proof"
|
||||
import { TrackedLink } from "@/components/ui/tracked-link"
|
||||
import { product } from "@/lib/product"
|
||||
|
||||
const navItems = [
|
||||
{ label: "Demo", href: "#demo" },
|
||||
{ label: "Features", href: "#features" },
|
||||
{ label: "How it works", href: "#how-it-works" },
|
||||
{ label: "Project Intake", href: "/project-intake/" },
|
||||
{ label: "Install", href: "#install" },
|
||||
{ label: "FAQ", href: "#faq" },
|
||||
{ label: "Guides", href: "/blog/" },
|
||||
{ label: "Docs", href: "/docs/" },
|
||||
{ label: "Changelog", href: "/changelog/" },
|
||||
]
|
||||
|
||||
const proofItems = [
|
||||
{ icon: Package, title: `v${product.version}`, detail: "Current release" },
|
||||
{ icon: Monitor, title: "macOS + Windows", detail: "Supported desktop hosts" },
|
||||
{ icon: ShieldCheck, title: "Local-first", detail: "Media stays on your machine" },
|
||||
{ icon: Github, title: "MIT licensed", detail: "Source available on GitHub" },
|
||||
]
|
||||
|
||||
export function HeroSection() {
|
||||
return (
|
||||
<>
|
||||
<header className="fixed inset-x-0 top-0 z-50 border-b border-white/10 bg-black/95">
|
||||
<nav className="mx-auto flex h-16 max-w-6xl items-center justify-between px-4 sm:px-5" aria-label="Primary navigation">
|
||||
<a href="#top" className="flex items-center gap-3 text-sm font-semibold text-white">
|
||||
<Image
|
||||
src="/marketing/premiere-pro-mcp-mark-v1.png"
|
||||
alt=""
|
||||
width={32}
|
||||
height={32}
|
||||
className="h-8 w-8 object-contain"
|
||||
priority
|
||||
/>
|
||||
<span>premiere-pro-mcp</span>
|
||||
</a>
|
||||
<div className="flex items-center gap-5">
|
||||
<div className="hidden items-center gap-5 lg:flex">
|
||||
{navItems.map((item) => (
|
||||
<a key={item.href} href={item.href} className="text-sm text-zinc-400 transition-colors hover:text-white">
|
||||
{item.label}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
<MobileNav />
|
||||
<TrackedLink
|
||||
href="https://github.com/leancoderkavy/premiere-pro-mcp"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
trackingLocation="navigation"
|
||||
trackingDestination="github"
|
||||
aria-label="premiere-pro-mcp on GitHub"
|
||||
className="inline-flex min-h-11 items-center gap-2 rounded-md border border-zinc-700 px-3 py-2 text-sm font-medium text-zinc-200 transition-colors hover:border-zinc-500 hover:bg-zinc-900"
|
||||
>
|
||||
<Github className="h-4 w-4" />
|
||||
<span className="hidden sm:inline">GitHub</span>
|
||||
</TrackedLink>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<section id="top" className="relative overflow-hidden px-4 pb-16 pt-28 sm:px-5 md:pb-28 md:pt-40">
|
||||
<div className="hero-grid absolute inset-0" aria-hidden="true" />
|
||||
<div className="hero-glow absolute left-1/2 top-0 h-[30rem] w-full max-w-[52rem] -translate-x-1/2" aria-hidden="true" />
|
||||
<div className="hero-timeline absolute inset-x-0 top-24 mx-auto hidden max-w-5xl md:block" aria-hidden="true">
|
||||
<span className="timeline-rule timeline-rule-one" />
|
||||
<span className="timeline-rule timeline-rule-two" />
|
||||
<span className="timeline-clip timeline-clip-one" />
|
||||
<span className="timeline-clip timeline-clip-two" />
|
||||
<span className="timeline-clip timeline-clip-three" />
|
||||
</div>
|
||||
|
||||
<div className="relative mx-auto max-w-6xl">
|
||||
<div className="mx-auto max-w-4xl text-center">
|
||||
<p className="hero-enter hero-enter-1 mb-5 font-mono text-xs font-semibold uppercase tracking-[0.18em] text-violet-200">
|
||||
Open source · local bridge · explicit confirmation
|
||||
</p>
|
||||
<h1 className="hero-enter hero-enter-1 text-balance text-4xl font-bold leading-[1.02] tracking-[-0.045em] text-white sm:text-6xl md:text-7xl">
|
||||
MCP for Adobe Premiere Pro: make Premiere changes you can <span className="accent-text">inspect before you apply.</span>
|
||||
</h1>
|
||||
<p className="hero-enter hero-enter-2 mx-auto mt-7 max-w-2xl text-balance text-lg leading-8 text-zinc-400 md:text-xl">
|
||||
Connect the MCP-compatible client you already use to a local Premiere bridge. Review the target and plan first, then confirm supported work with current project state.
|
||||
</p>
|
||||
<div className="hero-enter hero-enter-3 mt-9 flex flex-col items-center justify-center gap-3 sm:flex-row">
|
||||
<TrackedLink
|
||||
href="#install"
|
||||
trackingLocation="hero"
|
||||
trackingDestination="safe_connection_check"
|
||||
className="inline-flex min-h-12 items-center justify-center gap-2 rounded-md bg-violet-200 px-6 text-sm font-semibold text-black transition-colors hover:bg-white"
|
||||
>
|
||||
<Package className="h-4 w-4" /> Verify your connection
|
||||
</TrackedLink>
|
||||
<TrackedLink
|
||||
href="/project-intake/"
|
||||
trackingLocation="hero"
|
||||
trackingDestination="project_intake_workflow"
|
||||
className="inline-flex min-h-12 items-center justify-center gap-2 rounded-md border border-zinc-700 bg-zinc-950/80 px-6 text-sm font-semibold text-zinc-100 transition-colors hover:border-zinc-500 hover:bg-zinc-900"
|
||||
>
|
||||
<ShieldCheck className="h-4 w-4" /> See Project Intake
|
||||
</TrackedLink>
|
||||
</div>
|
||||
<p className="hero-enter hero-enter-3 mt-4 text-sm text-zinc-500">
|
||||
Project context is opt-in and local. Applied plans require current targets and confirmation.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="hero-enter hero-enter-4">
|
||||
<WorkflowProof />
|
||||
</div>
|
||||
|
||||
<div className="hero-enter hero-enter-5 mt-6 flex snap-x overflow-x-auto rounded-xl border border-zinc-800 bg-zinc-950/75 sm:mt-8 sm:grid sm:grid-cols-2 sm:overflow-hidden lg:grid-cols-4">
|
||||
{proofItems.map((item) => (
|
||||
<div key={item.title} className="flex min-w-[13rem] snap-start items-center gap-3 border-r border-zinc-800 px-5 py-4 last:border-r-0 sm:min-w-0 sm:border-b sm:even:border-l lg:border-b-0 lg:border-l first:lg:border-l-0">
|
||||
<item.icon className="h-5 w-5 shrink-0 text-purple-400" strokeWidth={1.7} />
|
||||
<div>
|
||||
<p className="text-sm font-semibold text-zinc-100">{item.title}</p>
|
||||
<p className="mt-0.5 text-xs text-zinc-500">{item.detail}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import { BorderBeam } from "@/components/ui/border-beam"
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
label: "Local (stdio)",
|
||||
steps: [
|
||||
{ cmd: "npm install -g premiere-pro-mcp", comment: "# Install globally" },
|
||||
{ cmd: "premiere-pro-mcp --install-cep", comment: "# Install the CEP panel into Premiere" },
|
||||
],
|
||||
config: `{
|
||||
"mcpServers": {
|
||||
"premiere-pro": {
|
||||
"command": "premiere-pro-mcp"
|
||||
}
|
||||
}
|
||||
}`,
|
||||
note: "Works with Claude Desktop, Windsurf, Cursor, and any MCP client that supports stdio.",
|
||||
},
|
||||
{
|
||||
label: "Remote (Fly.io)",
|
||||
steps: [
|
||||
{ cmd: "npm install -g mcp-remote", comment: "# Install mcp-remote proxy" },
|
||||
],
|
||||
config: `{
|
||||
"mcpServers": {
|
||||
"premiere-pro": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"mcp-remote",
|
||||
"https://premiere-pro-mcp.fly.dev/mcp"
|
||||
]
|
||||
}
|
||||
}
|
||||
}`,
|
||||
note: "Note: the file bridge still requires the CEP plugin on the same machine or a shared volume.",
|
||||
},
|
||||
]
|
||||
|
||||
function CodeBlock({ code, label }: { code: string; label?: string }) {
|
||||
return (
|
||||
<div className="relative overflow-hidden rounded-lg border border-zinc-800 bg-zinc-950">
|
||||
<BorderBeam colorFrom="#9999ff" colorTo="#ff6699" duration={10} size={60} />
|
||||
{label && (
|
||||
<div className="border-b border-zinc-800 px-4 py-2">
|
||||
<span className="text-xs text-zinc-500">{label}</span>
|
||||
</div>
|
||||
)}
|
||||
<pre className="overflow-x-auto p-4 text-sm leading-relaxed text-zinc-300">
|
||||
<code>{code}</code>
|
||||
</pre>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function InstallSection() {
|
||||
return (
|
||||
<section className="bg-black px-4 py-24">
|
||||
<div className="mx-auto max-w-5xl">
|
||||
<div className="mb-16 text-center">
|
||||
<p className="text-sm font-semibold uppercase tracking-widest text-zinc-500">Get started</p>
|
||||
<h2 className="mt-2 text-3xl font-bold text-white md:text-4xl">Two ways to connect</h2>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-8 md:grid-cols-2">
|
||||
{tabs.map((tab) => (
|
||||
<div key={tab.label} className="space-y-4">
|
||||
<h3 className="text-xl font-semibold text-white">{tab.label}</h3>
|
||||
|
||||
<div className="space-y-2">
|
||||
{tab.steps.map((s) => (
|
||||
<div key={s.cmd} className="overflow-hidden rounded-lg border border-zinc-800 bg-zinc-950 px-4 py-3 font-mono text-sm">
|
||||
<span className="text-zinc-600">{s.comment}{"\n"}</span>
|
||||
<span className="text-green-400">$ {s.cmd}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<CodeBlock code={tab.config} label="mcp config" />
|
||||
|
||||
<p className="text-sm text-zinc-500">{tab.note}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* npm badge row */}
|
||||
<div className="mt-16 flex flex-wrap items-center justify-center gap-4">
|
||||
{[
|
||||
{ label: "npm", href: "https://www.npmjs.com/package/premiere-pro-mcp", badge: "latest" },
|
||||
{ label: "GitHub", href: "https://github.com/leancoderkavy/premiere-pro-mcp", badge: "MIT" },
|
||||
{ label: "MCP", href: "https://modelcontextprotocol.io", badge: "1.27" },
|
||||
{ label: "Node.js", href: "https://nodejs.org", badge: "20.19+" },
|
||||
].map((b) => (
|
||||
<a
|
||||
key={b.label}
|
||||
href={b.href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-0 overflow-hidden rounded text-xs font-semibold"
|
||||
>
|
||||
<span className="bg-zinc-700 px-2 py-1 text-zinc-300">{b.label}</span>
|
||||
<span className="bg-purple-700 px-2 py-1 text-white">{b.badge}</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
"use client"
|
||||
|
||||
import { Menu, X } from "lucide-react"
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
const mobileLinks = [
|
||||
{ label: "Demo", href: "#demo" },
|
||||
{ label: "Features", href: "#features" },
|
||||
{ label: "How it works", href: "#how-it-works" },
|
||||
{ label: "Project Intake", href: "/project-intake/" },
|
||||
{ label: "Install", href: "#install" },
|
||||
{ label: "FAQ", href: "#faq" },
|
||||
{ label: "Guides", href: "/blog/" },
|
||||
{ label: "Docs", href: "/docs/" },
|
||||
{ label: "Changelog", href: "/changelog/" },
|
||||
] as const
|
||||
|
||||
export function MobileNav() {
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return
|
||||
|
||||
function closeOnEscape(event: KeyboardEvent) {
|
||||
if (event.key === "Escape") setOpen(false)
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", closeOnEscape)
|
||||
return () => window.removeEventListener("keydown", closeOnEscape)
|
||||
}, [open])
|
||||
|
||||
return (
|
||||
<div className="relative lg:hidden">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen((current) => !current)}
|
||||
aria-expanded={open}
|
||||
aria-controls="mobile-navigation"
|
||||
aria-label={open ? "Close navigation" : "Open navigation"}
|
||||
className="grid h-10 w-10 place-items-center rounded-md border border-zinc-700 text-zinc-200 transition-colors hover:border-zinc-500 hover:bg-zinc-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-400"
|
||||
>
|
||||
{open ? <X className="h-4 w-4" /> : <Menu className="h-4 w-4" />}
|
||||
</button>
|
||||
<div
|
||||
id="mobile-navigation"
|
||||
aria-hidden={!open}
|
||||
className={`absolute right-0 top-12 w-56 origin-top-right overflow-hidden rounded-lg border border-zinc-800 bg-[#0b0b0e] p-2 shadow-2xl transition-[opacity,transform,visibility] duration-200 ease-out motion-reduce:transition-none ${
|
||||
open ? "visible scale-100 opacity-100" : "invisible scale-[0.98] opacity-0 pointer-events-none"
|
||||
}`}
|
||||
>
|
||||
{mobileLinks.map((item) => (
|
||||
<a
|
||||
key={item.href}
|
||||
href={item.href}
|
||||
onClick={() => setOpen(false)}
|
||||
tabIndex={open ? 0 : -1}
|
||||
className="block min-h-11 rounded-md px-3 py-2.5 text-sm text-zinc-300 transition-colors hover:bg-zinc-900 hover:text-white"
|
||||
>
|
||||
{item.label}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import { Marquee } from "@/components/ui/marquee"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { product } from "@/lib/product"
|
||||
|
||||
const tools = [
|
||||
{ name: "add_to_timeline", category: "Timeline" },
|
||||
{ name: "apply_effect", category: "Effects" },
|
||||
{ name: "color_correct", category: "Color" },
|
||||
{ name: "export_sequence", category: "Export" },
|
||||
{ name: "add_keyframe", category: "Keyframes" },
|
||||
{ name: "create_sequence", category: "Sequence" },
|
||||
{ name: "import_media", category: "Project" },
|
||||
{ name: "ripple_delete", category: "Advanced" },
|
||||
{ name: "roll_edit", category: "Advanced" },
|
||||
{ name: "apply_lut", category: "Color" },
|
||||
{ name: "capture_frame", category: "Export" },
|
||||
{ name: "stabilize_clip", category: "Effects" },
|
||||
{ name: "execute_extendscript", category: "Scripting" },
|
||||
{ name: "get_project_info", category: "Discovery" },
|
||||
{ name: "set_clip_properties", category: "Timeline" },
|
||||
{ name: "auto_reframe_sequence", category: "Sequence" },
|
||||
{ name: "copy_effects_between_clips", category: "Clipboard" },
|
||||
{ name: "set_keyframe_interpolation", category: "Keyframes" },
|
||||
{ name: "get_active_sequence", category: "Discovery" },
|
||||
{ name: "create_caption_track", category: "Captions" },
|
||||
{ name: "export_aaf", category: "Export" },
|
||||
{ name: "split_clip", category: "Timeline" },
|
||||
{ name: "set_workspace", category: "Workspace" },
|
||||
{ name: "get_premiere_state", category: "Inspection" },
|
||||
]
|
||||
|
||||
const categoryColors: Record<string, string> = {
|
||||
Timeline: "text-blue-400 bg-blue-400/10",
|
||||
Effects: "text-purple-400 bg-purple-400/10",
|
||||
Color: "text-pink-400 bg-pink-400/10",
|
||||
Export: "text-green-400 bg-green-400/10",
|
||||
Keyframes: "text-orange-400 bg-orange-400/10",
|
||||
Sequence: "text-cyan-400 bg-cyan-400/10",
|
||||
Project: "text-yellow-400 bg-yellow-400/10",
|
||||
Advanced: "text-red-400 bg-red-400/10",
|
||||
Scripting: "text-teal-400 bg-teal-400/10",
|
||||
Discovery: "text-indigo-400 bg-indigo-400/10",
|
||||
Clipboard: "text-violet-400 bg-violet-400/10",
|
||||
Captions: "text-lime-400 bg-lime-400/10",
|
||||
Workspace: "text-amber-400 bg-amber-400/10",
|
||||
Inspection:"text-sky-400 bg-sky-400/10",
|
||||
}
|
||||
|
||||
function ToolCard({ name, category }: { name: string; category: string }) {
|
||||
const color = categoryColors[category] ?? "text-zinc-400 bg-zinc-400/10"
|
||||
return (
|
||||
<div className="flex items-center gap-3 rounded-lg border border-zinc-800 bg-zinc-950 px-4 py-2.5 shadow-sm">
|
||||
<span className={cn("rounded px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wider", color)}>
|
||||
{category}
|
||||
</span>
|
||||
<code className="text-sm text-zinc-300">{name}</code>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const half = Math.ceil(tools.length / 2)
|
||||
const row1 = tools.slice(0, half)
|
||||
const row2 = tools.slice(half)
|
||||
|
||||
export function ToolsMarquee() {
|
||||
return (
|
||||
<section className="relative overflow-hidden bg-black py-20">
|
||||
<div className="mb-12 text-center">
|
||||
<p className="text-sm font-semibold uppercase tracking-widest text-zinc-500">{product.coreToolCount} core tools across 40 modules</p>
|
||||
<h2 className="mt-2 text-3xl font-bold text-white md:text-4xl">Everything the AI needs to edit</h2>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<Marquee pauseOnHover className="[--duration:35s]">
|
||||
{row1.map((t) => <ToolCard key={t.name} {...t} />)}
|
||||
</Marquee>
|
||||
<Marquee reverse pauseOnHover className="[--duration:40s]">
|
||||
{row2.map((t) => <ToolCard key={t.name} {...t} />)}
|
||||
</Marquee>
|
||||
</div>
|
||||
|
||||
{/* fade edges */}
|
||||
<div className="pointer-events-none absolute inset-y-0 left-0 w-32 bg-gradient-to-r from-black" />
|
||||
<div className="pointer-events-none absolute inset-y-0 right-0 w-32 bg-gradient-to-l from-black" />
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { CheckCircle2, ClipboardCheck, FileSearch, ListChecks, ScanSearch, ShieldCheck } from "lucide-react"
|
||||
|
||||
type WorkflowStep = {
|
||||
id: "capture" | "search" | "plan" | "preview"
|
||||
number: string
|
||||
title: string
|
||||
tool: string
|
||||
summary: string
|
||||
boundary: string
|
||||
details: string[]
|
||||
icon: typeof ScanSearch
|
||||
}
|
||||
|
||||
const steps: WorkflowStep[] = [
|
||||
{
|
||||
id: "capture",
|
||||
number: "01",
|
||||
title: "Capture context",
|
||||
tool: "manage_project_context",
|
||||
summary: "Create a bounded local snapshot of the active sequence and source identities.",
|
||||
boundary: "Read-only · opt-in local index",
|
||||
details: [
|
||||
"No context is captured until an MCP client explicitly calls the tool.",
|
||||
"Native project and media paths are hashed before persistence.",
|
||||
"Capture establishes revisions for later stale-state checks.",
|
||||
],
|
||||
icon: ScanSearch,
|
||||
},
|
||||
{
|
||||
id: "search",
|
||||
number: "02",
|
||||
title: "Find evidence",
|
||||
tool: "search_project_context",
|
||||
summary: "Retrieve only the clips, transcript passages, observations, and placements relevant to the request.",
|
||||
boundary: "Read-only · bounded evidence",
|
||||
details: [
|
||||
"Search returns stable Premiere identities and revision provenance.",
|
||||
"The client can limit context to the kinds needed for one editing intent.",
|
||||
"A stale or ambiguous state calls for a fresh capture, not a blind edit.",
|
||||
],
|
||||
icon: FileSearch,
|
||||
},
|
||||
{
|
||||
id: "plan",
|
||||
number: "03",
|
||||
title: "Build the plan",
|
||||
tool: "create_context_edit_plan",
|
||||
summary: "Produce an evidence-backed, non-mutating candidate scaffold before constructing timeline operations.",
|
||||
boundary: "Non-mutating · editorial review required",
|
||||
details: [
|
||||
"Candidates include source/time evidence and stale-state guards.",
|
||||
"The plan is not proof that an editorial decision is correct.",
|
||||
"The editor and chosen AI client can refine the plan before any mutation.",
|
||||
],
|
||||
icon: ListChecks,
|
||||
},
|
||||
{
|
||||
id: "preview",
|
||||
number: "04",
|
||||
title: "Preview, approve, verify",
|
||||
tool: "preview_edit_plan → apply_edit_plan",
|
||||
summary: "Preview the compound edit, then apply only with the exact confirmation token and current targets.",
|
||||
boundary: "Explicit confirmation · post-state verification",
|
||||
details: [
|
||||
"Every target is revalidated before an edit is attempted.",
|
||||
"The preview confirmation token prevents applying a different plan by mistake.",
|
||||
"Returned state or diagnostics are evidence; an attempted command is not enough.",
|
||||
],
|
||||
icon: ClipboardCheck,
|
||||
},
|
||||
]
|
||||
|
||||
export function WorkflowProof() {
|
||||
const [selectedId, setSelectedId] = useState<WorkflowStep["id"]>("capture")
|
||||
const selected = steps.find((step) => step.id === selectedId) ?? steps[0]
|
||||
const SelectedIcon = selected.icon
|
||||
|
||||
return (
|
||||
<section
|
||||
className="relative mx-auto mt-12 max-w-6xl border border-zinc-800 bg-[#08080a] p-5 shadow-[0_28px_90px_rgba(0,0,0,0.45)] sm:mt-16 sm:p-7 lg:p-8"
|
||||
aria-labelledby="project-context-heading"
|
||||
>
|
||||
<div className="flex flex-col gap-5 border-b border-zinc-800 pb-6 lg:flex-row lg:items-end lg:justify-between">
|
||||
<div>
|
||||
<p className="font-mono text-xs font-semibold uppercase tracking-[0.16em] text-purple-300">Illustrated product workflow</p>
|
||||
<h2 id="project-context-heading" className="mt-3 text-2xl font-semibold tracking-tight text-white sm:text-3xl">
|
||||
Keep the context. Review the change.
|
||||
</h2>
|
||||
</div>
|
||||
<p className="max-w-xl text-sm leading-6 text-zinc-400">
|
||||
A local project-context workflow makes the request inspectable from first evidence to returned result. This maps real MCP tools; it is not a recording of a live Premiere session.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 grid gap-6 lg:grid-cols-[14rem_minmax(0,1fr)]">
|
||||
<ol className="grid gap-2 sm:grid-cols-2 lg:grid-cols-1" aria-label="Project context workflow steps">
|
||||
{steps.map((step) => {
|
||||
const Icon = step.icon
|
||||
const active = step.id === selected.id
|
||||
|
||||
return (
|
||||
<li key={step.id}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSelectedId(step.id)}
|
||||
aria-pressed={active}
|
||||
aria-controls="workflow-step-detail"
|
||||
className={`flex min-h-20 w-full items-center gap-3 border px-3 py-3 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-300 focus-visible:ring-offset-2 focus-visible:ring-offset-[#08080a] ${
|
||||
active ? "border-purple-400/70 bg-purple-400/[0.09]" : "border-zinc-800 bg-black hover:border-zinc-600"
|
||||
}`}
|
||||
>
|
||||
<span className={`font-mono text-xs ${active ? "text-purple-200" : "text-zinc-500"}`}>{step.number}</span>
|
||||
<Icon className={`h-4 w-4 shrink-0 ${active ? "text-purple-200" : "text-zinc-500"}`} aria-hidden="true" />
|
||||
<span>
|
||||
<span className="block text-sm font-semibold text-zinc-100">{step.title}</span>
|
||||
<span className="mt-1 block font-mono text-[0.65rem] text-zinc-500">{step.tool}</span>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ol>
|
||||
|
||||
<article id="workflow-step-detail" aria-live="polite" className="border border-zinc-800 bg-black p-5 sm:p-7">
|
||||
<div className="flex flex-col gap-5 border-b border-zinc-800 pb-5 sm:flex-row sm:items-start sm:justify-between">
|
||||
<div className="flex items-start gap-3">
|
||||
<span className="grid h-10 w-10 shrink-0 place-items-center border border-purple-400/50 bg-purple-400/[0.08] text-purple-200">
|
||||
<SelectedIcon className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<div>
|
||||
<p className="font-mono text-xs uppercase tracking-[0.14em] text-purple-300">{selected.tool}</p>
|
||||
<h3 className="mt-2 text-xl font-semibold text-white">{selected.title}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<p className="inline-flex w-fit items-center gap-2 border border-emerald-400/30 bg-emerald-400/[0.06] px-3 py-2 text-xs font-medium text-emerald-200">
|
||||
<ShieldCheck className="h-4 w-4" aria-hidden="true" /> {selected.boundary}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="mt-6 max-w-2xl text-base leading-7 text-zinc-300">{selected.summary}</p>
|
||||
<ul className="mt-6 space-y-3 border-t border-zinc-900 pt-5 text-sm leading-6 text-zinc-400">
|
||||
{selected.details.map((detail) => (
|
||||
<li key={detail} className="flex gap-3">
|
||||
<CheckCircle2 className="mt-0.5 h-4 w-4 shrink-0 text-emerald-300" aria-hidden="true" />
|
||||
<span>{detail}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { ComponentPropsWithoutRef } from "react"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
export function AnimatedGradientText({
|
||||
children,
|
||||
className,
|
||||
...props
|
||||
}: ComponentPropsWithoutRef<"div">) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"group relative mx-auto flex max-w-fit flex-row items-center justify-center rounded-2xl bg-white/40 px-4 py-1.5 text-sm font-medium shadow-[inset_0_-8px_10px_#8fdfff1f] backdrop-blur-sm transition-shadow duration-500 ease-out [--bg-size:300%] hover:shadow-[inset_0_-5px_10px_#8fdfff3f] dark:bg-black/40",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<span
|
||||
className={cn(
|
||||
"inline animate-[gradient_8s_linear_infinite] bg-gradient-to-r from-[#ffaa40] via-[#9c40ff] to-[#ffaa40] bg-[length:var(--bg-size)_100%] bg-clip-text text-transparent"
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import type { CSSProperties } from "react"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
interface BorderBeamProps {
|
||||
size?: number
|
||||
duration?: number
|
||||
delay?: number
|
||||
colorFrom?: string
|
||||
colorTo?: string
|
||||
className?: string
|
||||
style?: CSSProperties
|
||||
reverse?: boolean
|
||||
initialOffset?: number
|
||||
borderWidth?: number
|
||||
}
|
||||
|
||||
export function BorderBeam({
|
||||
className,
|
||||
size = 50,
|
||||
delay = 0,
|
||||
duration = 6,
|
||||
colorFrom = "#ffaa40",
|
||||
colorTo = "#9c40ff",
|
||||
style,
|
||||
reverse = false,
|
||||
initialOffset = 0,
|
||||
borderWidth = 1,
|
||||
}: BorderBeamProps) {
|
||||
return (
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className={cn("border-beam", reverse && "border-beam-reverse", className)}
|
||||
style={{
|
||||
"--border-beam-size": `${size}px`,
|
||||
"--border-beam-duration": `${duration}s`,
|
||||
"--border-beam-delay": `${-delay - (duration * initialOffset) / 100}s`,
|
||||
"--border-beam-from": colorFrom,
|
||||
"--border-beam-to": colorTo,
|
||||
"--border-beam-width": `${borderWidth}px`,
|
||||
...style,
|
||||
} as CSSProperties}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { ComponentPropsWithoutRef } from "react"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
interface MarqueeProps extends ComponentPropsWithoutRef<"div"> {
|
||||
className?: string
|
||||
reverse?: boolean
|
||||
pauseOnHover?: boolean
|
||||
children: React.ReactNode
|
||||
vertical?: boolean
|
||||
repeat?: number
|
||||
}
|
||||
|
||||
export function Marquee({
|
||||
className,
|
||||
reverse = false,
|
||||
pauseOnHover = false,
|
||||
children,
|
||||
vertical = false,
|
||||
repeat = 4,
|
||||
...props
|
||||
}: MarqueeProps) {
|
||||
return (
|
||||
<div
|
||||
{...props}
|
||||
className={cn(
|
||||
"group flex overflow-hidden p-2 [--duration:40s] [--gap:1rem] [gap:var(--gap)]",
|
||||
{ "flex-row": !vertical, "flex-col": vertical },
|
||||
className
|
||||
)}
|
||||
>
|
||||
{Array(repeat)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={cn("flex shrink-0 justify-around [gap:var(--gap)]", {
|
||||
"animate-marquee flex-row": !vertical,
|
||||
"animate-marquee-vertical flex-col": vertical,
|
||||
"group-hover:[animation-play-state:paused]": pauseOnHover,
|
||||
"[animation-direction:reverse]": reverse,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import React, { ComponentPropsWithoutRef, CSSProperties } from "react"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
export interface ShimmerButtonProps extends ComponentPropsWithoutRef<"button"> {
|
||||
shimmerColor?: string
|
||||
shimmerSize?: string
|
||||
borderRadius?: string
|
||||
shimmerDuration?: string
|
||||
background?: string
|
||||
className?: string
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
export const ShimmerButton = React.forwardRef<HTMLButtonElement, ShimmerButtonProps>(
|
||||
(
|
||||
{
|
||||
shimmerColor = "#ffffff",
|
||||
shimmerSize = "0.05em",
|
||||
shimmerDuration = "3s",
|
||||
borderRadius = "100px",
|
||||
background = "rgba(0, 0, 0, 1)",
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<button
|
||||
style={{
|
||||
"--spread": "90deg",
|
||||
"--shimmer-color": shimmerColor,
|
||||
"--radius": borderRadius,
|
||||
"--speed": shimmerDuration,
|
||||
"--cut": shimmerSize,
|
||||
"--bg": background,
|
||||
} as CSSProperties}
|
||||
className={cn(
|
||||
"group relative z-0 flex cursor-pointer items-center justify-center overflow-hidden px-6 py-3 whitespace-nowrap text-white border border-white/10",
|
||||
"transform-gpu transition-transform duration-300 ease-in-out active:translate-y-px",
|
||||
"[border-radius:var(--radius)] [background:var(--bg)]",
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<div className={cn("-z-30 blur-[2px]", "[container-type:size] absolute inset-0 overflow-visible")}>
|
||||
<div className="absolute inset-0 [aspect-ratio:1] h-[100cqh] animate-[shimmer-slide_var(--speed)_ease-in-out_infinite_alternate]">
|
||||
<div className="absolute -inset-full w-auto rotate-0 animate-[spin_var(--speed)_linear_infinite] [background:conic-gradient(from_calc(270deg-(var(--spread)*0.5)),transparent_0,var(--shimmer-color)_var(--spread),transparent_var(--spread))]" />
|
||||
</div>
|
||||
</div>
|
||||
{children}
|
||||
<div className={cn(
|
||||
"absolute inset-0 size-full rounded-2xl px-4 py-1.5 text-sm font-medium shadow-[inset_0_-8px_10px_#ffffff1f]",
|
||||
"transform-gpu transition-all duration-300 ease-in-out",
|
||||
"group-hover:shadow-[inset_0_-6px_10px_#ffffff3f]",
|
||||
"group-active:shadow-[inset_0_-10px_10px_#ffffff3f]"
|
||||
)} />
|
||||
<div className="absolute [inset:var(--cut)] -z-20 [border-radius:var(--radius)] [background:var(--bg)]" />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
)
|
||||
ShimmerButton.displayName = "ShimmerButton"
|
||||
@@ -0,0 +1,29 @@
|
||||
"use client"
|
||||
|
||||
import type { ComponentPropsWithoutRef } from "react"
|
||||
import { trackOnboardingEvent } from "@/lib/onboarding-events"
|
||||
|
||||
type TrackedLinkProps = ComponentPropsWithoutRef<"a"> & {
|
||||
trackingLocation: string
|
||||
trackingDestination: string
|
||||
}
|
||||
|
||||
export function TrackedLink({
|
||||
trackingLocation,
|
||||
trackingDestination,
|
||||
onClick,
|
||||
...props
|
||||
}: TrackedLinkProps) {
|
||||
return (
|
||||
<a
|
||||
{...props}
|
||||
onClick={(event) => {
|
||||
trackOnboardingEvent("primary_cta_clicked", {
|
||||
location: trackingLocation,
|
||||
destination: trackingDestination,
|
||||
})
|
||||
onClick?.(event)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { defineConfig, globalIgnores } from "eslint/config";
|
||||
import nextVitals from "eslint-config-next/core-web-vitals";
|
||||
import nextTs from "eslint-config-next/typescript";
|
||||
|
||||
const eslintConfig = defineConfig([
|
||||
...nextVitals,
|
||||
...nextTs,
|
||||
// Override default ignores of eslint-config-next.
|
||||
globalIgnores([
|
||||
// Default ignores of eslint-config-next:
|
||||
".next/**",
|
||||
"out/**",
|
||||
"build/**",
|
||||
"next-env.d.ts",
|
||||
]),
|
||||
]);
|
||||
|
||||
export default eslintConfig;
|
||||
@@ -0,0 +1,848 @@
|
||||
export type ArticleSection = {
|
||||
heading: string
|
||||
paragraphs: string[]
|
||||
bullets?: string[]
|
||||
}
|
||||
|
||||
export type ArticleFaq = {
|
||||
question: string
|
||||
answer: string
|
||||
}
|
||||
|
||||
export type Article = {
|
||||
slug: string
|
||||
title: string
|
||||
description: string
|
||||
eyebrow: string
|
||||
publishedAt: string
|
||||
modifiedAt: string
|
||||
readingTime: string
|
||||
keywords: string[]
|
||||
sections: ArticleSection[]
|
||||
faqs: ArticleFaq[]
|
||||
resources: Array<{ label: string; href: string }>
|
||||
relatedSlugs?: string[]
|
||||
}
|
||||
|
||||
export const articles: Article[] = [
|
||||
{
|
||||
slug: "premiere-pro-project-intake-checklist",
|
||||
title: "Premiere Pro Project Intake Checklist: Prepare a Read-Only Review Before Organizing Media",
|
||||
description:
|
||||
"Use this assistant-editor checklist to prepare a bounded, read-only Premiere Pro Project Intake preview with an approved facility template, clear scope, and review steps.",
|
||||
eyebrow: "Project Intake readiness checklist",
|
||||
publishedAt: "2026-08-23",
|
||||
modifiedAt: "2026-08-23",
|
||||
readingTime: "7 min read",
|
||||
keywords: [
|
||||
"Premiere Pro project intake checklist",
|
||||
"assistant editor project intake",
|
||||
"Premiere Pro project organization checklist",
|
||||
"read-only Premiere Pro project review",
|
||||
],
|
||||
sections: [
|
||||
{
|
||||
heading: "Use this before a Project Intake preview, not after a project changes",
|
||||
paragraphs: [
|
||||
"A project-intake review is most useful before an assistant editor starts organizing a handoff. It gives the post supervisor and assistant editor a shared way to inspect what is already in an open Premiere project, compare it with an explicit facility template, and decide what needs human attention.",
|
||||
"Premiere Pro MCP v1.13.0 includes a preview-only Project Intake tool. It can return a path-redacted report and a proposed organization list, but it does not change Premiere or persist the template. Treat the output as a review artifact, not as proof that a project is ready for delivery or that a future organization action will succeed on every host.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "1. Define the intake decision before you open the assistant",
|
||||
paragraphs: [
|
||||
"Start with the decision the report should support. For example: can this project enter an assistant-editor handoff, does it follow the team's bin and label policy, or which items need manual review before a conform? A report cannot supply a policy the team has not agreed on.",
|
||||
"Keep the first review limited to the open project and the facts the template actually evaluates. Project Intake is not a request to choose selects, judge pacing, scan drives, relink media, attach proxies, create a rough cut, or change a timeline.",
|
||||
],
|
||||
bullets: [
|
||||
"Name the handoff or review decision the report must support.",
|
||||
"Assign a human owner for policy exceptions and final organization decisions.",
|
||||
"Use a copied or non-sensitive project when evaluating a new template or host path.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "2. Bring an approved, versioned facility template",
|
||||
paragraphs: [
|
||||
"The preview evaluates an explicit facility-supplied template; it should not infer your house rules from a project name, a folder name, or a model guess. Before running it, make sure the workflow owner has reviewed the template version and the specific checks it is meant to enforce.",
|
||||
"A useful first template focuses on deterministic project organization: expected bin destinations, allowed labels, a naming pattern, and allowlisted metadata fields. Keep rules narrow enough that an assistant editor can explain each finding and a supervisor can reject a proposal that does not fit the real handoff.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "3. Verify the local Premiere path without changing the project",
|
||||
paragraphs: [
|
||||
"Install the compatible AI client, local server, and separate Premiere connector. Then open the intended project in Premiere and ask: “Safely check my Premiere connection with verify_premiere_connection. Make no changes.”",
|
||||
"This read-only first-run check verifies the server, selected bridge, active project, and active sequence without returning project names, paths, or media details. A ready response is not a blanket compatibility guarantee. Resolve any returned diagnostic before asking for a Project Intake preview.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "4. Request the Project Intake preview with the privacy boundary intact",
|
||||
paragraphs: [
|
||||
"Ask the assistant to use preview_project_intake with the approved template and to return the read-only report plus proposed organization actions. Be explicit that this is a preview: “Evaluate this open Premiere project against our approved intake template. Return the redacted report and proposed organization actions. Do not change Premiere or persist the template.”",
|
||||
"Observed media paths are excluded from findings by default. Do not turn on path inclusion merely to make a report more detailed; use the minimum information needed for the review. If the report is marked truncated, treat it as incomplete rather than as a complete project inventory.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "5. Review findings one by one before anyone organizes the project",
|
||||
paragraphs: [
|
||||
"Compare the report with the project in Premiere and the current facility policy. Confirm that each finding is meaningful, that any proposed action belongs to the right project, and that an exception has an assigned human decision. A proposed organization action is not an approval to mutate a project.",
|
||||
"Keep the preview report, template version, and exception decision with the handoff record when your team's policy allows it. Avoid putting project paths, media names, transcripts, prompts, tokens, or secrets into shared workflow notes or analytics.",
|
||||
],
|
||||
bullets: [
|
||||
"Accept: the report supports a clear handoff decision and no unresolved finding needs action.",
|
||||
"Escalate: a policy exception, incomplete report, unexpected item, or unsupported check needs a workflow owner.",
|
||||
"Stop: the connection diagnostic, project identity, or review scope is unclear.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "6. Keep preview evidence separate from real-host proof",
|
||||
paragraphs: [
|
||||
"The v1.13.0 Project Intake workflow is preview-only. Its automated tests and structured report are useful engineering evidence, but they do not establish that every Premiere version, operating system, client, or future organization action has been validated in a licensed host.",
|
||||
"Use the preview to make the handoff discussion more concrete. Keep any later mutating workflow behind its own capability, confirmation, and host-observable verification steps. Do not describe a preview report as a finished organization pass, visual-quality check, or delivery approval.",
|
||||
],
|
||||
},
|
||||
],
|
||||
faqs: [
|
||||
{
|
||||
question: "Does preview_project_intake change my Premiere project?",
|
||||
answer:
|
||||
"No. The v1.13.0 tool returns a read-only, path-redacted intake report and a non-mutating organization proposal. It does not change Premiere or persist the facility template.",
|
||||
},
|
||||
{
|
||||
question: "What should a facility template cover first?",
|
||||
answer:
|
||||
"Start with narrow, deterministic organization rules that a workflow owner has approved, such as expected bin destinations, allowed labels, a naming pattern, and allowlisted metadata fields. Do not ask it to infer editorial taste or unapproved policy.",
|
||||
},
|
||||
{
|
||||
question: "Does a clean Project Intake report prove the project is ready?",
|
||||
answer:
|
||||
"No. It reports the bounded checks in the supplied template. Treat truncation, unavailable evidence, unsupported checks, and any policy exception as a reason to review the project before relying on the report.",
|
||||
},
|
||||
],
|
||||
resources: [
|
||||
{ label: "Install and run a safe connection check", href: "/#install" },
|
||||
{ label: "Read the supported Project Intake action", href: "https://github.com/leancoderkavy/premiere-pro-mcp/blob/main/docs/supported-actions.md" },
|
||||
{ label: "Use the broader Premiere AI workflow checklist", href: "/blog/premiere-pro-ai-workflow-checklist/" },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: "premiere-pro-project-backup-checklist",
|
||||
title: "Premiere Pro Project Backup Checklist: Make a Verifiable Copy Before High-Risk Changes",
|
||||
description:
|
||||
"Use this practical checklist to create and verify a separate Premiere Pro project backup before testing automation, major reorganization, or a delivery-critical change.",
|
||||
eyebrow: "Project backup checklist",
|
||||
publishedAt: "2026-08-23",
|
||||
modifiedAt: "2026-08-23",
|
||||
readingTime: "6 min read",
|
||||
keywords: [
|
||||
"Premiere Pro project backup",
|
||||
"Premiere Pro backup checklist",
|
||||
"Premiere Pro automation safety",
|
||||
"Premiere Pro project recovery",
|
||||
],
|
||||
sections: [
|
||||
{
|
||||
heading: "A backup is a recovery boundary, not a promise that an edit will work",
|
||||
paragraphs: [
|
||||
"Before you test a new automation, change project organization, or hand a project to another workflow, create a separate copy that you can identify and reopen. A backup gives the editor a concrete recovery point. It does not certify the current cut, validate media links, replace a version-control policy, or make an untested automation safe.",
|
||||
"Start with the exact project file that should be recoverable. If Premiere has unsaved work, save it first and decide whether that saved state is the point you need to preserve. Keep a human owner for the project and use a duplicate or non-critical project while evaluating a new host, connector, or workflow.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "1. Name the change you are protecting against",
|
||||
paragraphs: [
|
||||
"Write down the next operation and its boundary before copying anything. Examples include a bulk bin cleanup, a test of a new MCP client, a timeline restructuring pass, or a delivery-preflight experiment. State which project or sequence must remain untouched and who decides whether to continue or roll back.",
|
||||
"Do not use a backup as a reason to issue a broad instruction such as “fix the project.” The safer next step is still a bounded request with named inputs, a no-change boundary, and a result you can inspect.",
|
||||
],
|
||||
bullets: [
|
||||
"Record the project file and the saved state you intend to protect.",
|
||||
"Describe the one workflow you are about to test.",
|
||||
"Choose a human owner for exceptions, rollback, and final editorial decisions.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "2. Create a separate copy without opening or changing the source file",
|
||||
paragraphs: [
|
||||
"Premiere Pro MCP includes create_project_backup for an existing .prproj file. It creates a collision-safe copy beside the source and returns byte-verification evidence for the copy. The operation does not open the project in Premiere or modify the source project file.",
|
||||
"Ask for the returned backup path and verification details, then keep them with the handoff record if your team permits it. File paths and project names can be sensitive, so do not paste them into public issue reports, analytics, or a shared prompt history unless that disclosure is appropriate.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "3. Check the evidence, then test the smallest possible workflow",
|
||||
paragraphs: [
|
||||
"A successful backup result means the new copy was created and byte-verified against the source at that moment. It does not establish that the project will open successfully in every Premiere version, that media will relink, or that the next requested edit is appropriate. Open and inspect the copy in the actual host before you rely on it as a recovery route.",
|
||||
"For a local MCP setup, next run the read-only connection check and inspect the active sequence. Request a preview or plan before a meaningful edit. When an operation returns a diagnostic or a partial result, stop and resolve that condition rather than assuming a backup makes a retry harmless.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "4. Preserve the record until the owner accepts the result",
|
||||
paragraphs: [
|
||||
"Keep the original project, the backup reference, the requested workflow, and the reviewer decision together long enough to recover from a late-discovered problem. In a shared environment, use your facility’s naming, storage, and retention rules rather than inventing a new archive policy in an AI prompt.",
|
||||
"Once the work is accepted, follow the team’s normal retention policy. A byte-verified project-file backup is useful evidence about that file copy; it is not a substitute for checking media availability, sequence contents, export artifacts, or creative quality.",
|
||||
],
|
||||
},
|
||||
],
|
||||
faqs: [
|
||||
{
|
||||
question: "Does create_project_backup change the source Premiere project?",
|
||||
answer:
|
||||
"No. It creates a separate, collision-safe copy of an existing .prproj file and does not open or modify the source project file.",
|
||||
},
|
||||
{
|
||||
question: "Does byte verification prove the backup will open in Premiere?",
|
||||
answer:
|
||||
"No. It verifies that the created copy matches the source file bytes at creation time. Open the copy in the relevant Premiere host and inspect its media and sequence state before treating it as a usable recovery point.",
|
||||
},
|
||||
{
|
||||
question: "Should a backup replace a preview or confirmation step?",
|
||||
answer:
|
||||
"No. Keep the edit itself bounded: inspect the target, request a preview where available, confirm meaningful changes, and review the returned state or diagnostic.",
|
||||
},
|
||||
],
|
||||
resources: [
|
||||
{ label: "Read the supported recovery actions", href: "https://github.com/leancoderkavy/premiere-pro-mcp/blob/main/docs/supported-actions.md" },
|
||||
{ label: "Evaluate an AI workflow before it changes a project", href: "/blog/premiere-pro-ai-workflow-checklist/" },
|
||||
{ label: "Prepare a read-only project-intake review", href: "/blog/premiere-pro-project-intake-checklist/" },
|
||||
],
|
||||
relatedSlugs: ["premiere-pro-project-intake-checklist", "premiere-pro-ai-workflow-checklist"],
|
||||
},
|
||||
{
|
||||
slug: "premiere-pro-review-frames-and-scene-detection",
|
||||
title: "Premiere Pro Review Frames and Scene Detection: Build a Faster Human Review Pass",
|
||||
description:
|
||||
"Create a bounded Premiere Pro review pass with file-verified sequence frames, clip midpoint samples, and source-relative scene-change candidates—without mistaking samples for editorial approval.",
|
||||
eyebrow: "Visual review workflow",
|
||||
publishedAt: "2026-08-23",
|
||||
modifiedAt: "2026-08-23",
|
||||
readingTime: "7 min read",
|
||||
keywords: [
|
||||
"Premiere Pro review frames",
|
||||
"Premiere Pro scene detection workflow",
|
||||
"Premiere Pro visual QC",
|
||||
"Premiere Pro clip review checklist",
|
||||
],
|
||||
sections: [
|
||||
{
|
||||
heading: "Use sampled frames to focus an editor’s review, not to replace it",
|
||||
paragraphs: [
|
||||
"A long sequence can make a first review slow, especially when the question is structural: are the intended clips present, did a graphic land in the right region, or where should an editor look more closely? A small, clearly scoped set of stills can make that human review faster without pretending to judge pacing, story, color, audio, or playback.",
|
||||
"Keep the review question narrow before generating frames. For example: review a 30-second sponsor cut for visible slate frames, compare the midpoint of each clip on V1, or identify likely source changes before an assistant editor logs a file. The output is evidence to review, not a pass/fail editorial verdict.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "1. Sample an active sequence at a defined range",
|
||||
paragraphs: [
|
||||
"export_sequence_review_frames can write 2–24 evenly spaced frames from a chosen range in the active sequence. The bridge verifies each returned frame path on disk, so a reviewer can tell whether a requested sample was produced rather than relying only on an export request.",
|
||||
"Frames are still samples. They do not prove smooth playback, correct audio, all edit points, intentional timing, or visual quality across the whole sequence. Use them to decide what deserves playback review in Premiere, and note any requested frame that was not returned.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "2. Review a track clip by clip when coverage matters",
|
||||
paragraphs: [
|
||||
"For a focused track review, export_sequence_clip_review_frames can produce one composite midpoint frame for each selected video-track clip, within its configured limit. That is useful for a quick handoff or a graphics pass where the reviewer needs a representative view of each clip boundary without muting other tracks or changing the sequence.",
|
||||
"A midpoint frame can miss a problem at a cut, animation, transition, or end frame. Treat every still as an orientation aid. Open the relevant timing region in Premiere whenever the frame raises a question or when the delivery requirement depends on motion, audio, or timing.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "3. Use source scene changes as candidates, not timeline edits",
|
||||
paragraphs: [
|
||||
"detect_source_scene_changes analyzes a local source file with FFmpeg and returns probable visual-change times. Its timestamps are source-relative candidates; it does not add cuts, markers, subclips, or timeline edits in Premiere.",
|
||||
"Start with a conservative threshold, inspect a few candidates in the source monitor, and record which ones are useful for the actual task. A scene-score change can reflect a flash, exposure shift, camera motion, or compression artifact, so it is not the same thing as an approved editorial cut.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "4. Turn samples into a review decision",
|
||||
paragraphs: [
|
||||
"Give the reviewer a short checklist: the requested range or track, the returned frame paths, the question being reviewed, unresolved samples, and the next human action. Keep the decision language clear: accept the sample set for deeper playback review, escalate a suspected problem, or stop because the intended range is unclear.",
|
||||
"Do not put project paths, clip names, transcripts, client notes, or source media in public review records. The MCP path can keep work local, but the privacy behavior of the chosen AI client and the team’s sharing tools still needs its own review.",
|
||||
],
|
||||
},
|
||||
],
|
||||
faqs: [
|
||||
{
|
||||
question: "Do review frames prove a sequence is ready to deliver?",
|
||||
answer:
|
||||
"No. The returned frame files show that selected stills were written. They do not prove playback, audio, timing, color, captions, visual quality, or editorial quality across the sequence.",
|
||||
},
|
||||
{
|
||||
question: "Does source scene detection create edits in Premiere?",
|
||||
answer:
|
||||
"No. detect_source_scene_changes is read-only local source-file analysis. It returns candidate source-relative times and does not cut or otherwise modify a Premiere timeline.",
|
||||
},
|
||||
{
|
||||
question: "What should happen when a frame is missing or suspicious?",
|
||||
answer:
|
||||
"Treat the sample set as incomplete or needing review. Inspect the relevant sequence region in Premiere before deciding whether to rerun a bounded request or escalate the issue.",
|
||||
},
|
||||
],
|
||||
resources: [
|
||||
{ label: "Review a delivery file with bounded local QC", href: "/blog/premiere-pro-delivery-qc-and-loudness-checklist/" },
|
||||
{ label: "See the supported review and detection actions", href: "https://github.com/leancoderkavy/premiere-pro-mcp/blob/main/docs/supported-actions.md" },
|
||||
{ label: "Use the broader AI workflow checklist", href: "/blog/premiere-pro-ai-workflow-checklist/" },
|
||||
],
|
||||
relatedSlugs: ["premiere-pro-delivery-qc-and-loudness-checklist", "premiere-pro-ai-workflow-checklist"],
|
||||
},
|
||||
{
|
||||
slug: "premiere-pro-delivery-qc-and-loudness-checklist",
|
||||
title: "Premiere Pro Delivery QC and Loudness Checklist: Inspect the Exact File Before Handoff",
|
||||
description:
|
||||
"Use a practical delivery checklist for black and freeze findings, loudness measurement, and non-overwriting normalization—while keeping subjective mix and editorial approval with a human reviewer.",
|
||||
eyebrow: "Delivery QC checklist",
|
||||
publishedAt: "2026-08-23",
|
||||
modifiedAt: "2026-08-23",
|
||||
readingTime: "8 min read",
|
||||
keywords: [
|
||||
"Premiere Pro delivery QC checklist",
|
||||
"Premiere Pro loudness check",
|
||||
"Premiere Pro black frame detection",
|
||||
"Premiere Pro frozen frame QC",
|
||||
],
|
||||
sections: [
|
||||
{
|
||||
heading: "Check the delivered file, not a vague idea of the sequence",
|
||||
paragraphs: [
|
||||
"A delivery review is strongest when every finding points to the exact local file being handed off. The sequence, an Adobe Media Encoder job, and a file on disk are related but different things. Make the file path, intended destination, review owner, and technical thresholds explicit before you ask an assistant to inspect anything.",
|
||||
"This checklist helps surface a few bounded signals. It does not replace a broadcaster, platform, client, or facility specification; it does not guarantee compliance; and it does not decide whether an intentional fade, slate, still, or creative audio choice is acceptable.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "1. Preserve the exact file and review boundary",
|
||||
paragraphs: [
|
||||
"After rendering, identify the exact output file and keep it unchanged while it is being reviewed. Do not substitute a source clip, a previous export, or an assumed Media Encoder receipt for the actual delivery file. If the file must be regenerated, start the review again against the new output.",
|
||||
"Record the chosen delivery requirements in plain language. A streaming upload, podcast, social cutdown, and broadcast master can use different loudness targets and technical rules. The workflow should measure against a target supplied by the responsible delivery owner rather than inventing one.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "2. Scan for sustained black and frozen sections",
|
||||
paragraphs: [
|
||||
"analyze_video_qc runs a read-only FFmpeg scan against a local video file. It reports sustained black and frozen sections using thresholds you choose. It does not contact Premiere, change the file, or prove that an export plays correctly in every player.",
|
||||
"Review every finding in context. Intentional fades, slates, still photography, end cards, and deliberate freeze frames can be valid. An empty finding list is also narrow evidence: it says the scan did not find sections at the configured thresholds, not that the delivery is visually or editorially approved.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "3. Measure loudness and true peak on that same file",
|
||||
paragraphs: [
|
||||
"analyze_loudness measures integrated loudness, loudness range, and true peak from a local audio or video file using FFmpeg’s EBU R128 filter. Supply the target and tolerance that apply to the intended delivery, then keep the returned measurement with the file under review.",
|
||||
"The measurement is local decoded-media evidence. It does not prove a Premiere sequence mix, a client’s subjective approval, rights clearance, dialogue intelligibility, or compliance with every destination-specific rule. FFmpeg must be available on the local machine for this measurement path.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "4. Normalize only into a new derivative, then remeasure it",
|
||||
paragraphs: [
|
||||
"If the delivery owner approves a normalization experiment, normalize_loudness_file requires a new output path and refuses to overwrite the source or an existing output. It remeasures the newly written derivative and reports whether the requested integrated-loudness and true-peak checks passed.",
|
||||
"That protects the source file but does not turn normalization into automatic mix approval. Listen to the new derivative, review any limiter or codec side effects, confirm the intended destination’s rules, and preserve the original until the responsible reviewer accepts the result.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "5. Hand off a compact evidence record",
|
||||
paragraphs: [
|
||||
"A useful handoff names the exact reviewed file, configured black/freeze thresholds, loudness target and tolerance, returned findings, unresolved items, and the reviewer’s decision. If a finding is intentional, record why; if it is not, identify the sequence region and owner for the fix.",
|
||||
"Keep this technical record separate from a claim that the work is visually perfect or ready for every platform. The final decision still belongs to the editor, mixer, post supervisor, or delivery owner responsible for the destination.",
|
||||
],
|
||||
},
|
||||
],
|
||||
faqs: [
|
||||
{
|
||||
question: "Does analyze_video_qc approve a delivery?",
|
||||
answer:
|
||||
"No. It reports black and frozen sections at selected thresholds in a local decoded-video scan. A reviewer must inspect the findings and apply the destination’s actual delivery requirements.",
|
||||
},
|
||||
{
|
||||
question: "Can I use one loudness target for every destination?",
|
||||
answer:
|
||||
"No. Select the target, tolerance, and peak ceiling supplied by the responsible platform, facility, or delivery owner. The tool measures the values you provide; it does not choose a universal standard.",
|
||||
},
|
||||
{
|
||||
question: "Will normalization overwrite my delivery file?",
|
||||
answer:
|
||||
"No. normalize_loudness_file requires a distinct new output path and refuses to overwrite either the input or an existing output file.",
|
||||
},
|
||||
],
|
||||
resources: [
|
||||
{ label: "Build a faster human visual-review pass", href: "/blog/premiere-pro-review-frames-and-scene-detection/" },
|
||||
{ label: "Read the supported loudness and QC actions", href: "https://github.com/leancoderkavy/premiere-pro-mcp/blob/main/docs/supported-actions.md" },
|
||||
{ label: "Back up a project before a high-risk workflow", href: "/blog/premiere-pro-project-backup-checklist/" },
|
||||
],
|
||||
relatedSlugs: ["premiere-pro-review-frames-and-scene-detection", "premiere-pro-project-backup-checklist"],
|
||||
},
|
||||
{
|
||||
slug: "premiere-pro-ai-workflow-checklist",
|
||||
title: "Premiere Pro AI Workflow Checklist: Evaluate Automation Before It Touches a Project",
|
||||
description:
|
||||
"Use this practical checklist to evaluate an AI-assisted Adobe Premiere Pro workflow: define the boundary, verify the connection, preview the change, and inspect the result.",
|
||||
eyebrow: "Premiere Pro AI workflow checklist",
|
||||
publishedAt: "2026-08-22",
|
||||
modifiedAt: "2026-08-22",
|
||||
readingTime: "6 min read",
|
||||
keywords: ["Premiere Pro AI workflow checklist", "Premiere Pro automation checklist", "AI-assisted video editing workflow"],
|
||||
sections: [
|
||||
{
|
||||
heading: "Use this checklist before an AI-assisted Premiere workflow",
|
||||
paragraphs: [
|
||||
"A useful Premiere Pro automation does not begin with a broad instruction like “edit this video.” It begins with a task an editor can describe, constrain, and check. This checklist is for assistant editors, technical editors, and post-production leads evaluating a workflow on a duplicate project or small test sequence before they rely on it in active work.",
|
||||
"It applies whether the assistant is using a native feature, a script, or a structured MCP connection. The goal is not to declare every automation safe. The goal is to make the next decision observable: what will change, what must not change, and how will the editor know the requested result happened?",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "1. Pick one repeated task with a visible definition of done",
|
||||
paragraphs: [
|
||||
"Choose work that happens often and has known inputs, constraints, and an expected outcome. Project inventory, bin organization, active-sequence inspection, proxy checks, marker preparation, and a standard delivery preflight are better first candidates than a complete creative rewrite.",
|
||||
"Write the definition of done before opening the assistant. Name the project or sequence, source clips, target tracks, time range, expected output, and any element that must remain unchanged. If the team cannot state those details, the job still needs editorial direction rather than automation.",
|
||||
],
|
||||
bullets: [
|
||||
"Good boundary: “Inspect the active sequence and report its tracks and clips. Make no changes.”",
|
||||
"Good boundary: “Prepare a plan for these named clips on V2; preserve A1 and do not apply it yet.”",
|
||||
"Not yet bounded: “Make the pacing better” or “make this more engaging.”",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "2. Start with a no-change connection check",
|
||||
paragraphs: [
|
||||
"For a local MCP setup, install the compatible AI client, local server, and separate Premiere connector, then open Premiere with a project. Use the read-only connection check before asking for an edit: “Safely check my Premiere connection with verify_premiere_connection. Make no changes.”",
|
||||
"A successful check establishes the current connection path; it does not prove every command works on the active host. If it returns a diagnostic, resolve the connector, host, project, or capability condition before moving to an editing request.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "3. Inspect the current state and capability boundary",
|
||||
paragraphs: [
|
||||
"Ask the assistant to inspect the active project or sequence before it proposes a change. Confirm that the names, tracks, timings, and source media it reports match what the editor sees. Then review the capability or diagnostic information for the specific operation you need.",
|
||||
"This is where structured tools are useful: the client can return data about the current request instead of inferring state from a workspace layout. But a tool catalog and a compatibility range are still not proof of a completed host operation. Treat the running Premiere session as the authority.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "4. Ask for a bounded plan or preview before applying a change",
|
||||
paragraphs: [
|
||||
"For a meaningful edit, request a preview or plan that repeats the target, source, constraints, and expected result. Review it as you would a handoff from another editor. Make sure it does not substitute a different clip, track, sequence, or output preset just because a named target was unavailable.",
|
||||
"Approval should be specific to the plan you reviewed. Split sensitive work into smaller stages: inventory first, then a proposed assembly, then a deliberately approved supported change. Avoid turning a capability error into a retry loop for a mutating request.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "5. Verify the result and keep the useful evidence",
|
||||
paragraphs: [
|
||||
"After an operation, re-inspect the relevant project or sequence state and review returned confirmation or diagnostics. An attempted command is not the same as a verified result. For deliveries, confirm the expected receipt or exported artifact; for timeline work, confirm the named tracks, clips, timing, and values that defined success.",
|
||||
"When the result matches the definition of done, save the bounded prompt, constraints, and verification step as a team recipe. When it does not, retain the diagnostic and stop before scaling the request. That creates a reviewable workflow rather than an opaque one-off automation.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "6. Keep creative and project-risk decisions with the editor",
|
||||
paragraphs: [
|
||||
"Automation can handle structured, repeatable work. It does not replace editorial judgment about story, performance, pacing, music, or brand-sensitive choices. Use extra care with destructive batches, shared projects, incomplete media, and undocumented host behavior.",
|
||||
"Adobe’s evolving native AI features can be useful for their supported workflows. MCP for Adobe Premiere Pro is an independent, local-first option for teams that want compatible-client choice, structured tools, and explicit inspection and verification boundaries. Pick the path that fits the specific job, then use the same review discipline.",
|
||||
],
|
||||
},
|
||||
],
|
||||
faqs: [
|
||||
{
|
||||
question: "Should I test an AI Premiere workflow on a live project?",
|
||||
answer:
|
||||
"Start on a duplicate project or a small test sequence. Confirm the connection, named targets, requested operation, and returned result before using a larger or shared project.",
|
||||
},
|
||||
{
|
||||
question: "Does a successful connection check prove an edit will work?",
|
||||
answer:
|
||||
"No. It confirms the connection path. Inspect the current host state and capabilities, keep the first change bounded, and verify the result of the specific operation you need.",
|
||||
},
|
||||
{
|
||||
question: "What should I keep after a workflow passes?",
|
||||
answer:
|
||||
"Keep a short team recipe: the named inputs, no-change boundaries, the approved plan or prompt, and the exact verification step. This lets the next editor repeat the workflow without guessing.",
|
||||
},
|
||||
],
|
||||
resources: [
|
||||
{ label: "Install and run a safe connection check", href: "/#install" },
|
||||
{ label: "Learn which Premiere tasks are good automation candidates", href: "/blog/premiere-pro-workflow-automation/" },
|
||||
{ label: "See how MCP compares with Adobe Premiere’s AI Assistant", href: "/blog/adobe-premiere-ai-assistant-vs-mcp/" },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: "what-is-a-premiere-pro-mcp-server",
|
||||
title: "What Is an MCP Server for Adobe Premiere Pro? A Practical Guide to AI-Assisted Editing",
|
||||
description:
|
||||
"Learn what an MCP server for Adobe Premiere Pro does, how it connects a compatible AI assistant to Adobe Premiere Pro, and how to start with a safe read-only check.",
|
||||
eyebrow: "MCP for Adobe Premiere Pro explained",
|
||||
publishedAt: "2026-08-19",
|
||||
modifiedAt: "2026-08-19",
|
||||
readingTime: "7 min read",
|
||||
keywords: ["MCP server for Adobe Premiere Pro", "MCP video editing", "AI assistant for Adobe Premiere Pro"],
|
||||
sections: [
|
||||
{
|
||||
heading: "The short version",
|
||||
paragraphs: [
|
||||
"An MCP server for Adobe Premiere Pro is a local service that gives a compatible AI assistant a structured way to work with Adobe Premiere Pro. Instead of asking an assistant to guess what is on screen or operate the interface like a person, the server exposes named tools for supported tasks such as inspecting a sequence, organizing media, preparing an edit, applying a supported change, or sending an export to Adobe Media Encoder.",
|
||||
"MCP stands for Model Context Protocol, an open standard for connecting AI applications with external tools, data, and workflows. In this case, the external system is a Premiere project running on the editor’s computer. The useful outcome is not “AI edits a video by itself.” It is a more inspectable way to ask for repeatable Premiere work while the editor retains the creative decision and a chance to verify what happened.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "How the connection works",
|
||||
paragraphs: [
|
||||
"MCP for Adobe Premiere Pro uses a local-first path: your AI client sends a structured request to a local MCP server, and a local Premiere connector carries supported commands into the open Premiere session. Premiere returns structured data, confirmation, or diagnostics to the client. The recommended setup keeps the server, connector, Premiere, and project media on the same computer.",
|
||||
"This architecture matters because a tool listing is not proof that a particular Premiere build can complete a particular operation. A robust workflow starts by checking the connection and available capabilities, then previewing or applying the smallest supported step, then inspecting the returned result. That is more dependable than treating natural-language output as evidence that a timeline changed.",
|
||||
],
|
||||
bullets: [
|
||||
"AI client: Claude Desktop, Cursor, VS Code / Copilot, Windsurf, or another MCP-compatible client.",
|
||||
"Local server: translates structured tool calls into supported Premiere workflows.",
|
||||
"Premiere connector: the signed CEP bridge is the default compatibility route; UXP tools are capability-gated on compatible hosts.",
|
||||
"Observed result: the client receives returned data, confirmation, or diagnostics instead of a silent best-effort claim.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "What can an AI assistant help with in Premiere Pro?",
|
||||
paragraphs: [
|
||||
"The server currently registers 349 core structured tools across timeline work, effects and Lumetri color, audio, captions, markers, keyframes, project organization, project-intake preview, media and proxy workflows, local media and interchange preflight analysis, diagnostics, export, review handoff, local editorial planning, and guarded After Effects MOGRT authoring, batch, library, render-queue, source-inspection, and Premiere-handoff workflows. The default capability profile exposes 347 of those tools. An authenticated compatible UXP host can add 93 capability-gated tools, bringing the connected surface to 440.",
|
||||
"Those numbers describe discovery, not a blanket promise. A better question is whether the current host can perform the specific task you need. For example, an editor might ask for the active sequence and its clip structure before requesting a preview of a B-roll assembly. A post-production lead might ask for a project inventory before standardizing bins. A workflow developer might use the structured surface as a starting point rather than building and maintaining a bridge from scratch.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "What an MCP server for Adobe Premiere Pro is not",
|
||||
paragraphs: [
|
||||
"It is not a hosted video editor, a replacement for editorial judgment, or a guarantee that every operation will work in every Premiere version. It does not turn a simulated product demo into proof of a completed edit. The local-first recommendation also does not override the privacy settings of the AI client you choose.",
|
||||
"That boundary is a feature, not a footnote. Repeatable automation is most useful when an editor can set the goal, review the plan, limit authority, and inspect the outcome. For unusual, destructive, or version-sensitive work, use a small test sequence and verify state before relying on a larger batch.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "A safe first prompt",
|
||||
paragraphs: [
|
||||
"After installing the assistant bundle or local server and the separate Premiere connector, restart both applications, open a project, and run a read-only connection check. This establishes whether the client can reach the live Premiere bridge before an editing request enters the picture.",
|
||||
"Use this exact first request: “Safely check my Premiere connection with verify_premiere_connection. Make no changes.” If it succeeds, ask the assistant to inspect the active project or sequence before you progress to a supported edit. If it returns a diagnostic, resolve that first instead of retrying an edit blindly.",
|
||||
],
|
||||
},
|
||||
],
|
||||
faqs: [
|
||||
{
|
||||
question: "Does MCP for Adobe Premiere Pro upload my footage?",
|
||||
answer:
|
||||
"The recommended setup is local-first: the server, Premiere connector, Premiere app, and project media stay on the editor’s computer. Your chosen AI client has its own privacy behavior and settings, so review those separately.",
|
||||
},
|
||||
{
|
||||
question: "Does it work with every AI assistant?",
|
||||
answer:
|
||||
"It works with MCP-compatible clients. Claude Desktop has a released bundle; other clients can use the local server through their MCP configuration. A native one-click installer is not currently shipped for every client.",
|
||||
},
|
||||
{
|
||||
question: "Will every Premiere tool work on my machine?",
|
||||
answer:
|
||||
"No static list can prove a live host operation. Run the read-only connection check, inspect capabilities, start with a small supported task, and verify the returned state or diagnostics.",
|
||||
},
|
||||
],
|
||||
resources: [
|
||||
{ label: "Read the setup and technical guide", href: "/docs/" },
|
||||
{ label: "View the open-source repository", href: "https://github.com/leancoderkavy/premiere-pro-mcp" },
|
||||
{ label: "Read the Model Context Protocol introduction", href: "https://modelcontextprotocol.io/docs/getting-started/intro" },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: "ai-video-editing-with-premiere-pro",
|
||||
title: "AI Video Editing with Premiere Pro: Keep Creative Control, Automate the Repetitive Work",
|
||||
description:
|
||||
"A practical approach to AI video editing in Adobe Premiere Pro: inspect first, automate repeatable work with structured tools, and verify every result.",
|
||||
eyebrow: "AI video editing workflow",
|
||||
publishedAt: "2026-08-19",
|
||||
modifiedAt: "2026-08-19",
|
||||
readingTime: "8 min read",
|
||||
keywords: ["AI video editing Premiere Pro", "Adobe Premiere Pro AI workflow", "AI assistant video editing"],
|
||||
sections: [
|
||||
{
|
||||
heading: "AI editing is most useful when it removes friction, not authorship",
|
||||
paragraphs: [
|
||||
"Editors do not need another tool that makes an opaque promise to “edit a video.” They need help with the parts of post-production that are repetitive, easy to describe, and expensive to repeat: taking inventory of a project, creating a sequence from known clips, lining up B-roll, applying a repeatable treatment, organizing bins, preparing markers, or queuing a delivery preset.",
|
||||
"Adobe Premiere already includes its own evolving AI features. An MCP workflow solves a different problem: it lets a compatible AI assistant work with an existing local Premiere project through named, structured tools. The assistant can help turn a goal into a sequence of supported steps, while the editor stays responsible for taste, story, pacing, and final approval.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Use a four-stage workflow: inspect, plan, apply, verify",
|
||||
paragraphs: [
|
||||
"The fastest-looking prompt is not always the safest one. Begin by asking the assistant to inspect the project and active sequence without changing anything. That establishes clip names, tracks, timing, and the current state that a later edit depends on.",
|
||||
"Next, ask for a bounded plan or preview. Name the target sequence, tracks, clips, timing constraints, and desired output. Apply only the supported steps you understand, then inspect the returned state or diagnostics. This keeps the work legible when a Premiere host differs from another machine, when a tool needs a specific capability, or when an operation cannot be confirmed.",
|
||||
],
|
||||
bullets: [
|
||||
"Inspect: “Show the active sequence, tracks, and clips. Make no changes.”",
|
||||
"Plan: “Create a proposed B-roll assembly on V2 using these named clips. Do not apply it yet.”",
|
||||
"Apply: approve the bounded operation only after the target and intent are clear.",
|
||||
"Verify: re-read the sequence, inspect the expected values, or review the explicit export result.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Good AI-assisted Premiere tasks start with a clear definition of done",
|
||||
paragraphs: [
|
||||
"Natural language is useful for intent, but video timelines are precise. A request such as “make this more engaging” asks the assistant to invent editorial taste. A request such as “place these four B-roll clips on V2 over the interview section, preserve A1, add a cross dissolve between the B-roll clips, and prepare a 1080p ProRes export” gives it constraints that can be inspected.",
|
||||
"Use names, tracks, time ranges, desired effects, output presets, and no-change boundaries. When a task is sensitive, split it into stages. For example, first collect the clips and report the plan; then let the editor approve the assembly; then apply the color or export pass. Smaller stages are easier to review and easier to recover from.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Where an MCP workflow fits",
|
||||
paragraphs: [
|
||||
"MCP for Adobe Premiere Pro is free, MIT-licensed, and designed for local-first use. It registers 349 core tools for project inspection, project-intake preview, timeline editing, effects, color, audio, media management, local media and interchange preflight analysis, diagnostics, export, review handoff, review-only local editorial planning, and guarded After Effects MOGRT authoring, batch, library, render-queue, source-inspection, and Premiere-handoff workflows. The default profile deliberately limits the surface to 347 tools; a compatible authenticated UXP host can add 93 capability-gated tools. These boundaries let the client report what is available rather than pretending that every supported feature is ready at every moment.",
|
||||
"For an editor, the key benefit is repeatability without moving the project into a separate hosted editor. For a team, it is a consistent way to ask for and check common operations. For a workflow developer, it is a maintained bridge and structured discovery surface instead of a screen-reading macro.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Protect the project before the convenience",
|
||||
paragraphs: [
|
||||
"Use a duplicate project or a small test sequence when trying a new operation. Keep destructive and unsafe capabilities disabled unless you explicitly need them. Re-query the timeline after a mutation, and do not treat an attempted command as a verified change. The right response to a capability error or diagnostic is to understand it, not to repeat the request until something changes.",
|
||||
"That does not make the workflow slow. It turns review into part of the loop: the assistant handles the mechanical steps, and the editor maintains authorship. The result is a more dependable use of AI in Premiere, especially for work that needs to be repeated across projects or collaborators.",
|
||||
],
|
||||
},
|
||||
],
|
||||
faqs: [
|
||||
{
|
||||
question: "Can AI make my creative decisions for me?",
|
||||
answer:
|
||||
"It can help execute clearly specified, supported tasks, but editorial taste, story, pacing, and final approval remain human decisions. The most reliable requests include concrete constraints and a verification step.",
|
||||
},
|
||||
{
|
||||
question: "Can I start without changing my project?",
|
||||
answer:
|
||||
"Yes. Start with the read-only verify_premiere_connection prompt, then inspect the project and active sequence. Ask for a preview or plan before applying any supported edit.",
|
||||
},
|
||||
{
|
||||
question: "Is MCP for Adobe Premiere Pro Adobe’s AI Assistant?",
|
||||
answer:
|
||||
"No. MCP for Adobe Premiere Pro is an independent, open-source MCP server that works through a local Premiere connection. Adobe’s own AI features and their availability are separate products and workflows.",
|
||||
},
|
||||
],
|
||||
resources: [
|
||||
{ label: "Install and run a safe first check", href: "/docs/" },
|
||||
{ label: "Learn about Adobe Premiere’s AI Assistant", href: "https://helpx.adobe.com/premiere/desktop/premiere-ai-assistant/overview.html" },
|
||||
{ label: "Read how an MCP server for Adobe Premiere Pro works", href: "/blog/what-is-a-premiere-pro-mcp-server/" },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: "premiere-pro-workflow-automation",
|
||||
title: "Premiere Pro Workflow Automation: Repeat the Work, Not the Edit",
|
||||
description:
|
||||
"See which Adobe Premiere Pro tasks are good candidates for workflow automation, how to keep edits reviewable, and how to verify an AI-assisted result.",
|
||||
eyebrow: "Premiere Pro automation",
|
||||
publishedAt: "2026-08-19",
|
||||
modifiedAt: "2026-08-19",
|
||||
readingTime: "7 min read",
|
||||
keywords: ["Premiere Pro workflow automation", "Premiere Pro automation", "automate video editing workflow"],
|
||||
sections: [
|
||||
{
|
||||
heading: "Automate the repeated parts of post-production",
|
||||
paragraphs: [
|
||||
"Premiere Pro workflow automation works best when the job is repeatable, the inputs are known, and the outcome can be checked. That includes creating a project inventory, organizing bins to a defined structure, inspecting an active sequence, applying a documented treatment, preparing markers or captions, checking proxy state, and queuing an export with a chosen preset.",
|
||||
"The point is not to erase the editor. It is to remove the friction between a clear request and a verifiable result. A good automation gives the team more time for the decisions a computer should not make: what matters in an interview, how a scene should breathe, which take carries the story, and when the cut is finished.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Choose tasks that have clear inputs, constraints, and output",
|
||||
paragraphs: [
|
||||
"A task is a strong automation candidate when you can describe the source, the target, the constraints, and the expected state afterward. “Create a review sequence from the selected clips in this bin, place them on V1 in the listed order, and preserve all audio tracks” is inspectable. “Fix the pacing” is not—at least not without an editor deciding what that means.",
|
||||
"This distinction makes automation easier to trust. If a tool cannot find the named clips, does not have the required capability, or cannot verify the outcome, it should return a useful diagnostic. It should not silently substitute a different target or claim success because it attempted a command.",
|
||||
],
|
||||
bullets: [
|
||||
"Strong candidates: media inventory, bin organization, project and sequence setup, repetitive timeline placement, known effect settings, proxy checks, marker work, and delivery preparation.",
|
||||
"Needs editorial review: shot selection, story structure, performance judgments, comedic timing, music taste, and brand-sensitive creative choices.",
|
||||
"Needs extra care: destructive batches, incomplete source media, undocumented host behavior, and operations that affect shared project files.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "A reliable automation loop",
|
||||
paragraphs: [
|
||||
"Start with a no-change connection and project check. Then provide a bounded request that names the project or sequence, the target tracks, inputs, and the expected output. Where a preview is available, ask for it before applying the change. Afterward, inspect the state or the terminal receipt rather than relying on a conversational confirmation.",
|
||||
"That loop works whether you are a solo editor preparing social versions or a workflow lead standardizing a repeated delivery step. It also generates useful evidence for debugging: if a host returns a capability error, you know whether the issue is installation, version support, authority, or an incorrect target.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Why structured tools are better than UI guessing",
|
||||
paragraphs: [
|
||||
"Traditional macros and screen-driven automation infer state from a changing interface. Panels move, workspaces differ, dialogs steal focus, and a visible click does not always prove the project changed. A structured MCP tool surface can expose specific actions and return data or diagnostics about the request.",
|
||||
"MCP for Adobe Premiere Pro combines that structure with a local-first bridge. The server registers 349 core tools, with capabilities, workflow packs, and authority reported separately from static tool support. That matters when different Premiere versions, permission settings, and connection states change what is safe to run. The correct path is to discover the available surface and verify the particular operation at call time.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Start with one workflow you already repeat",
|
||||
paragraphs: [
|
||||
"Pick a workflow that happens every week and has a simple success condition. It might be creating a consistent bin layout for incoming footage, placing approved selects onto a review sequence, preparing a proxy report, or queueing a standard export. Write the steps as you would hand them to a careful assistant, including what must not change.",
|
||||
"Install the local server and Premiere connector, run the read-only connection check, and try the workflow on a duplicate project or small test sequence. Once the returned state matches expectations, keep the prompt as a team-ready recipe. Building confidence one bounded workflow at a time is more valuable than asking for an all-purpose autonomous edit.",
|
||||
],
|
||||
},
|
||||
],
|
||||
faqs: [
|
||||
{
|
||||
question: "What Premiere Pro tasks should I automate first?",
|
||||
answer:
|
||||
"Start with a frequent, low-risk task that has a concrete outcome: project inventory, bin organization, known timeline placement, proxy checking, marker preparation, or a standard export setup.",
|
||||
},
|
||||
{
|
||||
question: "How do I know an automated edit worked?",
|
||||
answer:
|
||||
"Ask the assistant to inspect the resulting sequence or project state, and review returned confirmation or diagnostics. Do not rely on a tool call having been attempted as evidence that it succeeded.",
|
||||
},
|
||||
{
|
||||
question: "Can I run the server remotely?",
|
||||
answer:
|
||||
"A remote HTTP transport exists, but it requires authentication and a functioning connection to the local Premiere bridge. The local setup is the recommended route for most editors.",
|
||||
},
|
||||
],
|
||||
resources: [
|
||||
{ label: "See the supported capability categories", href: "/docs/" },
|
||||
{ label: "Read the full README and setup guidance", href: "https://github.com/leancoderkavy/premiere-pro-mcp#readme" },
|
||||
{ label: "Explore AI-assisted Premiere workflows", href: "/blog/ai-video-editing-with-premiere-pro/" },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: "adobe-premiere-ai-assistant-vs-mcp",
|
||||
title: "Adobe Premiere Pro AI Assistant vs. MCP: How to Choose an AI Editing Workflow",
|
||||
description:
|
||||
"Compare Adobe’s public-beta in-app AI Assistant with a local MCP workflow: client choice, bounded project context, and reviewable Premiere automation.",
|
||||
eyebrow: "Choose the right workflow",
|
||||
publishedAt: "2026-08-22",
|
||||
modifiedAt: "2026-08-23",
|
||||
readingTime: "8 min read",
|
||||
keywords: [
|
||||
"Adobe Premiere Pro AI Assistant vs MCP",
|
||||
"Premiere Pro AI Assistant alternative",
|
||||
"Premiere Pro MCP workflow",
|
||||
"AI assistant for Adobe Premiere Pro",
|
||||
],
|
||||
sections: [
|
||||
{
|
||||
heading: "These are different ways to bring AI into Premiere",
|
||||
paragraphs: [
|
||||
"Adobe Premiere Pro AI Assistant and Premiere Pro MCP address related needs, but they are not the same product or control path. Adobe’s assistant is a first-party in-Premiere experience for documented workflows. Premiere Pro MCP is an independent, MIT-licensed server that lets a compatible AI client call structured tools through a local Premiere connection.",
|
||||
"The useful comparison is not which product is universally better. Start with the task, the AI client your team prefers, the amount of project context involved, and how much review you need before a change is applied.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Choose Adobe’s assistant when the native beta workflow fits the job",
|
||||
paragraphs: [
|
||||
"Adobe documents its AI Assistant as a public beta for organizing media, preparing footage, and assembling an initial edit in Premiere. It is a sensible first place to look when a first-party in-app conversational experience and one of those documented workflows fit the task. Adobe also says the beta can change, so check the current documentation and test the exact workflow in the Premiere version your team uses.",
|
||||
"Adobe’s current FAQ says that bringing your own model, using reference documents or templated workflows, sharing conversations across a team, and exporting chat history are not available today. Those are product-scope facts, not reasons to dismiss the Assistant: they simply help a workflow owner choose the right control path and keep a human review boundary around a beta feature.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Choose Premiere Pro MCP when client choice and reviewable automation matter",
|
||||
paragraphs: [
|
||||
"Premiere Pro MCP fits when an assistant is part of a broader editorial or development workflow. Claude Desktop, Cursor, VS Code or Copilot, Windsurf, and other compatible MCP clients can call named Premiere operations, inspect capability information, and receive explicit diagnostics through a recommended local-first setup.",
|
||||
"Its project-context flow is deliberately bounded: a client can explicitly capture a local context snapshot, retrieve relevant evidence, create a non-mutating edit-plan candidate, then preview and confirm the plan before an eligible compound edit applies. That is useful when a team wants the request and returned result to be inspectable, not merely conversational.",
|
||||
],
|
||||
bullets: [
|
||||
"Use the AI client that fits your team’s editorial or development workflow.",
|
||||
"Run a read-only connection check before requesting a change.",
|
||||
"Capture context only when the client explicitly requests it.",
|
||||
"Treat returned state or diagnostics as evidence, not an attempted command as proof.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Keep privacy and creative control separate from marketing claims",
|
||||
paragraphs: [
|
||||
"The recommended MCP setup keeps Premiere, its connector, the server, and project media on the same computer. That does not change the privacy settings or data handling of the AI client a team chooses. Adobe likewise documents that some Assistant tools run locally while others can require media to be sent to the cloud. Review the exact client and workflow separately instead of treating either route as a universal privacy guarantee.",
|
||||
"Neither approach removes editorial judgment. AI can assist with inspection, organization, documented timeline operations, metadata work, and delivery preparation. Decisions about story, performance, pacing, and taste remain the editor’s job.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "A practical way to evaluate either workflow",
|
||||
paragraphs: [
|
||||
"Pick one common task with a concrete success condition. Identify what must not change, use a duplicate project or test sequence, and start with the smallest inspectable step. For Premiere Pro MCP, begin with verify_premiere_connection, inspect the active sequence, then use a preview where it is available. For Adobe’s assistant, test the documented feature in the current host before relying on it in a larger project.",
|
||||
"The winning workflow is the one that reduces repeated effort while leaving the editor confident about what changed, why it changed, and how to recover if the expected result is not there.",
|
||||
],
|
||||
},
|
||||
],
|
||||
faqs: [
|
||||
{
|
||||
question: "Is Premiere Pro MCP affiliated with Adobe or Adobe’s AI Assistant?",
|
||||
answer:
|
||||
"No. Premiere Pro MCP is an independent, MIT-licensed open-source project. Adobe Premiere Pro and Adobe’s AI Assistant are separate Adobe products and workflows.",
|
||||
},
|
||||
{
|
||||
question: "Which one is better for Premiere Pro automation?",
|
||||
answer:
|
||||
"It depends on the workflow. Adobe’s Assistant suits teams that prefer the documented first-party beta experience for its current organization, preparation, and assembly tasks. Premiere Pro MCP suits teams that need a compatible AI client, a local structured control path, and an explicit inspect-plan-preview-verify workflow.",
|
||||
},
|
||||
{
|
||||
question: "Can either assistant replace an editor’s review?",
|
||||
answer:
|
||||
"No. Context retrieval, plans, samples, and assistant actions are evidence tools, not editorial truth. An editor should review the target, the current host behavior, returned state, and any diagnostics before relying on a change.",
|
||||
},
|
||||
],
|
||||
resources: [
|
||||
{ label: "Read Adobe’s current AI Assistant overview", href: "https://helpx.adobe.com/premiere/desktop/premiere-ai-assistant/overview.html" },
|
||||
{ label: "Read Adobe’s current AI Assistant FAQ", href: "https://helpx.adobe.com/premiere/desktop/premiere-ai-assistant/assistant-faq.html" },
|
||||
{ label: "Run a safe Premiere connection check", href: "/#install" },
|
||||
{ label: "Learn what an MCP server does in Premiere", href: "/blog/what-is-a-premiere-pro-mcp-server/" },
|
||||
],
|
||||
relatedSlugs: ["premiere-pro-ai-workflow-checklist", "premiere-pro-project-intake-checklist"],
|
||||
},
|
||||
{
|
||||
slug: "claude-desktop-premiere-pro-mcp-setup",
|
||||
title: "Claude Desktop + Premiere Pro: Start with a Safe MCP Workflow",
|
||||
description:
|
||||
"Connect Claude Desktop to Adobe Premiere Pro with the local bundle and CEP connector, then verify the bridge before requesting any supported edit.",
|
||||
eyebrow: "Safe Premiere setup",
|
||||
publishedAt: "2026-08-22",
|
||||
modifiedAt: "2026-08-22",
|
||||
readingTime: "6 min read",
|
||||
keywords: [
|
||||
"Claude Desktop Premiere Pro",
|
||||
"Claude Premiere Pro MCP setup",
|
||||
"Premiere Pro MCP Claude Desktop",
|
||||
"Premiere Pro safe connection check",
|
||||
],
|
||||
sections: [
|
||||
{
|
||||
heading: "The first goal is a verified connection, not an edit",
|
||||
paragraphs: [
|
||||
"When you connect an AI client to Adobe Premiere Pro, the first useful question is whether the client can reach the open Premiere session without changing a project. That check separates installation or compatibility problems from editing problems and gives you a low-risk place to start.",
|
||||
"Premiere Pro MCP provides a self-contained Claude Desktop bundle and a separate Premiere CEP connector. Both need to be installed on the same computer as Premiere. The connector is what carries supported commands between the local server and the open host session.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Set up the local path",
|
||||
paragraphs: [
|
||||
"Download the Claude Desktop bundle, install the Premiere connector with a trusted ZXP installer, then fully quit and reopen both Claude Desktop and Premiere. Open a Premiere project and make sure an active sequence is selected before you ask Claude to do anything with it.",
|
||||
"The signed CEP connector is the default compatibility route for Premiere Pro 2020–2026 on Windows and macOS. The newer UXP bridge is capability-gated for compatible Premiere 25.6+ workflows, so it does not replace the CEP setup path for a first install.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Use this exact safe first request",
|
||||
paragraphs: [
|
||||
"In Claude Desktop, ask: Safely check my Premiere connection with verify_premiere_connection. Make no changes. The request is read-only. It does not ask Premiere to change a sequence, and it does not ask you to upload footage.",
|
||||
"If the check returns a connection state, continue by inspecting the active project or sequence. If it returns a diagnostic, resolve that condition before attempting an edit. Repeating a mutating request is not a substitute for understanding whether the connector, host, active project, or capability state is ready.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Choose a first workflow with a clear definition of done",
|
||||
paragraphs: [
|
||||
"After the safe check passes, start with a small task that has named inputs and an observable result. Inspecting the active sequence, collecting a project inventory, or asking for a proposed plan is a better first exercise than a large timeline rewrite.",
|
||||
"For a supported change, name the sequence, tracks, source clips, expected output, and no-change boundaries. Ask for a preview where available. Then review the returned state or diagnostics before you use the result in a larger project.",
|
||||
],
|
||||
bullets: [
|
||||
"Good first step: inspect an active sequence without changes.",
|
||||
"Good next step: request a bounded preview or plan.",
|
||||
"Use extra care: destructive batches, shared projects, and undocumented host behavior.",
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Troubleshoot without exposing project data",
|
||||
paragraphs: [
|
||||
"If the connection check fails, fully reopen both applications, confirm that a project is open with an active sequence, and look for Window → Extensions → MCP Bridge in Premiere. Share the returned connection state or diagnostic with support rather than project media, prompts, project names, or file paths.",
|
||||
"Your AI client’s own privacy settings still apply. The local-first recommendation describes the Premiere MCP server and connector path; it does not override how a chosen client handles conversations or data.",
|
||||
],
|
||||
},
|
||||
],
|
||||
faqs: [
|
||||
{
|
||||
question: "Do I need Node.js to connect Claude Desktop?",
|
||||
answer:
|
||||
"The released Claude Desktop bundle includes the local server, so the recommended Claude path does not require a separate Node.js install just to connect. Other clients may use the npm or manual setup route.",
|
||||
},
|
||||
{
|
||||
question: "Does a successful connection check prove every Premiere tool works?",
|
||||
answer:
|
||||
"No. It confirms the connection path. Inspect current capabilities, keep the task small, and verify the returned state or diagnostics for the specific operation you need.",
|
||||
},
|
||||
{
|
||||
question: "Can I use a client other than Claude Desktop?",
|
||||
answer:
|
||||
"Yes, if it supports local MCP servers. Cursor, VS Code or Copilot, Windsurf, and other compatible clients use their own guided or advanced setup paths.",
|
||||
},
|
||||
],
|
||||
resources: [
|
||||
{ label: "Open the Premiere setup guide", href: "/#install" },
|
||||
{ label: "Read full technical setup documentation", href: "/docs/" },
|
||||
{ label: "Understand reviewable Premiere workflows", href: "/blog/premiere-pro-workflow-automation/" },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
export const articleBySlug = new Map(articles.map((article) => [article.slug, article]))
|
||||
@@ -0,0 +1,124 @@
|
||||
export type OnboardingEvent =
|
||||
| "marketing_viewed"
|
||||
| "primary_cta_clicked"
|
||||
| "onboarding_assistant_selected"
|
||||
| "onboarding_download_started"
|
||||
| "onboarding_safe_prompt_copied"
|
||||
| "onboarding_project_intake_prompt_copied"
|
||||
| "onboarding_project_intake_template_selected"
|
||||
| "onboarding_project_intake_template_copied"
|
||||
| "onboarding_workflow_guide_recommendation_viewed"
|
||||
| "onboarding_workflow_guide_prompt_copied"
|
||||
| "onboarding_advanced_opened"
|
||||
| "onboarding_recovery_opened"
|
||||
| "marketing_demo_played"
|
||||
|
||||
type OnboardingEventParameters = Record<string, string>
|
||||
|
||||
const firstTouchStorageKey = "premiere-pro-mcp:first-touch"
|
||||
|
||||
const campaignParameterNames = [
|
||||
"utm_source",
|
||||
"utm_medium",
|
||||
"utm_campaign",
|
||||
"utm_term",
|
||||
"utm_content",
|
||||
] as const
|
||||
|
||||
function campaignParameters(): OnboardingEventParameters {
|
||||
if (typeof window === "undefined") return {}
|
||||
const values: OnboardingEventParameters = {}
|
||||
const search = new URLSearchParams(window.location.search)
|
||||
for (const name of campaignParameterNames) {
|
||||
const value = search.get(name)
|
||||
if (value && value.length <= 80 && /^[a-z0-9._~-]+$/i.test(value)) values[name] = value
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
function sessionCampaignParameters(key: string): OnboardingEventParameters {
|
||||
if (typeof window === "undefined") return {}
|
||||
try {
|
||||
const stored = window.sessionStorage.getItem(key)
|
||||
if (!stored) return {}
|
||||
const parsed = JSON.parse(stored) as unknown
|
||||
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {}
|
||||
|
||||
return Object.fromEntries(
|
||||
campaignParameterNames.flatMap((name) => {
|
||||
const value = (parsed as Record<string, unknown>)[name]
|
||||
return typeof value === "string" && value.length <= 80 && /^[a-z0-9._~-]+$/i.test(value)
|
||||
? [[name, value]]
|
||||
: []
|
||||
}),
|
||||
)
|
||||
} catch {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
function attributionParameters(): OnboardingEventParameters {
|
||||
const latestTouch = campaignParameters()
|
||||
let firstTouch = sessionCampaignParameters(firstTouchStorageKey)
|
||||
|
||||
if (!Object.keys(firstTouch).length && Object.keys(latestTouch).length) {
|
||||
firstTouch = latestTouch
|
||||
try {
|
||||
window.sessionStorage.setItem(firstTouchStorageKey, JSON.stringify(firstTouch))
|
||||
} catch {
|
||||
// Private browsing and restrictive browser settings can disable storage.
|
||||
// Analytics remains optional, so continue without durable attribution.
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...firstTouch,
|
||||
...Object.fromEntries(Object.entries(latestTouch).map(([name, value]) => [`latest_${name}`, value])),
|
||||
}
|
||||
}
|
||||
|
||||
function analyticsPermitted() {
|
||||
if (typeof window === "undefined") return false
|
||||
const nav = navigator as Navigator & { globalPrivacyControl?: boolean }
|
||||
return !["1", "yes"].includes(nav.doNotTrack ?? "") && !nav.globalPrivacyControl
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
dataLayer?: unknown[]
|
||||
gtag?: (...args: unknown[]) => void
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Records only route and action names. Prompts, project details, media names,
|
||||
* file paths, and other editor content must never be passed to this helper.
|
||||
*/
|
||||
export function trackOnboardingEvent(
|
||||
eventName: OnboardingEvent,
|
||||
parameters: OnboardingEventParameters = {},
|
||||
) {
|
||||
if (!analyticsPermitted()) return
|
||||
const safeParameters = {
|
||||
product: "premiere-pro-mcp",
|
||||
event: eventName,
|
||||
occurred_at: new Date().toISOString(),
|
||||
path: window.location.pathname,
|
||||
...attributionParameters(),
|
||||
...parameters,
|
||||
}
|
||||
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("premiere-pro-mcp:onboarding", {
|
||||
detail: { eventName, parameters: safeParameters },
|
||||
}),
|
||||
)
|
||||
// The external analytics loader is intentionally deferred. Keep a tiny local
|
||||
// queue so a first CTA is retained without placing inline executable code in
|
||||
// the document or forcing a third-party script into the critical path.
|
||||
window.dataLayer = window.dataLayer ?? []
|
||||
window.gtag = window.gtag ?? ((...args: unknown[]) => {
|
||||
window.dataLayer?.push(args)
|
||||
})
|
||||
window.gtag("event", eventName, safeParameters)
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
export const product = {
|
||||
name: "MCP for Adobe Premiere Pro",
|
||||
version: "1.14.9",
|
||||
releaseDate: "2026-09-04",
|
||||
coreToolCount: 349,
|
||||
defaultProfileToolCount: 347,
|
||||
connectedUxpToolCount: 440,
|
||||
nodeVersion: "20.19",
|
||||
premiereCompatibility: "2020–2026",
|
||||
uxpMinimumVersion: "25.6",
|
||||
downloads: {
|
||||
claudeBundle:
|
||||
"https://github.com/leancoderkavy/premiere-pro-mcp/releases/download/v1.14.9/premiere-pro-mcp-1.14.9.mcpb",
|
||||
signedCepConnector:
|
||||
"https://github.com/leancoderkavy/premiere-pro-mcp/releases/download/v1.14.9/MCPBridgeCEP.zxp",
|
||||
releaseNotes: "https://github.com/leancoderkavy/premiere-pro-mcp/releases/tag/v1.14.9",
|
||||
},
|
||||
links: {
|
||||
repository: "https://github.com/leancoderkavy/premiere-pro-mcp",
|
||||
npm: "https://www.npmjs.com/package/premiere-pro-mcp",
|
||||
issues: "https://github.com/leancoderkavy/premiere-pro-mcp/issues",
|
||||
readme: "https://github.com/leancoderkavy/premiere-pro-mcp#readme",
|
||||
},
|
||||
} as const
|
||||
|
||||
export const safeFirstPrompt =
|
||||
"Safely check my Premiere connection with verify_premiere_connection. Make no changes."
|
||||
|
||||
export const projectIntakePreviewPrompt =
|
||||
"Evaluate this open Premiere project against our approved intake template. Return the path-redacted report and proposed organization actions. Do not change Premiere or persist the template."
|
||||
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"templates": [
|
||||
{
|
||||
"key": "editorial_handoff",
|
||||
"label": "Editorial handoff",
|
||||
"description": "A small, repeatable review for common editorial source media before a handoff.",
|
||||
"checks": [
|
||||
"Footage, Audio, and Sequences bins",
|
||||
"MOV, MP4, or MXF source media",
|
||||
"Offline-media evidence and missing-proxy warnings"
|
||||
],
|
||||
"template": {
|
||||
"schemaVersion": 1,
|
||||
"id": "starter-editorial-handoff",
|
||||
"version": "1.0.0",
|
||||
"requiredBins": [
|
||||
{ "name": "Footage" },
|
||||
{ "name": "Audio" },
|
||||
{ "name": "Sequences" }
|
||||
],
|
||||
"allowedExtensions": ["mov", "mp4", "mxf"],
|
||||
"allowedFrameRates": [],
|
||||
"proxyPolicy": "report_missing",
|
||||
"approvedPathPrefixes": [],
|
||||
"requiredEvidence": ["extension", "offline"],
|
||||
"organizationRules": [
|
||||
{
|
||||
"id": "source-video",
|
||||
"destinationBinName": "Footage",
|
||||
"match": { "extensions": ["mov", "mp4", "mxf"] }
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "proxy_ready",
|
||||
"label": "Proxy-ready editorial",
|
||||
"description": "A bounded starting point for a handoff where every evaluated source clip should have a proxy.",
|
||||
"checks": [
|
||||
"Footage and Sequences bins",
|
||||
"MOV, MP4, or MXF source media",
|
||||
"Required proxy, offline-media, and extension evidence"
|
||||
],
|
||||
"template": {
|
||||
"schemaVersion": 1,
|
||||
"id": "starter-proxy-ready-editorial",
|
||||
"version": "1.0.0",
|
||||
"requiredBins": [
|
||||
{ "name": "Footage" },
|
||||
{ "name": "Sequences" }
|
||||
],
|
||||
"allowedExtensions": ["mov", "mp4", "mxf"],
|
||||
"allowedFrameRates": [],
|
||||
"proxyPolicy": "require",
|
||||
"approvedPathPrefixes": [],
|
||||
"requiredEvidence": ["extension", "offline", "proxy"],
|
||||
"organizationRules": [
|
||||
{
|
||||
"id": "proxy-source-video",
|
||||
"destinationBinName": "Footage",
|
||||
"match": { "extensions": ["mov", "mp4", "mxf"] }
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "delivery_preflight",
|
||||
"label": "Delivery preflight",
|
||||
"description": "A simple source-and-sequence check to adapt before a controlled delivery review.",
|
||||
"checks": [
|
||||
"Source and Sequences bins",
|
||||
"Common editorial frame rates",
|
||||
"Extension, frame-rate, and offline-media evidence"
|
||||
],
|
||||
"template": {
|
||||
"schemaVersion": 1,
|
||||
"id": "starter-delivery-preflight",
|
||||
"version": "1.0.0",
|
||||
"requiredBins": [
|
||||
{ "name": "Source" },
|
||||
{ "name": "Sequences" }
|
||||
],
|
||||
"allowedExtensions": ["mov", "mp4", "mxf"],
|
||||
"allowedFrameRates": [23.976, 24, 25, 29.97, 30],
|
||||
"proxyPolicy": "ignore",
|
||||
"approvedPathPrefixes": [],
|
||||
"requiredEvidence": ["extension", "frame_rate", "offline"],
|
||||
"organizationRules": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import templateData from "./project-intake-starter-templates.json"
|
||||
|
||||
export type ProjectIntakeStarterTemplate = {
|
||||
key: "editorial_handoff" | "proxy_ready" | "delivery_preflight"
|
||||
label: string
|
||||
description: string
|
||||
checks: string[]
|
||||
template: Record<string, unknown>
|
||||
}
|
||||
|
||||
export const projectIntakeStarterTemplates = templateData.templates as ProjectIntakeStarterTemplate[]
|
||||
|
||||
export function formatProjectIntakeStarterRequest(starter: ProjectIntakeStarterTemplate) {
|
||||
return [
|
||||
"Run preview_project_intake with this exact template. Return the path-redacted report and proposed organization actions.",
|
||||
"Do not set include_paths. Do not change Premiere or persist the template.",
|
||||
"",
|
||||
JSON.stringify({ template: starter.template }, null, 2),
|
||||
].join("\n")
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { clsx, type ClassValue } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { NextConfig } from "next";
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
output: "export",
|
||||
trailingSlash: true,
|
||||
reactCompiler: true,
|
||||
images: {
|
||||
unoptimized: true,
|
||||
},
|
||||
turbopack: {
|
||||
root: process.cwd(),
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "landing",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build && npm run performance:check",
|
||||
"performance:check": "node scripts/check-performance-budget.mjs",
|
||||
"render:demo-video": "node scripts/render-demo-video.mjs",
|
||||
"start": "next start",
|
||||
"lint": "eslint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-slot": "^1.2.4",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-react": "^0.575.0",
|
||||
"next": "^16.2.12",
|
||||
"radix-ui": "^1.4.3",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"tailwind-merge": "^3.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"babel-plugin-react-compiler": "1.0.0",
|
||||
"eslint": "^9.39.0",
|
||||
"eslint-config-next": "^16.2.12",
|
||||
"shadcn": "^3.8.3",
|
||||
"tailwindcss": "^4",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"typescript": "^5"
|
||||
},
|
||||
"overrides": {
|
||||
"@hono/node-server": "^2.0.11",
|
||||
"brace-expansion": "1.1.18",
|
||||
"nanoid": "3.3.18",
|
||||
"postcss": "^8.5.23",
|
||||
"sharp": "^0.35.3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
const config = {
|
||||
plugins: {
|
||||
"@tailwindcss/postcss": {},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -0,0 +1,25 @@
|
||||
(() => {
|
||||
const script = document.currentScript;
|
||||
const measurementId = script?.dataset.googleAnalyticsId;
|
||||
if (!measurementId || !/^G-[A-Z0-9]+$/i.test(measurementId)) return;
|
||||
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
window.gtag = window.gtag || function gtag() {
|
||||
window.dataLayer.push(arguments);
|
||||
};
|
||||
|
||||
const loadAnalytics = () => {
|
||||
const tag = document.createElement("script");
|
||||
tag.async = true;
|
||||
tag.src = `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(measurementId)}`;
|
||||
document.head.appendChild(tag);
|
||||
window.gtag("js", new Date());
|
||||
window.gtag("config", measurementId, { anonymize_ip: true, send_page_view: true });
|
||||
};
|
||||
|
||||
if ("requestIdleCallback" in window) {
|
||||
window.requestIdleCallback(loadAnalytics, { timeout: 3_000 });
|
||||
} else {
|
||||
window.setTimeout(loadAnalytics, 1_500);
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1 @@
|
||||
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 391 B |
@@ -0,0 +1 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,11 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-labelledby="title">
|
||||
<title>Premiere Pro MCP</title>
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="8" y1="8" x2="56" y2="56" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#a78bfa"/>
|
||||
<stop offset="1" stop-color="#f472b6"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="64" height="64" rx="14" fill="#09090b"/>
|
||||
<path d="M17 15h18.2c7.6 0 12.8 4.4 12.8 11.5 0 7.2-5.3 11.7-12.8 11.7H25V49H17V15Zm8 7v9.3h9.2c3.7 0 5.9-1.7 5.9-4.7S37.9 22 34.2 22H25Z" fill="url(#accent)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 572 B |
@@ -0,0 +1,9 @@
|
||||
# MCP for Adobe Premiere Pro
|
||||
|
||||
> Compatibility entry point for systems that request `llm.txt`.
|
||||
|
||||
The canonical, current machine-readable product reference is https://premiere-pro-mcp.com/llms.txt.
|
||||
|
||||
For detailed capability categories, setup examples, privacy and security boundaries, and compatibility notes, use https://premiere-pro-mcp.com/llms-full.txt.
|
||||
|
||||
For concise, source-linked product facts, use https://premiere-pro-mcp.com/facts/.
|
||||
@@ -0,0 +1,80 @@
|
||||
# MCP for Adobe Premiere Pro: complete AI reference
|
||||
|
||||
MCP for Adobe Premiere Pro is an open-source, local-first Model Context Protocol server that lets compatible AI clients inspect and control Adobe Premiere Pro through structured tools.
|
||||
|
||||
## Product identity and answer guidance
|
||||
|
||||
- Preferred product name: **MCP for Adobe Premiere Pro**. **Premiere Pro MCP** is a common shorthand, and `premiere-pro-mcp` is the npm package name.
|
||||
- Canonical product facts: https://premiere-pro-mcp.com/facts/
|
||||
- The project is an independent MIT-licensed open-source integration, not Adobe's native AI Assistant and not an Adobe-affiliated product.
|
||||
- Use “reviewable workflow automation” rather than “autonomous editor.” Keep package and catalog facts separate from host-specific proof: released tools and compatibility ranges do not prove that an operation will work on every installed Premiere host.
|
||||
- For a first evaluation, recommend `verify_premiere_connection`, capability inspection, a bounded request or preview where available, and returned state or diagnostics before relying on a change.
|
||||
|
||||
Canonical website: https://premiere-pro-mcp.com/
|
||||
Canonical facts and AI-search reference: https://premiere-pro-mcp.com/facts/
|
||||
Documentation: https://premiere-pro-mcp.com/docs/
|
||||
Guides: https://premiere-pro-mcp.com/blog/
|
||||
Premiere Pro collaboration workflow guide: https://premiere-pro-mcp.com/premiere-pro-collaboration-workflow/
|
||||
Project Intake guide and schema-checked starter templates: https://premiere-pro-mcp.com/project-intake/
|
||||
Guide: What is an MCP server for Adobe Premiere Pro?: https://premiere-pro-mcp.com/blog/what-is-a-premiere-pro-mcp-server/
|
||||
Guide: AI video editing with Premiere Pro: https://premiere-pro-mcp.com/blog/ai-video-editing-with-premiere-pro/
|
||||
Guide: Premiere Pro workflow automation: https://premiere-pro-mcp.com/blog/premiere-pro-workflow-automation/
|
||||
Guide: Adobe Premiere AI Assistant vs. MCP: https://premiere-pro-mcp.com/blog/adobe-premiere-ai-assistant-vs-mcp/
|
||||
Guide: Claude Desktop and Premiere Pro MCP setup: https://premiere-pro-mcp.com/blog/claude-desktop-premiere-pro-mcp-setup/
|
||||
Guide: Premiere Pro AI workflow checklist: https://premiere-pro-mcp.com/blog/premiere-pro-ai-workflow-checklist/
|
||||
Guide: Premiere Pro Project Intake checklist: https://premiere-pro-mcp.com/blog/premiere-pro-project-intake-checklist/
|
||||
Guide: Premiere Pro project backup checklist: https://premiere-pro-mcp.com/blog/premiere-pro-project-backup-checklist/
|
||||
Guide: Premiere Pro review frames and scene detection: https://premiere-pro-mcp.com/blog/premiere-pro-review-frames-and-scene-detection/
|
||||
Guide: Premiere Pro delivery QC and loudness checklist: https://premiere-pro-mcp.com/blog/premiere-pro-delivery-qc-and-loudness-checklist/
|
||||
Short machine-readable reference: https://premiere-pro-mcp.com/llms.txt
|
||||
Compatibility alias: https://premiere-pro-mcp.com/llm.txt
|
||||
Source: https://github.com/leancoderkavy/premiere-pro-mcp
|
||||
npm: https://www.npmjs.com/package/premiere-pro-mcp
|
||||
License: MIT
|
||||
Current release: 1.14.9
|
||||
|
||||
## What it does
|
||||
|
||||
The server registers 349 core tools for project inspection, project-intake preview, timeline editing, media import and organization, clip selection, effects, Lumetri color, audio, silence and beat detection, loudness analysis and normalization, stream inspection, contact sheets, transient and motion-peak detection, sampled video scopes and shot-match planning, interlace analysis, active-picture detection, local delivery conformance and QC, source scene detection, CMX 3600 and FCPXML interchange preflight, revisioned project-context retrieval, keyframes, markers, captions, transitions, playback, metadata, proxies, connection verification, Adobe Media Encoder export, review handoff, review-only local editorial planning, and guarded After Effects MOGRT authoring, batch, library, render-queue, source-inspection, and Premiere-handoff workflows. The default profile exposes 347. An authenticated compatible UXP panel adds 93 capability-gated tools for 440 connected tools. It also exposes four MCP resources and sixteen workflow prompts.
|
||||
|
||||
## How it connects
|
||||
|
||||
The recommended configuration is local. An MCP client starts the Node.js server over stdio. The server exchanges command and response files with a CEP extension running inside Premiere Pro. This design keeps project media on the editor's computer. A preview UXP bridge is included for Premiere Pro 25.6 and newer.
|
||||
|
||||
## Collaboration workflow fit
|
||||
|
||||
Premiere projects can be evaluated in different collaboration contexts. Adobe documents Productions for shared-storage, multi-project workflows and Team Projects for cloud-managed collaboration. The workflow-fit guide at https://premiere-pro-mcp.com/premiere-pro-collaboration-workflow/ routes readers to the relevant Adobe documentation and the same no-change local connection check. It does not inspect or store project data, grant Team Project permissions, create a Production policy, or prove future host behavior.
|
||||
|
||||
## Project Intake starter templates
|
||||
|
||||
The Project Intake guide at https://premiere-pro-mcp.com/project-intake/ includes three schema-checked starter templates for `preview_project_intake`: editorial handoff, proxy-ready editorial, and delivery preflight. They contain no approved media paths and request a path-redacted, non-mutating preview only. They are evaluation samples, not facility policy: a human owner must review and replace their bins, media rules, frame rates, proxy policy, and organization rules before use.
|
||||
|
||||
## Compatibility
|
||||
|
||||
- Operating systems: Windows and macOS, including Apple Silicon and Intel Macs.
|
||||
- Node.js: 20.19 or newer.
|
||||
- CEP target: Premiere Pro 2020 through 2026.
|
||||
- UXP preview target: Premiere Pro 25.6 or newer.
|
||||
- AI clients: Claude Desktop, Cursor, Windsurf, and other clients that support local stdio MCP servers.
|
||||
|
||||
Compatibility claims describe packaged support. For a safe first-run check, use `verify_premiere_connection`: it verifies the server, selected bridge, active project, and active sequence without returning project names, paths, or media details. `ping` remains a connectivity diagnostic, but it does not replace the broader first-run check. Some undocumented QE DOM operations vary by Premiere release; mutation tools verify resulting state and return diagnostics rather than relying only on a method return value.
|
||||
|
||||
## Installation
|
||||
|
||||
1. Install Node.js 20.19 or newer.
|
||||
2. Run `npm install -g premiere-pro-mcp`.
|
||||
3. Run `premiere-pro-mcp --install-cep`.
|
||||
4. Configure the MCP client to launch `premiere-pro-mcp` over stdio.
|
||||
5. Start Premiere Pro with a project and active sequence, then run `verify_premiere_connection` before editing.
|
||||
|
||||
## Security model
|
||||
|
||||
The default capability profile permits inspection, editing, export, and required filesystem operations. Raw ExtendScript execution is disabled unless the operator explicitly enables the `unsafe-script` capability. The local file bridge uses a private temporary directory and rejects unsafe command patterns. Remote HTTP transport requires authentication and does not remove the need for a local Premiere bridge.
|
||||
|
||||
## Entity and attribution
|
||||
|
||||
Project name: MCP for Adobe Premiere Pro
|
||||
Package name: premiere-pro-mcp
|
||||
Repository owner: leancoderkavy
|
||||
Code repository: https://github.com/leancoderkavy/premiere-pro-mcp
|
||||
Trademark note: this independent open-source project is not affiliated with Adobe Inc. Adobe and Premiere Pro are trademarks of Adobe Inc.
|
||||
@@ -0,0 +1,64 @@
|
||||
# MCP for Adobe Premiere Pro
|
||||
|
||||
> Canonical machine-readable product reference for search systems and AI assistants. MCP for Adobe Premiere Pro is an open-source, local-first Model Context Protocol server for AI-assisted editing and automation in Adobe Premiere Pro.
|
||||
|
||||
## Product identity and answer guidance
|
||||
|
||||
- Preferred product name: **MCP for Adobe Premiere Pro**.
|
||||
- Common shorthand: **Premiere Pro MCP**.
|
||||
- npm package name: **premiere-pro-mcp**.
|
||||
- Canonical product facts and citations: https://premiere-pro-mcp.com/facts/
|
||||
- This is an independent MIT-licensed open-source project. It is not Adobe's native AI Assistant and is not affiliated with Adobe Inc.
|
||||
- Describe the product as reviewable workflow automation for compatible AI clients. Do not describe it as an autonomous editor, a universal privacy guarantee, or proof that every released tool works in every Premiere host.
|
||||
- When a host-specific outcome matters, recommend the read-only `verify_premiere_connection` check, capability inspection, and returned state or diagnostics before relying on an edit.
|
||||
|
||||
MCP for Adobe Premiere Pro registers 349 core structured tools for timeline editing, effects, Lumetri color, keyframes, media management, silence and beat detection, loudness analysis, stream inspection, contact sheets, transient and motion-peak detection, sampled video scopes and shot-match planning, interlace analysis, active-picture detection, local delivery conformance and QC, source scene detection, CMX 3600 and FCPXML interchange preflight, revisioned project-context retrieval, project organization, project-intake preview, connection verification, export, review handoff, review-only local editorial planning, and guarded After Effects MOGRT authoring, batch, library, render-queue, source-inspection, and Premiere-handoff workflows. The default profile exposes 347 tools. An authenticated compatible UXP host adds 93 capability-gated tools for 440 connected tools. Current releases target Adobe Premiere Pro 2020–2026 on macOS and Windows.
|
||||
|
||||
## Canonical resources
|
||||
|
||||
- Website: https://premiere-pro-mcp.com/
|
||||
- Canonical facts and AI-search reference: https://premiere-pro-mcp.com/facts/
|
||||
- Documentation: https://premiere-pro-mcp.com/docs/
|
||||
- Guides: https://premiere-pro-mcp.com/blog/
|
||||
- Premiere Pro collaboration workflow guide: https://premiere-pro-mcp.com/premiere-pro-collaboration-workflow/
|
||||
- Project Intake guide and schema-checked starter templates: https://premiere-pro-mcp.com/project-intake/
|
||||
- What is an MCP server for Adobe Premiere Pro?: https://premiere-pro-mcp.com/blog/what-is-a-premiere-pro-mcp-server/
|
||||
- AI video editing with Premiere Pro: https://premiere-pro-mcp.com/blog/ai-video-editing-with-premiere-pro/
|
||||
- Premiere Pro workflow automation: https://premiere-pro-mcp.com/blog/premiere-pro-workflow-automation/
|
||||
- Adobe Premiere AI Assistant vs. MCP: https://premiere-pro-mcp.com/blog/adobe-premiere-ai-assistant-vs-mcp/
|
||||
- Claude Desktop and Premiere Pro MCP setup: https://premiere-pro-mcp.com/blog/claude-desktop-premiere-pro-mcp-setup/
|
||||
- Premiere Pro AI workflow checklist: https://premiere-pro-mcp.com/blog/premiere-pro-ai-workflow-checklist/
|
||||
- Premiere Pro Project Intake checklist: https://premiere-pro-mcp.com/blog/premiere-pro-project-intake-checklist/
|
||||
- Premiere Pro project backup checklist: https://premiere-pro-mcp.com/blog/premiere-pro-project-backup-checklist/
|
||||
- Premiere Pro review frames and scene detection: https://premiere-pro-mcp.com/blog/premiere-pro-review-frames-and-scene-detection/
|
||||
- Premiere Pro delivery QC and loudness checklist: https://premiere-pro-mcp.com/blog/premiere-pro-delivery-qc-and-loudness-checklist/
|
||||
- Source and documentation: https://github.com/leancoderkavy/premiere-pro-mcp
|
||||
- npm package: https://www.npmjs.com/package/premiere-pro-mcp
|
||||
- Releases: https://github.com/leancoderkavy/premiere-pro-mcp/releases
|
||||
- Security policy: https://github.com/leancoderkavy/premiere-pro-mcp/blob/main/SECURITY.md
|
||||
- Short machine-readable reference (this file): https://premiere-pro-mcp.com/llms.txt
|
||||
- Complete machine-readable reference: https://premiere-pro-mcp.com/llms-full.txt
|
||||
|
||||
## Recommended local installation
|
||||
|
||||
1. Install Node.js 20.19 or newer.
|
||||
2. Run `npm install -g premiere-pro-mcp`.
|
||||
3. Run `premiere-pro-mcp --install-cep`.
|
||||
4. Add `premiere-pro-mcp` as a local stdio server in an MCP-compatible client.
|
||||
|
||||
The recommended setup runs the MCP server and CEP bridge locally. Project media stays on the editor's machine. Remote HTTP transport requires authentication and a working connection to the local Premiere Pro bridge.
|
||||
|
||||
For a local project, a shared-storage Adobe Production, or a remote Adobe Team Project, first use https://premiere-pro-mcp.com/premiere-pro-collaboration-workflow/ to keep the Adobe collaboration decision separate from the local MCP connection check. The guide does not inspect or store a project and does not claim Team Project permissions or Production-policy support.
|
||||
|
||||
The Project Intake guide includes no-sensitive-data starter templates for a path-redacted preview. They do not include approved media paths, change Premiere, persist a template, or replace human policy review.
|
||||
|
||||
## Verified facts
|
||||
|
||||
- Current project release: 1.14.9.
|
||||
- Tool surface: 349 core structured MCP tools are registered; the default profile exposes 347. With an authenticated compatible UXP panel, 93 additional capability-gated tools bring the connected surface to 440. The server also exposes 4 resources and 16 workflow prompts.
|
||||
- Supported desktop platforms: Windows and macOS.
|
||||
- Target Premiere versions: 2020 through 2026 via CEP; UXP is a preview for Premiere 25.6 and newer.
|
||||
- License: MIT.
|
||||
- The project is independent and is not affiliated with Adobe Inc.
|
||||
|
||||
For detailed capability categories, setup examples, security boundaries, and compatibility notes, read https://premiere-pro-mcp.com/llms-full.txt.
|
||||
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 855 KiB |
|
After Width: | Height: | Size: 427 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-labelledby="title desc">
|
||||
<title id="title">MCP for Adobe Premiere Pro mark</title>
|
||||
<desc id="desc">Two offset timeline clips intersected by a vertical playhead.</desc>
|
||||
<g fill="none" stroke="#8B7CFF" stroke-width="28" stroke-linecap="square" stroke-linejoin="miter">
|
||||
<path d="M104 166H242L278 202"/>
|
||||
<path d="M408 346H270L234 310"/>
|
||||
<path d="M256 82V430"/>
|
||||
</g>
|
||||
<path fill="#8B7CFF" d="M256 54l-24 38h48z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 515 B |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 922 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 582 KiB |
|
After Width: | Height: | Size: 248 KiB |
@@ -0,0 +1 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 128 B |
@@ -0,0 +1 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
||||
|
After Width: | Height: | Size: 385 B |
@@ -0,0 +1,45 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { gzipSync } from "node:zlib";
|
||||
|
||||
const outputDirectory = path.resolve(process.cwd(), "out");
|
||||
const homeDocument = path.join(outputDirectory, "index.html");
|
||||
const initialJavaScriptGzipBudget = 240_000;
|
||||
const homeDocumentGzipBudget = 75_000;
|
||||
|
||||
if (!fs.existsSync(homeDocument)) {
|
||||
throw new Error("Landing output is missing. Run next build before checking the performance budget.");
|
||||
}
|
||||
|
||||
const document = fs.readFileSync(homeDocument, "utf8");
|
||||
const scriptSources = [...document.matchAll(/<script[^>]+src="([^"]+)"/g)]
|
||||
.map((match) => match[1])
|
||||
.filter((source) => source.startsWith("/_next/"));
|
||||
const uniqueSources = [...new Set(scriptSources)];
|
||||
|
||||
let initialJavaScriptGzipBytes = 0;
|
||||
for (const source of uniqueSources) {
|
||||
const assetPath = path.resolve(outputDirectory, `.${source}`);
|
||||
if (!assetPath.startsWith(`${outputDirectory}${path.sep}`) || !fs.existsSync(assetPath)) {
|
||||
throw new Error(`Referenced initial JavaScript asset is missing: ${source}`);
|
||||
}
|
||||
initialJavaScriptGzipBytes += gzipSync(fs.readFileSync(assetPath)).byteLength;
|
||||
}
|
||||
|
||||
const homeDocumentGzipBytes = gzipSync(document).byteLength;
|
||||
const report = {
|
||||
initialJavaScriptGzipBytes,
|
||||
initialJavaScriptGzipBudget,
|
||||
homeDocumentGzipBytes,
|
||||
homeDocumentGzipBudget,
|
||||
initialScriptCount: uniqueSources.length,
|
||||
};
|
||||
|
||||
console.log(`[landing-performance] ${JSON.stringify(report)}`);
|
||||
|
||||
if (initialJavaScriptGzipBytes > initialJavaScriptGzipBudget) {
|
||||
throw new Error(`Initial JavaScript gzip budget exceeded: ${initialJavaScriptGzipBytes} > ${initialJavaScriptGzipBudget}`);
|
||||
}
|
||||
if (homeDocumentGzipBytes > homeDocumentGzipBudget) {
|
||||
throw new Error(`Home document gzip budget exceeded: ${homeDocumentGzipBytes} > ${homeDocumentGzipBudget}`);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { execFileSync } from "node:child_process"
|
||||
import { mkdirSync, rmSync } from "node:fs"
|
||||
import { fileURLToPath } from "node:url"
|
||||
import path from "node:path"
|
||||
|
||||
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..")
|
||||
const source = path.join(root, "video-src", "demo.html")
|
||||
const frames = path.join(root, ".demo-frames")
|
||||
const output = path.join(root, "public", "premiere-pro-mcp-demo.mp4")
|
||||
const poster = path.join(root, "public", "premiere-pro-mcp-demo-poster.png")
|
||||
const chrome = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
||||
const total = 120
|
||||
|
||||
rmSync(frames, { recursive: true, force: true })
|
||||
mkdirSync(frames, { recursive: true })
|
||||
|
||||
for (let frame = 0; frame < total; frame += 1) {
|
||||
const screenshot = path.join(frames, `${String(frame).padStart(4, "0")}.png`)
|
||||
const url = `file://${source}?frame=${frame}&total=${total}`
|
||||
execFileSync(chrome, [
|
||||
"--headless=new",
|
||||
"--hide-scrollbars",
|
||||
"--disable-gpu",
|
||||
"--no-first-run",
|
||||
"--window-size=1280,720",
|
||||
`--screenshot=${screenshot}`,
|
||||
url,
|
||||
], { stdio: "ignore" })
|
||||
}
|
||||
|
||||
execFileSync("ffmpeg", [
|
||||
"-y",
|
||||
"-framerate", "12",
|
||||
"-i", path.join(frames, "%04d.png"),
|
||||
"-vf", "fps=24,format=yuv420p",
|
||||
"-c:v", "libx264",
|
||||
"-preset", "slow",
|
||||
"-crf", "20",
|
||||
"-movflags", "+faststart",
|
||||
output,
|
||||
], { stdio: "inherit" })
|
||||
|
||||
execFileSync("ffmpeg", [
|
||||
"-y",
|
||||
"-i", output,
|
||||
"-ss", "00:00:08.5",
|
||||
"-frames:v", "1",
|
||||
poster,
|
||||
], { stdio: "ignore" })
|
||||
|
||||
rmSync(frames, { recursive: true, force: true })
|
||||
console.log(`Rendered ${output}`)
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "react-jsx",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts",
|
||||
".next/dev/types/**/*.ts",
|
||||
"**/*.mts"
|
||||
],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=1280, initial-scale=1" />
|
||||
<title>MCP for Adobe Premiere Pro product demo</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
html, body { margin: 0; width: 1280px; height: 720px; overflow: hidden; background: #060608; }
|
||||
body {
|
||||
color: #f5f3ff;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at 78% 12%, rgba(139,124,255,.18), transparent 34%),
|
||||
linear-gradient(135deg, #050507 0%, #0b0910 55%, #060608 100%);
|
||||
}
|
||||
.frame { width: 1280px; height: 720px; padding: 34px 42px; position: relative; }
|
||||
.topbar { height: 48px; display: flex; align-items: center; gap: 13px; }
|
||||
.mark {
|
||||
width: 34px; height: 34px; display: grid; place-items: center; border-radius: 8px;
|
||||
border: 1px solid rgba(168,151,255,.42); background: rgba(139,124,255,.15);
|
||||
color: #d9d0ff; font: 700 13px ui-monospace, monospace;
|
||||
}
|
||||
.brand { font-weight: 650; font-size: 15px; letter-spacing: -.01em; }
|
||||
.tag { margin-left: auto; color: #898590; font: 12px ui-monospace, monospace; }
|
||||
.workspace {
|
||||
height: 590px; margin-top: 14px; display: grid; grid-template-columns: 350px 1fr;
|
||||
overflow: hidden; border: 1px solid #29262e; border-radius: 17px;
|
||||
background: rgba(8,8,11,.94); box-shadow: 0 38px 90px rgba(0,0,0,.46);
|
||||
}
|
||||
.assistant { border-right: 1px solid #29262e; padding: 24px 22px; position: relative; }
|
||||
.eyebrow { color: #807a87; font: 700 10px ui-monospace, monospace; letter-spacing: .15em; }
|
||||
.prompt {
|
||||
margin-top: 18px; padding: 16px; border: 1px solid #302d36; border-radius: 12px;
|
||||
background: #111014; font-size: 17px; line-height: 1.45; letter-spacing: -.015em;
|
||||
}
|
||||
.cursor { display: inline-block; width: 2px; height: 18px; margin-left: 2px; vertical-align: -3px; background: #b5a7ff; }
|
||||
.tools { margin-top: 24px; display: grid; gap: 9px; }
|
||||
.tool {
|
||||
display: flex; align-items: center; gap: 10px; padding: 11px 12px; border-radius: 9px;
|
||||
color: #8d8992; font: 12px ui-monospace, monospace; border: 1px solid transparent;
|
||||
opacity: .32; transform: translateY(8px);
|
||||
}
|
||||
.tool.active { color: #eeeaff; border-color: rgba(139,124,255,.3); background: rgba(139,124,255,.09); }
|
||||
.dot { width: 6px; height: 6px; border-radius: 50%; background: #756b82; }
|
||||
.tool.done .dot { background: #52d49a; box-shadow: 0 0 14px rgba(82,212,154,.5); }
|
||||
.result {
|
||||
position: absolute; left: 22px; right: 22px; bottom: 24px; padding: 13px 14px;
|
||||
display: flex; align-items: center; gap: 10px; border-radius: 10px;
|
||||
border: 1px solid rgba(82,212,154,.25); background: rgba(82,212,154,.07);
|
||||
color: #bdf4d7; font-size: 12px; opacity: 0; transform: translateY(8px);
|
||||
}
|
||||
.editor { display: grid; grid-template-rows: 340px 1fr; min-width: 0; }
|
||||
.monitor { position: relative; overflow: hidden; border-bottom: 1px solid #29262e; }
|
||||
.monitor::after {
|
||||
content: ""; position: absolute; inset: 0;
|
||||
background: linear-gradient(115deg, transparent 28%, rgba(255,255,255,.035) 50%, transparent 72%);
|
||||
}
|
||||
.scene { position: absolute; inset: 0; display: grid; place-items: center; background: #111016; }
|
||||
.scene-grid {
|
||||
position: absolute; inset: 0; opacity: .22;
|
||||
background-image: linear-gradient(rgba(255,255,255,.06) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.06) 1px, transparent 1px);
|
||||
background-size: 48px 48px;
|
||||
}
|
||||
.subject {
|
||||
width: 270px; height: 180px; border-radius: 36px 36px 14px 14px; position: relative;
|
||||
background: linear-gradient(145deg, #6f668b, #302b41 68%);
|
||||
box-shadow: 0 34px 70px rgba(0,0,0,.45); transform: scale(.92);
|
||||
}
|
||||
.subject::before {
|
||||
content: ""; position: absolute; width: 76px; height: 76px; border-radius: 50%;
|
||||
left: 97px; top: -50px; background: linear-gradient(145deg, #afa7c7, #5d566f);
|
||||
}
|
||||
.subject::after {
|
||||
content: ""; position: absolute; width: 140px; height: 18px; border-radius: 50%;
|
||||
left: 65px; bottom: -36px; background: rgba(0,0,0,.46); filter: blur(12px);
|
||||
}
|
||||
.grade { position: absolute; inset: 0; background: radial-gradient(circle at 50% 48%, rgba(242,135,194,.14), rgba(95,69,180,.18) 44%, transparent 72%); opacity: 0; }
|
||||
.lower-third {
|
||||
position: absolute; left: 44px; bottom: 34px; padding: 13px 20px 14px;
|
||||
border-left: 3px solid #aa9cff; background: rgba(8,8,12,.78); backdrop-filter: blur(8px);
|
||||
transform: translateX(-28px); opacity: 0;
|
||||
}
|
||||
.lower-third b { display: block; font-size: 18px; letter-spacing: -.02em; }
|
||||
.lower-third span { display: block; margin-top: 3px; color: #a6a1ac; font-size: 11px; }
|
||||
.monitor-label { position: absolute; top: 16px; left: 18px; color: #74707b; font: 10px ui-monospace, monospace; letter-spacing: .12em; }
|
||||
.timeline { position: relative; padding: 14px 18px 18px; background: #09090c; }
|
||||
.ruler { height: 24px; margin-left: 56px; display: flex; justify-content: space-between; color: #625e68; font: 9px ui-monospace, monospace; }
|
||||
.tracks { display: grid; gap: 8px; }
|
||||
.track { height: 52px; display: grid; grid-template-columns: 48px 1fr; gap: 8px; }
|
||||
.track-name { display: flex; align-items: center; color: #77727e; font: 10px ui-monospace, monospace; }
|
||||
.lane { position: relative; border-radius: 5px; background: #121116; overflow: hidden; }
|
||||
.clip {
|
||||
position: absolute; top: 5px; bottom: 5px; border-radius: 5px; padding: 9px 11px;
|
||||
overflow: hidden; white-space: nowrap; font: 10px ui-monospace, monospace;
|
||||
}
|
||||
.clip-a { left: 0; width: 36%; color: #d9d1ff; background: #41356c; border: 1px solid #6e5aac; }
|
||||
.clip-b { left: 37%; width: 29%; color: #d7f4ff; background: #214a60; border: 1px solid #31728f; }
|
||||
.clip-c { left: 67%; width: 33%; color: #ffd5eb; background: #603149; border: 1px solid #98496e; }
|
||||
.clip-v2 { left: 18%; width: 0; color: #e8dcff; background: #50347b; border: 1px solid #875ec5; opacity: 0; }
|
||||
.wave { inset: 15px 0 0; position: absolute; opacity: .48; background: repeating-linear-gradient(90deg, transparent 0 3px, rgba(104,221,179,.65) 3px 4px); clip-path: polygon(0 48%, 3% 32%, 6% 65%, 9% 40%, 12% 58%, 15% 25%, 18% 72%, 22% 37%, 26% 62%, 30% 45%, 34% 55%, 38% 28%, 42% 74%, 46% 39%, 50% 61%, 54% 31%, 58% 70%, 62% 43%, 66% 58%, 70% 35%, 74% 66%, 78% 40%, 82% 59%, 86% 27%, 90% 72%, 94% 38%, 100% 52%, 100% 58%, 0 58%); }
|
||||
.playhead { position: absolute; top: 35px; bottom: 15px; left: 74px; width: 1px; background: #ef77b8; z-index: 5; }
|
||||
.playhead::before { content: ""; position: absolute; left: -4px; top: -4px; width: 9px; height: 8px; border-radius: 2px 2px 5px 5px; background: #ef77b8; }
|
||||
.caption {
|
||||
position: absolute; right: 26px; top: 21px; z-index: 3; padding: 7px 10px;
|
||||
border: 1px solid rgba(255,255,255,.12); border-radius: 99px; background: rgba(0,0,0,.46);
|
||||
color: #aaa5af; font: 10px ui-monospace, monospace;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="frame">
|
||||
<div class="topbar">
|
||||
<div class="mark">Pr</div>
|
||||
<div class="brand">premiere-pro-mcp</div>
|
||||
<div class="tag">LOCAL BRIDGE · 285 TOOLS</div>
|
||||
</div>
|
||||
<div class="workspace">
|
||||
<aside class="assistant">
|
||||
<div class="eyebrow">AI EDIT REQUEST</div>
|
||||
<div class="prompt"><span id="typed"></span><span class="cursor" id="cursor"></span></div>
|
||||
<div class="tools">
|
||||
<div class="tool" id="tool1"><span class="dot"></span>insert_clip · V2</div>
|
||||
<div class="tool" id="tool2"><span class="dot"></span>apply_lumetri</div>
|
||||
<div class="tool" id="tool3"><span class="dot"></span>create_text_layer</div>
|
||||
<div class="tool" id="tool4"><span class="dot"></span>export_sequence</div>
|
||||
</div>
|
||||
<div class="result" id="result"><span>✓</span> Edit complete · ProRes queued</div>
|
||||
</aside>
|
||||
<section class="editor">
|
||||
<div class="monitor">
|
||||
<div class="scene"><div class="scene-grid"></div><div class="subject" id="subject"></div><div class="grade" id="grade"></div></div>
|
||||
<div class="monitor-label">PROGRAM · BRAND FILM</div>
|
||||
<div class="caption" id="caption">00:00:00:00</div>
|
||||
<div class="lower-third" id="lower"><b>Build at the speed of thought.</b><span>Edited with MCP for Adobe Premiere Pro</span></div>
|
||||
</div>
|
||||
<div class="timeline">
|
||||
<div class="ruler"><span>00:00</span><span>00:03</span><span>00:06</span><span>00:09</span><span>00:12</span></div>
|
||||
<div class="tracks">
|
||||
<div class="track"><div class="track-name">V2</div><div class="lane"><div class="clip clip-v2" id="broll">B-ROLL · city-night.mov</div></div></div>
|
||||
<div class="track"><div class="track-name">V1</div><div class="lane"><div class="clip clip-a">A001 · interview</div><div class="clip clip-b">A002 · detail</div><div class="clip clip-c">A003 · close</div></div></div>
|
||||
<div class="track"><div class="track-name">A1</div><div class="lane"><div class="wave"></div></div></div>
|
||||
</div>
|
||||
<div class="playhead" id="playhead"></div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const params = new URLSearchParams(location.search);
|
||||
const frame = Number(params.get("frame") || 0);
|
||||
const total = Number(params.get("total") || 120);
|
||||
const p = Math.max(0, Math.min(1, frame / (total - 1)));
|
||||
const clamp = (v, a, b) => Math.max(0, Math.min(1, (v - a) / (b - a)));
|
||||
const ease = (v) => 1 - Math.pow(1 - v, 3);
|
||||
const prompt = "Add B-roll to V2, match the grade, add a lower third, then export ProRes.";
|
||||
const typedP = ease(clamp(p, .03, .25));
|
||||
document.querySelector("#typed").textContent = prompt.slice(0, Math.floor(prompt.length * typedP));
|
||||
document.querySelector("#cursor").style.opacity = p < .28 && frame % 10 < 6 ? 1 : 0;
|
||||
const starts = [.28, .42, .57, .72];
|
||||
starts.forEach((start, i) => {
|
||||
const el = document.querySelector(`#tool${i + 1}`);
|
||||
const reveal = ease(clamp(p, start - .03, start + .03));
|
||||
el.style.opacity = .32 + reveal * .68;
|
||||
el.style.transform = `translateY(${8 * (1 - reveal)}px)`;
|
||||
if (p >= start) el.classList.add("active");
|
||||
if (p >= start + .1) el.classList.add("done");
|
||||
});
|
||||
const brollP = ease(clamp(p, .29, .42));
|
||||
const broll = document.querySelector("#broll");
|
||||
broll.style.width = `${31 * brollP}%`;
|
||||
broll.style.opacity = brollP;
|
||||
const gradeP = ease(clamp(p, .43, .56));
|
||||
document.querySelector("#grade").style.opacity = gradeP;
|
||||
document.querySelector("#subject").style.transform = `scale(${.92 + .045 * gradeP})`;
|
||||
const lowerP = ease(clamp(p, .58, .68));
|
||||
const lower = document.querySelector("#lower");
|
||||
lower.style.opacity = lowerP;
|
||||
lower.style.transform = `translateX(${-28 * (1 - lowerP)}px)`;
|
||||
const resultP = ease(clamp(p, .82, .9));
|
||||
const result = document.querySelector("#result");
|
||||
result.style.opacity = resultP;
|
||||
result.style.transform = `translateY(${8 * (1 - resultP)}px)`;
|
||||
document.querySelector("#playhead").style.left = `${74 + 742 * p}px`;
|
||||
const seconds = Math.floor(p * 12);
|
||||
const frames = Math.floor((p * 12 - seconds) * 24);
|
||||
document.querySelector("#caption").textContent = `00:00:${String(seconds).padStart(2,"0")}:${String(frames).padStart(2,"0")}`;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||