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
This commit is contained in:
João Henrique
2026-09-08 09:59:31 -04:00
commit b541f502ba
1507 changed files with 387650 additions and 0 deletions
+218
View File
@@ -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>
</>
)
}
+112
View File
@@ -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>
</>
)
}
+1024
View File
File diff suppressed because it is too large Load Diff
+159
View File
@@ -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&apos;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>
</>
)
}
+226
View File
@@ -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>
</>
)
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

+425
View File
@@ -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;
}
}
+139
View File
@@ -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>
);
}
+23
View File
@@ -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",
},
],
}
}
+114
View File
@@ -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>
)
}
+52
View File
@@ -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>
)
}
+230
View File
@@ -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 />
</>
)
}
+78
View File
@@ -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>
)
}
+35
View File
@@ -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",
}
}
+70
View File
@@ -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,
},
]
}