How it works Examples Docs Pricing Blog WP Blocks Install free

Blog /

Five things Claude Code should know about your WordPress site

The agent-first workflow for DesignSetGo Apps is short. You scaffold a project with npx designsetgo apps init, you open it in Claude Code (or Cursor, or Aider, or any agent that reads files in the working directory), you describe what you want, and the agent deploys it to your WordPress site with npx designsetgo apps deploy. There is no copy-pasting code into wp-admin, no Gutenberg sidebar to remember, no “now switch to your terminal and run this command.” The agent runs the terminal.

The starter ships with a CLAUDE.md at the project root, which is the file Claude Code reads first on every session. That file is doing most of the work. But if you want to understand why the agent gets things right out of the box, or you want to brief a different agent that doesn’t auto-load CLAUDE.md, here are the five facts that matter most. Drop them into a system prompt, paste them into a session, or just internalize them yourself before you start describing what you want.

1. The app talks to WordPress through a bridge, not the REST API

The single most common mistake an agent makes when it sees “WordPress” in a prompt is to reach for fetch('/wp-json/wp/v2/posts'). That works in a logged-in admin context. It does not work in a DSGo App, because the app runs in a sandbox with no REST cookie and no API token.

Instead, the app imports @designsetgo/app-client and calls typed methods that go over postMessage to the WordPress side:

import { dsgo } from '@designsetgo/app-client';
await dsgo.ready;

const posts = await dsgo.posts.list({ per_page: 10 });
const me    = await dsgo.user.current();
const site  = await dsgo.site.info();

Every call is gated by what dsgo-app.json declares in permissions.read. If the manifest doesn’t list posts, the bridge rejects the call with permission_denied. If it does, the call returns and visibility honors the visitor’s WordPress capabilities automatically. The agent does not need to think about auth, REST nonces, or CORS, because none of those exist in this surface.

Brief for the agent: “Never call /wp-json from inside this app. Use @designsetgo/app-client and add the matching permission to dsgo-app.json before calling it.”

The bridge is intentionally boring. There is one capability map, and it lives in BRIDGE-API.md. When the agent wants to add “log the current user’s name to the page,” the right sequence is:

  1. Add "user" to permissions.read in dsgo-app.json.
  2. Call await dsgo.user.current() from the page script.

That’s it. No new dependency, no new server route, no new authentication step. If the agent wants to send email, it adds "email" to permissions.read plus an email block with allowed recipients, then calls dsgo.email.send({ to: 'admin', subject: '...', body: '...' }). Email goes through wp_mail(), so whatever SMTP plugin the site already uses handles delivery.

The full list, all gated by permissions, is in the starter’s CLAUDE.mdsite_infopostspagesuseraiabilitiescommerceemail. Plus storage (no permission, just call it), media uploads (gated by WordPress’s upload_files capability), and the built-in router for SPA-style apps.

Brief for the agent: “Before reaching for a third-party library, check whether there’s already a dsgo.* method for the thing. There usually is.”

3. The site’s AI keys are never in the bundle

WordPress 7.0 introduced a Connectors API. The site admin pastes their Anthropic, OpenAI, or Google credentials in Settings → Connectors once, and every plugin that wants to call an LLM inherits that configuration. DSGo Apps inherits it too.

So inside a DSGo App, the AI call looks like this:

const result = await dsgo.ai.prompt({
  messages: [{ role: 'user', content: 'Summarize this post' }],
  max_tokens: 800,
});

There is no API key in the bundle. There is no process.env.ANTHROPIC_API_KEY anywhere. The manifest declares an ai block (with max_tool_calls and timeout_seconds), the visitor’s request goes through the bridge, the WordPress side routes it through the site’s configured Connector, and the answer comes back. The plugin author never sees a key, the bundle never ships one, and switching the site from Anthropic to OpenAI is a setting change, not a redeploy.

If the agent has spent any time building “AI WordPress plugins” pre-7.0, this is the part that surprises it. Reassure it: yes, really, no keys in the code.

Brief for the agent: “For LLM calls, use dsgo.ai.prompt(). Do not add an SDK dependency. Do not look for environment variables.”

4. Each route is a real HTML page at a real URL

If the agent assumes it’s building a single-page app that takes over /apps/your-slug/ and renders everything client-side, it will build something that works, but it will leave search-engine traffic on the table. The starter is wired for inline isolation, which means each route in dsgo-app.json becomes a server-rendered HTML page at /apps/<id>/<path>, with a fresh CSP nonce stamped on every script tag at request time.

That changes the agent’s instincts in two useful ways. First, “add a pricing page” means adding a new entry to routes, a corresponding file under src/pages/, and a build step. The URL is real, the title is real, the meta description ships in the response, and Google indexes it normally. Second, dynamic routes like /posts/:slug can pull their dataset live from WordPress content via the dataset field, with built-in sources for wp:postswp:pageswp:cpt:<slug>, and wc:products. No bundled JSON, no rebuilds when an editor publishes a post.

If you actually want the iframe sandbox model (a tool, a widget, a calculator), the manifest opts in with isolation: "iframe" and the trade-offs flip the other way: full origin isolation, no SEO. Both modes exist on purpose. The starter picks inline because most apps want to be findable.

Brief for the agent: “This is multi-page by default. Each route is its own HTML file under src/pages/. Search engines see fully-rendered pages.”

5. Deployment is one command, and the agent runs it

The CLI is small enough to memorize:

npx designsetgo apps login mysite.com        # one-time auth
npx designsetgo apps deploy --build          # build + upload
npx designsetgo apps deploy --dry-run        # validate without uploading
npx designsetgo apps list                    # what's installed
npx designsetgo apps open                    # open in browser
npx designsetgo apps logs                    # plugin-level error log

apps deploy --build runs the build, validates the manifest, packs the bundle, and pushes it to the site over HTTPS. The agent should treat this as the iteration loop: edit, deploy, check the result, repeat. --dry-run is for sanity-checking a change without shipping it. --debug prints the request/response if something fails.

The two iteration constraints worth knowing. First, npm run dev runs Astro locally but the bridge has no host to talk to, so any feature that uses dsgo.* has to be tested against a real deploy. Second, deploys are atomic at the bundle level: if validation fails the old version stays live, so the agent can’t half-break the app by shipping a bad manifest.

Brief for the agent: “After every meaningful change, run npx designsetgo apps deploy --build and check npx designsetgo apps logs if it doesn’t behave the way you expected.”

Putting it together

If you start a new Claude Code session against a freshly scaffolded DSGo App, the agent has CLAUDE.md loaded automatically, so most of the above is already in context. The reason to internalize the five points anyway is that they’re the same five points you need when you’re briefing a colleague, paying for a freelance hour, or describing the product to someone who wants to know whether their existing AI workflow ports over.

The short version is: yes, it ports over. The agent already knows how to write HTML, CSS, TypeScript, and Astro. What it learns from DSGo Apps is that talking to WordPress is now a two-line manifest change, that the keys live in the site instead of the bundle, and that “deploy” is a command it can run itself.

Everything else is just building the thing.