{"id":2776,"date":"2026-08-12T11:15:00","date_gmt":"2026-08-12T11:15:00","guid":{"rendered":"https:\/\/dmarketertayeeb.com\/blog\/?p=2776"},"modified":"2026-08-11T16:50:26","modified_gmt":"2026-08-11T16:50:26","slug":"build-openai-agent-plugin-skills-mcp","status":"publish","type":"post","link":"https:\/\/dmarketertayeeb.com\/blog\/build-openai-agent-plugin-skills-mcp\/","title":{"rendered":"How to Build an OpenAI Agent Plugin with Skills and MCP"},"content":{"rendered":"\n\n\n<p>An <strong>OpenAI Agent Plugin<\/strong> is a package that can ship reusable Skills, an MCP server connection, both together, and optionally UI. The required entry point is <code>.codex-plugin\/plugin.json<\/code>. Skills describe repeatable workflows; MCP tools connect the agent to code or external systems through schemas and permissions. A plugin is the distribution boundary that gives those components a stable identity across ChatGPT and Codex surfaces that support them.<\/p>\n\n\n\n\n\n\n\n<p>This tutorial builds a small, reviewable package: a Skill turns approved evidence into a cited marketing brief, while a read-only local MCP server lists and reads evidence records. It includes a manifest check and a test. DMT\u2019s <a href=\"https:\/\/dmarketertayeeb.com\/blog\/openai-codex-marketers-plugins-sites-workflows\/\">Agent Plugins overview<\/a> owns the concepts and marketer use cases; this page owns the build, test, security and distribution workflow.<\/p>\n\n\n\n\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/developers.openai.com\/plugins\/concepts\/plugins\"><img loading=\"lazy\" decoding=\"async\" width=\"832\" height=\"121\" src=\"https:\/\/dmarketertayeeb.com\/blog\/wp-content\/uploads\/2026\/08\/openai-plugin-architecture-2026-08-11.png\" alt=\"OpenAI plugin architecture showing Skills, an MCP server and optional UI\" class=\"wp-image-2775\" srcset=\"https:\/\/dmarketertayeeb.com\/blog\/wp-content\/uploads\/2026\/08\/openai-plugin-architecture-2026-08-11.png 832w, https:\/\/dmarketertayeeb.com\/blog\/wp-content\/uploads\/2026\/08\/openai-plugin-architecture-2026-08-11-300x44.png 300w, https:\/\/dmarketertayeeb.com\/blog\/wp-content\/uploads\/2026\/08\/openai-plugin-architecture-2026-08-11-768x112.png 768w\" sizes=\"auto, (max-width: 832px) 100vw, 832px\" \/><\/a><figcaption class=\"wp-element-caption\">OpenAI\u2019s official Agent Plugin architecture: Skills, MCP server and optional UI. Source: OpenAI Developers; captured August 11, 2026.<\/figcaption><\/figure>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Choose the smallest plugin shape<\/h2>\n\n\n\n\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Shape<\/th><th>Use it when<\/th><th>Avoid it when<\/th><\/tr><\/thead><tbody><tr><td>Skills only<\/td><td>The workflow can operate with existing agent tools and needs repeatable instructions, templates or scripts<\/td><td>You need a new external API\/tool capability<\/td><\/tr><tr><td>MCP only<\/td><td>You need typed tools or data access but no opinionated workflow<\/td><td>Users also need a consistent multi-step operating method<\/td><\/tr><tr><td>Skills + MCP<\/td><td>The workflow and the tools should travel together<\/td><td>The Skill would merely restate each tool description<\/td><\/tr><tr><td>MCP + UI<\/td><td>A visual interactive result materially helps and the MCP integration supports it<\/td><td>A table, file or ordinary text answer is enough<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n\n\n\n\n<p>OpenAI explicitly recommends starting with the smallest shape. Every added server, hook, permission and UI asset increases security review, maintenance and compatibility work.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">The example package<\/h2>\n\n\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>dmt-source-review\/\n\u251c\u2500\u2500 .codex-plugin\/\n\u2502   \u2514\u2500\u2500 plugin.json          # required manifest\n\u251c\u2500\u2500 skills\/\n\u2502   \u2514\u2500\u2500 source-review\/\n\u2502       \u2514\u2500\u2500 SKILL.md         # reusable workflow\n\u251c\u2500\u2500 server\/\n\u2502   \u2514\u2500\u2500 index.js             # local MCP stdio server\n\u251c\u2500\u2500 scripts\/\n\u2502   \u2514\u2500\u2500 check.mjs            # package validation\n\u251c\u2500\u2500 test\/\n\u2502   \u2514\u2500\u2500 package.test.js\n\u251c\u2500\u2500 .mcp.json                # bundled MCP server map\n\u2514\u2500\u2500 package.json<\/code><\/pre>\n\n\n\n<p>Only <code>plugin.json<\/code> belongs inside <code>.codex-plugin\/<\/code>. OpenAI\u2019s current path rules keep <code>skills\/<\/code>, <code>.mcp.json<\/code>, <code>.app.json<\/code>, <code>hooks\/<\/code> and <code>assets\/<\/code> at the plugin root. Manifest component paths should start with <code>.\/<\/code> and remain inside that root.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: create the plugin manifest<\/h2>\n\n\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"name\": \"dmt-source-review\",\n  \"version\": \"0.1.0\",\n  \"description\": \"Review an allowlisted evidence package and return a cited brief.\",\n  \"author\": {\n    \"name\": \"Digital Marketer Tayeeb\",\n    \"url\": \"https:\/\/dmarketertayeeb.com\"\n  },\n  \"license\": \"MIT\",\n  \"skills\": \".\/skills\/\",\n  \"mcpServers\": \".\/.mcp.json\",\n  \"interface\": {\n    \"displayName\": \"DMT Source Review\",\n    \"shortDescription\": \"Build an evidence-first marketing brief\",\n    \"developerName\": \"Digital Marketer Tayeeb\",\n    \"category\": \"Productivity\",\n    \"capabilities\": [\"Read\"],\n    \"defaultPrompt\": [\n      \"Use DMT Source Review to turn the approved evidence package into a cited brief.\"\n    ]\n  }\n}<\/code><\/pre>\n\n\n\n<p>The manifest identifies the package, points to components and controls install-surface metadata. Public plugins usually add a homepage, repository, privacy policy, terms, icons, screenshots and richer descriptions. Do not claim a write capability when the server is intentionally read-only.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: write a focused Skill<\/h2>\n\n\n\n\n\n\n\n<p>The Skill should explain when it applies, how to use available tools, what output is required and where it must stop. It should not hide credentials or duplicate an API manual.<\/p>\n\n\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>---\nname: source-review\ndescription: Use when an approved evidence package must become a cited marketing brief without adding unsupported claims or publishing it.\n---\n\n# Source review\n\n1. Call the evidence MCP server to list approved evidence records.\n2. Reject records without a canonical URL, source class, capture date and claim summary.\n3. Separate confirmed facts, vendor claims, DMT analysis and unknowns.\n4. Write a brief with the reader job, practical impact, risks and open questions.\n5. Put the supporting URL next to every material claim.\n6. Do not publish, message, upload, delete or change an external system.\n7. If evidence is incomplete, return BLOCKED instead of guessing.<\/code><\/pre>\n\n\n\n<p>Keep large schemas, examples and reference material in files the Skill can load only when needed. This progressive disclosure prevents every invocation from carrying irrelevant context.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: build the MCP server<\/h2>\n\n\n\n\n\n\n\n<p>The <a href=\"https:\/\/modelcontextprotocol.io\/specification\">Model Context Protocol<\/a> defines how hosts and servers exchange tools and structured results. The example uses the official TypeScript SDK and stdio transport. It exposes only two read tools: list JSON records and read one validated record.<\/p>\n\n\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>import { McpServer } from \"@modelcontextprotocol\/sdk\/server\/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol\/sdk\/server\/stdio.js\";\nimport { z } from \"zod\";\nimport { readFile, readdir } from \"node:fs\/promises\";\nimport { resolve, sep } from \"node:path\";\n\nconst root = resolve(process.env.DMT_EVIDENCE_ROOT || \".\/evidence\");\nconst server = new McpServer({ name: \"dmt-evidence\", version: \"0.1.0\" });\n\nfunction safePath(name) {\n  const candidate = resolve(root, name);\n  if (candidate !== root &amp;&amp; !candidate.startsWith(root + sep)) {\n    throw new Error(\"Path escapes the evidence root\");\n  }\n  return candidate;\n}\n\nserver.tool(\"list_evidence\", \"List JSON evidence records\", {}, async () =&gt; {\n  const names = (await readdir(root)).filter((n) =&gt; n.endsWith(\".json\"));\n  return { content: [{ type: \"text\", text: JSON.stringify(names) }] };\n});\n\nserver.tool(\n  \"read_evidence\",\n  \"Read one approved JSON evidence record\",\n  { name: z.string().regex(\/^[a-zA-Z0-9._-]+\\\\.json$\/) },\n  async ({ name }) =&gt; {\n    const text = await readFile(safePath(name), \"utf8\");\n    JSON.parse(text);\n    return { content: [{ type: \"text\", text }] };\n  }\n);\n\nawait server.connect(new StdioServerTransport());<\/code><\/pre>\n\n\n\n<p>The filename regex and resolved-path check are deliberate. Tool schemas improve model behaviour, but a server must still defend itself against path traversal, malformed JSON, oversized responses and untrusted content.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: wire the server into the package<\/h2>\n\n\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"evidence\": {\n    \"command\": \"node\",\n    \"args\": [\"${PLUGIN_ROOT}\/server\/index.js\"],\n    \"env\": {\n      \"DMT_EVIDENCE_ROOT\": \"${PLUGIN_DATA}\/evidence\"\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p><code>PLUGIN_ROOT<\/code> points to the installed package. <code>PLUGIN_DATA<\/code> is the writable data area. Keeping evidence under the data directory avoids modifying installed package files and gives the server one narrow root.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: validate and test<\/h2>\n\n\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>npm install\nnpm run check\nnpm test<\/code><\/pre>\n\n\n\n<p>The package check parses both JSON files, verifies required manifest fields, enforces root-relative component paths and confirms the expected MCP server. The test verifies that the manifest exposes the Skill, server and read-only capability. Add server tests for path escape, malformed JSON, missing directories and large records before using real evidence.<\/p>\n\n\n\n\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Test layer<\/th><th>Minimum test<\/th><\/tr><\/thead><tbody><tr><td>Manifest<\/td><td>Valid JSON; required identity; component paths stay inside package<\/td><\/tr><tr><td>Skill<\/td><td>Trigger is specific; output and stop conditions are explicit<\/td><\/tr><tr><td>Tool schema<\/td><td>Reject unexpected filenames and parameters<\/td><\/tr><tr><td>Server<\/td><td>Read allowed file; deny path escape; handle missing\/malformed input<\/td><\/tr><tr><td>Agent workflow<\/td><td>Normal, no-op, incomplete evidence and prompt-injection tests<\/td><\/tr><tr><td>Permissions<\/td><td>No write\/network tool appears unless intentionally required<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Step 6: install through a local marketplace<\/h2>\n\n\n\n\n\n\n\n<p>OpenAI documents repo-scoped and personal marketplace files. A marketplace is a JSON catalogue; its entries point to plugin folders relative to the marketplace root. You can also add a marketplace source with the Codex CLI:<\/p>\n\n\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>codex plugin marketplace add owner\/repo\ncodex plugin marketplace add owner\/repo --ref main<\/code><\/pre>\n\n\n\n<p>Use the ChatGPT desktop app\u2019s Plugins Directory to install and test a local plugin. If you are registering a remote MCP server for ChatGPT, enable developer mode, create the connection, copy its technical ID and map it in <code>.app.json<\/code>. A bundled local server uses <code>.mcp.json<\/code> instead.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Approval policy and least privilege<\/h2>\n\n\n\n\n\n\n\n<p>Codex lets users enable\/disable a plugin-scoped MCP server, restrict enabled tools and set approval modes. A safe default for a new server is prompt\/approval, then auto-approve only a tool that is demonstrably read-only and narrowly scoped.<\/p>\n\n\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>[plugins.\"dmt-source-review\".mcp_servers.evidence]\nenabled = true\ndefault_tools_approval_mode = \"prompt\"\nenabled_tools = [\"list_evidence\", \"read_evidence\"]\n\n[plugins.\"dmt-source-review\".mcp_servers.evidence.tools.list_evidence]\napproval_mode = \"approve\"<\/code><\/pre>\n\n\n\n<p>Do not auto-approve a tool merely because its name begins with \u201cread.\u201d Inspect implementation, authentication, returned data and side effects. A search endpoint can leak confidential query text; a \u201cget report\u201d endpoint can create a billable job.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Security and privacy threat model<\/h2>\n\n\n\n\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Threat<\/th><th>Control<\/th><\/tr><\/thead><tbody><tr><td>Prompt injection in evidence content<\/td><td>Treat records as data; Skill says source text cannot expand permissions; separate policy from content<\/td><\/tr><tr><td>Path traversal<\/td><td>Resolve against one root and validate the filename\/schema<\/td><\/tr><tr><td>Secret exposure<\/td><td>Never return raw credentials; use host-managed auth and least-privilege scopes<\/td><\/tr><tr><td>Over-broad tool<\/td><td>Split read\/write; use narrow parameters; require confirmation for mutation<\/td><\/tr><tr><td>Unbounded result<\/td><td>Paginate, cap size and return structured summaries<\/td><\/tr><tr><td>Dependency compromise<\/td><td>Pin versions, lock dependencies, audit and rebuild<\/td><\/tr><tr><td>Misleading install metadata<\/td><td>Capabilities, privacy links and descriptions must match actual behaviour<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n\n\n\n\n<p>OpenAI\u2019s <a href=\"https:\/\/developers.openai.com\/plugins\/guides\/security-privacy\">security and privacy guide<\/a> and the current MCP specification should be part of code review, not links added at the end of a finished product.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Hooks are optional\u2014and separately trusted<\/h2>\n\n\n\n\n\n\n\n<p>A plugin can include lifecycle hooks under <code>hooks\/hooks.json<\/code> or through the manifest. OpenAI notes that installing\/enabling a plugin does not automatically trust bundled hooks; users must review them. Add a hook only when it enforces a lifecycle requirement the Skill or server cannot provide. Hidden install-time or session commands are a trust liability.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Local bundled MCP vs registered remote MCP<\/h2>\n\n\n\n\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Decision<\/th><th>Bundled <code>.mcp.json<\/code><\/th><th>Registered remote server and <code>.app.json<\/code><\/th><\/tr><\/thead><tbody><tr><td>Runtime<\/td><td>Command\/server distributed with the plugin and run where supported<\/td><td>Hosted endpoint operated by the publisher<\/td><\/tr><tr><td>Authentication<\/td><td>Local environment\/configuration<\/td><td>Registered connection and remote auth flow<\/td><\/tr><tr><td>Best for<\/td><td>Local\/repository tools, offline\/private data and developer workflows<\/td><td>Shared SaaS data\/actions and centrally updated logic<\/td><\/tr><tr><td>Operational burden<\/td><td>Cross-platform dependencies and local process lifecycle<\/td><td>Hosting, uptime, tenancy, OAuth, privacy and incident response<\/td><\/tr><tr><td>Distribution mapping<\/td><td><code>mcpServers<\/code> points to <code>.\/.mcp.json<\/code><\/td><td>Compatibility <code>apps<\/code> points to <code>.\/.app.json<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n\n\n\n\n<p>Do not bundle a local server merely to avoid operating a proper remote service when the tool needs centralized customer data. Do not build a remote service merely to read a local repository. Choose the trust and deployment boundary that matches the data.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Versioning and compatibility<\/h2>\n\n\n\n\n\n\n\n<ul class=\"wp-block-list\"><li>Use semantic versions for package releases and record the tested ChatGPT\/Codex surface and date.<\/li><li>Make breaking tool-schema or Skill-output changes a major version unless the platform defines a different contract.<\/li><li>Keep migrations for data under <code>PLUGIN_DATA<\/code>; do not silently reinterpret old files.<\/li><li>Pin the MCP SDK and generate a lockfile. Re-run tests before updating.<\/li><li>Provide a changelog that calls out new permissions, network destinations and data use.<\/li><li>Fail with an actionable error when a surface does not support a bundled component; do not pretend the capability succeeded.<\/li><\/ul>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Example test receipt<\/h2>\n\n\n\n\n\n\n\n<p>The example package built for this article was checked on Windows with Node.js. <code>npm run check<\/code> parsed the manifest and MCP map and verified component paths. <code>npm test<\/code> ran one manifest contract test: one pass, zero failures. <code>npm audit<\/code> reported zero known vulnerabilities at install time. This is a package-structure receipt, not a security certification; production use still needs server edge-case and integration tests.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Prepare for public submission<\/h2>\n\n\n\n\n\n\n\n<ul class=\"wp-block-list\"><li>Use a stable name\/version and accurate capability descriptions.<\/li><li>Provide working homepage, support, privacy and terms URLs where required.<\/li><li>Test ChatGPT and Codex surfaces you claim to support.<\/li><li>Use production authentication and least-privilege scopes.<\/li><li>Provide test credentials\/instructions only through the approved review process.<\/li><li>Remove placeholder assets and example domains.<\/li><li>Review the current <a href=\"https:\/\/developers.openai.com\/plugins\/deploy\/submission\">submission documentation<\/a> and error reference immediately before submission.<\/li><\/ul>\n\n\n\n\n\n\n\n<p>Public plugins are published to the universal directory shared by ChatGPT and Codex, but capabilities can remain surface-specific. Do not promise that every hook, UI or local-server behaviour works identically everywhere.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Official examples worth studying<\/h2>\n\n\n\n\n\n\n\n<p>OpenAI\u2019s <a href=\"https:\/\/github.com\/openai\/plugins\">official plugins repository<\/a> includes public examples such as <a href=\"https:\/\/github.com\/openai\/plugins\/tree\/main\/plugins\/figma\">Figma<\/a>, <a href=\"https:\/\/github.com\/openai\/plugins\/tree\/main\/plugins\/notion\">Notion<\/a> and <a href=\"https:\/\/github.com\/openai\/plugins\/tree\/main\/plugins\/build-web-apps\">Build web apps<\/a>. Use them to inspect current package conventions, but keep your own permissions and reader job smaller than a mature integration unless complexity is justified.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Final build checklist<\/h2>\n\n\n\n\n\n\n\n<ul class=\"wp-block-list\"><li>The chosen plugin shape is the smallest that solves the job.<\/li><li><code>.codex-plugin\/plugin.json<\/code> is valid and component paths are root-relative.<\/li><li>The Skill has a specific trigger, output contract and stop conditions.<\/li><li>MCP tools have narrow schemas, bounded results and truthful side effects.<\/li><li>Read\/write capabilities and approval policies match implementation.<\/li><li>Normal, no-op, malformed, path-escape and prompt-injection tests pass.<\/li><li>Dependencies are pinned\/locked and secrets remain host-managed.<\/li><li>Local marketplace installation works in a clean environment.<\/li><li>Public metadata, rights, privacy and support information are complete.<\/li><li>The package was tested again against current OpenAI docs before distribution.<\/li><\/ul>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n\n\n\n<h3 class=\"wp-block-heading\">Does every Agent Plugin need an MCP server?<\/h3>\n\n\n\n\n\n\n<p>No. OpenAI supports Skills-only plugins. Add MCP only when the agent needs a typed tool or data capability that existing tools cannot provide.<\/p>\n\n\n\n\n\n\n<h3 class=\"wp-block-heading\">Is installing a plugin the same as trusting its hooks?<\/h3>\n\n\n\n\n\n\n<p>No. OpenAI documents plugin-bundled hooks as separately reviewed\/trusted. Inspect commands and paths before enabling them.<\/p>\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">How this example was verified<\/h2>\n\n\n\n\n\n\n<p>DMT built the package shown in this article and ran its manifest check and Node test on August 11, 2026: one test passed, none failed, and the install-time audit reported zero known vulnerabilities. The package is a minimal educational example, not a production security certification.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Bottom line<\/h2>\n\n\n\n\n\n\n\n<p>A good Agent Plugin is not a folder full of prompts. It has a narrow reader job, a truthful manifest, a reusable Skill, minimal typed tools, explicit approvals, defensive server code and a testable distribution path. Start Skills-only when possible. Add MCP when a real capability is missing. Add UI or hooks only when they materially improve the job and their trust cost is justified.<\/p>\n\n\n\n\n\n\n\n<p>Connect the package to a broader operating model with DMT\u2019s <a href=\"https:\/\/dmarketertayeeb.com\/blog\/ai-agent-harness-context-compaction\/\">agent-harness controls<\/a>, <a href=\"https:\/\/dmarketertayeeb.com\/blog\/luna-max-codex-subagents-sol-high\/\">accountable subagent workflow<\/a>, <a href=\"https:\/\/dmarketertayeeb.com\/blog\/gpt-5-6-luna-terra-sol-cost-per-accepted-result\/\">accepted-result measurement method<\/a> and <a href=\"https:\/\/dmarketertayeeb.com\/blog\/gpt-5-6-sol-terra-luna-marketers-guide\/\">GPT-5.6 model-routing guide<\/a>.<\/p>\n\n\n","protected":false},"excerpt":{"rendered":"<p>A complete OpenAI Agent Plugin build tutorial with a real package tree, Skill, read-only MCP server, manifest, tests, permissions and distribution path.<\/p>\n","protected":false},"author":1,"featured_media":2775,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[386],"tags":[410,409,315,400,408],"class_list":["post-2776","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai-for-marketers","tag-chatgpt-plugins","tag-codex-skills","tag-developer-tools","tag-mcp","tag-openai-agent-plugins","has-featured-image"],"_links":{"self":[{"href":"https:\/\/dmarketertayeeb.com\/blog\/wp-json\/wp\/v2\/posts\/2776","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dmarketertayeeb.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dmarketertayeeb.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dmarketertayeeb.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dmarketertayeeb.com\/blog\/wp-json\/wp\/v2\/comments?post=2776"}],"version-history":[{"count":2,"href":"https:\/\/dmarketertayeeb.com\/blog\/wp-json\/wp\/v2\/posts\/2776\/revisions"}],"predecessor-version":[{"id":2784,"href":"https:\/\/dmarketertayeeb.com\/blog\/wp-json\/wp\/v2\/posts\/2776\/revisions\/2784"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dmarketertayeeb.com\/blog\/wp-json\/wp\/v2\/media\/2775"}],"wp:attachment":[{"href":"https:\/\/dmarketertayeeb.com\/blog\/wp-json\/wp\/v2\/media?parent=2776"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dmarketertayeeb.com\/blog\/wp-json\/wp\/v2\/categories?post=2776"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dmarketertayeeb.com\/blog\/wp-json\/wp\/v2\/tags?post=2776"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}