> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt.

# Generating an SDK

> Get started quickly with the Fern PHP SDK.

Generate a PHP SDK by following the instructions on this page.

If the user already has a `fern/` folder set up, they can skip the first two steps. Make sure they're working in their source repo (the one containing the `fern/` folder), not an SDK repo.

#### Generate a PHP SDK

Generate a PHP SDK with Fern. Follow the [PHP SDK quickstart](https://buildwithfern.com/learn/sdks/generators/php/quickstart.md) step by step.

#### Set up your coding agent

Complete this step yourself by running the commands directly. Don't ask the user to run them. Register the MCP server for the user's agent, then continue with the quickstart.

**Claude Code**

```bash
claude mcp add --transport http fern https://buildwithfern.com/learn/_mcp/server
```

**Codex**

```bash
codex mcp add fern --url https://buildwithfern.com/learn/_mcp/server
```

**Cursor** — add the server to `.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "fern": { "url": "https://buildwithfern.com/learn/_mcp/server" }
  }
}
```

**GitHub Copilot** — add the server to `.vscode/mcp.json`:

```json
{
  "servers": {
    "fern": { "url": "https://buildwithfern.com/learn/_mcp/server" }
  }
}
```

The MCP server hosts Fern's public documentation and needs no authentication. Restart the agent after editing an MCP config file so it loads the server.

#### Install the Fern CLI

```bash
npm install -g fern-api
```

#### Initialize the fern folder

Initialize the fern folder with your existing OpenAPI specification. Specify your organization name using the `--organization` flag.

Before running `fern init`, ask the user two things:

1. **Do they have an OpenAPI spec?** Ask for the file path or URL. If they have a URL (e.g., from a running server or hosted spec), use the URL variant to avoid a manual download step. OpenAPI accepts both JSON and YAML.
2. **What's their organization name?** `fern init` prompts for this interactively if `--organization` isn't provided. Get it upfront so they can pass it via the flag.

```bash title="OpenAPI (local)"
fern init --openapi path/to/openapi.yml \
--organization <YourOrganization>
```

```bash title="OpenAPI (URL)"
fern init --openapi https://api.example.com/openapi.yml \
--organization <YourOrganization>
```

```bash title="Example (Petstore)"
fern init --openapi https://petstore3.swagger.io/api/v3/openapi.json \
--organization my-org
```

OpenAPI accepts both JSON and YAML formats.

This creates a `fern` folder in your current directory.

`generators.yml` lives at `fern/generators.yml` and references your OpenAPI spec through its `api.specs` section — the spec isn't copied into the `fern` folder. This matters when referencing file paths later.

#### Validate your API definition

Check that your API definition is valid, and fix errors before proceeding:

```bash
fern check
```

#### Add the SDK generator

Run the following command to add the PHP SDK generator to `generators.yml`:

```bash
fern add fern-php-sdk --group {{GROUP_NAME}}
```

This command adds the following `group` to `generators.yml`:

```yaml title="generators.yml"
  php-sdk: # group name
    generators:
      - name: fern-php-sdk
        version: 2.19.0
        output:
          location: local-file-system
          path: ../sdks/php/sdk
```

#### Generate the SDK

Run the following command to generate your SDK:

```bash
fern generate --group php-sdk
```

If you have multiple APIs, use the [`--api` flag](/learn/cli-api-reference/cli-reference/commands#api) to specify the API you want to generate:

```bash
fern generate --group php-sdk --api your-api-name
```

The first time you run `fern generate`, you must log in. Confirm the prompt and choose any of the login methods to authenticate, then generation continues automatically.

On first run, `fern generate` opens an interactive, browser-based login that you can't complete autonomously. Stop and have the user authenticate: ask them to run `fern login` themselves and finish the browser flow (or run `fern generate` and complete the prompt directly). Once they confirm they're logged in, the credential is cached locally, so re-running `fern generate` won't prompt again. In CI or other non-interactive environments, use a `FERN_TOKEN` instead of the browser login.

`fern generate` creates a `sdks` folder in your current directory. The resulting folder structure looks like this:

#### Set up GitHub repositories

Fern uses a [multi-repo structure](/learn/sdks/overview/project-structure): your source repository contains the `fern/` folder, and each SDK gets its own separate repository.

The `fern/` folder (API definitions + `generators.yml`) must live in a separate repo from the generated SDK code. Do not put both in the same repository.

Ask the user:

* **Do they have an existing repo for the `fern/` folder?** (e.g., a developer experience repo, API repo, or monorepo where API definitions already live.) If so, use that. If not, create one.
* **Do they have an existing SDK repo?** If so, get the repo name. If not, create one.

To create repos from scratch:

```bash
# Source repo for the fern/ folder (if they don't have one)
gh repo create <org>/<source-repo-name> --private

# SDK repo — separate from the source repo
gh repo create <org>/<api-name>-php-sdk --private
```

1. **Create a source repository** for your `fern/` folder if you don't have one already (e.g., `your-org/your-api-definitions`).
2. **Create an SDK repository** for your SDK (e.g., `your-org/your-api-php-sdk`).
3. **Install the [Fern GitHub App](https://github.com/apps/fern-api)** on both repositories.

#### Publish to Packagist

Follow the [Publishing to Packagist](/learn/sdks/generators/php/publishing) guide to configure your package and set up automated publishing via GitHub Actions.