Introduction and some background

Claude subscriptions are attractive for coding agents, but using them with a third-party CLI tool is not straightforward. Anthropic’s subscription OAuth credentials are meant for Claude Code and the claude.ai website, not as generic API credentials. By April 2026, unsupported third-party tools like OpenClaw had to use separately billed extra usage or the normal Claude API instead.[1][2] This is less helpful when your workflow lives in Kilo Code or OpenCode and you want to keep its agents, modes, permissions, and integrations.

The economics help explain the restriction. Agentic workloads repeatedly read files, call tools, and carry long contexts without waiting for a person, so their API-list-price equivalent can be much higher than a fixed subscription price. That is not the same as Anthropic’s actual infrastructure cost, but it makes a future separation between interactive and programmatic usage likely.[3][4]

Anthropic announced that separation in May 2026. From 15 June 2026, the Claude Agent SDK, claude -p, GitHub Actions, and third-party Agent SDK applications were supposed to consume a separate monthly credit. When this day of the supposed rollout came, Anthropic paused the change before it took effect however.[5] As of now (24 June 2026), token usage via the Claude Agent SDK is captured via your normal subscription quota. This does not authorise copying a Claude Code OAuth token into an unrelated client; it applies to applications using the SDK’s documented subscription-backed authentication flow.

Meridian uses the Claude Agent SDK under the hood. You can think of the Claude Agent SDK as being the engine of Claude Code, just freestanding. Meridian exposes that engine through an Anthropic Messages endpoint, allowing Kilo Code or OpenCode to use it like a regular model provider.[6]

This tutorial runs Meridian on a remote server, separate from Kilo Code or OpenCode. For a single user, running everything on the same machine through localhost is simpler and avoids the reverse proxy, TLS, and firewall. So use these steps as a guide, not a rigid recipe.

1) Basic preparations

I will use an Ubuntu server and run the commands as the root user in the following steps. If you prefer an unprivileged user, add sudo where administrative privileges are required and adapt the home directory, installation paths, and systemd service user accordingly. Meridian can run on the same machine as your coding tool, but a small dedicated server is convenient when several workstations should use the same endpoint. We will bind Meridian to 127.0.0.1:3456, so it cannot be reached directly from the network; instead, we will route through a reverse proxy later on.

Meridian requires a recent Node.js installation. First check whether Node.js and npm are already installed:

node --version
npm --version

If both commands work and Node.js is version 22 or newer, you can skip the rest of this section. Installing Node.js again is not necessary.

Otherwise, install Node.js 24 through nvm. Run these commands as the same Linux user that will later run Meridian:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.6/install.sh | bash
\. "$HOME/.nvm/nvm.sh"
nvm install 24

nvm installs Node.js below the current user’s home directory. This matters later because systemd does not load your interactive shell and therefore does not know about nvm by itself.

Verify the installation before continuing:

node --version
npm --version

2) Installing Meridian

2.1) Basic setup

Meridian needs both its own package and Anthropic’s Claude Code package. Recent npm versions restrict install scripts for selected dependencies, so allow the scripts for both scoped packages and then install them globally:

npm config set allow-scripts=@rynfar/meridian,@anthropic-ai/claude-code --location=user
npm install --global @rynfar/meridian @anthropic-ai/claude-code

The package names have to be supplied as one comma-separated value. Running the npm config set command twice would replace the first value with the second one. You can also pass the same list through npm‘s --allow-scripts option during installation.[7]

After this is done, authenticate Claude Code:

claude login
claude auth status

Complete the login in your browser. We only need the authentication state here, so do not define a workspace when Claude asks for one; quit the onboarding flow at that point. The login must belong to the same Linux user that will run the systemd service, because the credentials are stored in that user’s home directory.

2.2) Finding the installed paths

The correct ExecStart value depends on how Node.js and Meridian were installed. Probe for the actual paths:

which node
which meridian
dirname "$(which node)"

Keep the output. The complete output of which meridian becomes ExecStart, while the output of the dirname command goes at the beginning of the service’s PATH. With nvm, both paths normally contain the installed Node.js version. A system-wide Node.js installation will produce different paths, which is perfectly fine.

2.3) Running Meridian as a systemd service

Create the systemd service:

nano /etc/systemd/system/meridian.service
[Unit]
Description=Meridian Proxy
After=network.target

[Service]
Environment=MERIDIAN_HOST=127.0.0.1
Environment=MERIDIAN_PORT=3456
Environment=MERIDIAN_API_KEY=x
Environment=PATH=/root/.nvm/versions/node/v24.18.0/bin:/usr/bin:/bin
ExecStart=/root/.nvm/versions/node/v24.18.0/bin/meridian
Restart=on-failure
RestartSec=3

[Install]
WantedBy=default.target

This is a finished example for Node.js 24.18.0 installed through nvm for the root user. Replace x with the API key you want Kilo Code or OpenCode to use (or not if you actually want to use x). If which node and which meridian returned different locations, replace the Node.js directory in PATH and the complete ExecStart path with those results. systemd requires literal absolute paths and will not evaluate which, shell substitutions, or nvm commands inside the unit. For a non-root deployment, use that account’s home directory and installation paths, and make sure it is the same account that ran claude login.

Reload systemd, start Meridian, and enable it for future boots:

systemctl daemon-reload
systemctl enable meridian
systemctl status meridian

If the service does not start, inspect its journal:

journalctl -u meridian -n 100 --no-pager

The most common causes are an incorrect ExecStart, a PATH that does not contain Node.js, or a service user different from the one that completed claude login.

Finally, test the authenticated endpoint locally. Replace the placeholder with the value configured for MERIDIAN_API_KEY in the systemd service:

curl --fail --silent --show-error \
    -H "Authorization: Bearer YOUR_MERIDIAN_API_KEY" \
    http://127.0.0.1:3456/v1/models

You should receive a JSON list of the models Meridian currently exposes. Use that list instead of relying on model names copied from an older article, because the available aliases can change with Meridian and Claude.

3) Deploy an nginx reverse proxy

3.1) Configuring nginx

If Meridian and your coding tool run on the same machine, keep using 127.0.0.1:3456 and skip this section. For access from another workstation, we will place nginx in front of Meridian. The resulting request path is:

Kilo Code or OpenCode
    |
    | HTTPS
    v
meridian.example.com (nginx)
    |
    | HTTP on loopback
    v
127.0.0.1:3456 (Meridian)

This example assumes that meridian.example.com points to the server and that you already have a TLS certificate and private key for that name. The hostname and certificate paths below are dummy values; replace them with your own. For an internal service, a private certificate authority or a Let’s Encrypt DNS challenge are both valid options.

Install nginx and open its default site:

apt-get install nginx

echo '' > /etc/nginx/sites-available/default
nano /etc/nginx/sites-available/defaultt

Replace the file with the following configuration:

server {
    listen 80;
    listen [::]:80;
    rewrite ^(.*) https://$host$1 permanent;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name meridian.example.com;
    client_max_body_size 0;

    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    location / {
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_request_buffering off;

        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
        send_timeout 86400s;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_pass http://127.0.0.1:3456;
    }
}

The first server block redirects plain HTTP to HTTPS. The second terminates TLS and forwards requests to Meridian on the loopback interface. proxy_buffering off is important because model output is streamed back while it is generated. The long timeouts allow an agentic task to run for hours without nginx closing an otherwise healthy connection.

client_max_body_size 0 disables nginx‘s request-size limit, matching the setup used for long or multimodal LLM requests. On an Internet-facing service, a finite body limit and shorter timeouts are safer. Meridian’s API key is authentication, but it is not rate limiting or protection against a leaked key.

Validate the configuration before loading it. This catches wrong certificate paths and nginx syntax errors without taking the existing server down:

nginx -t
systemctl reload nginx

3.2) Configuring the firewall

Now install UFW, deny unsolicited incoming traffic, and allow nginx. If you administer the machine over SSH, allow OpenSSH before enabling the firewall or you may lock yourself out:

apt-get install ufw

ufw default deny incoming
ufw default allow outgoing
ufw allow OpenSSH
ufw allow 'Nginx Full'

ufw enable
ufw status verbose

Do not add a rule for port 3456. Meridian remains private on the loopback interface; only nginx should be reachable from the network. If this is a cloud server, apply the same restriction to its provider-level firewall or security group.

3.3) Testing the endpoint

Query the model list through nginx first:

curl --fail --silent --show-error \
    -H "x-api-key: YOUR_MERIDIAN_API_KEY" \
    https://meridian.example.com/v1/models

Then select one of the returned model IDs and send a streaming Anthropic Messages request. The model ID below is only an example:

curl --fail --no-buffer \
    https://meridian.example.com/v1/messages \
    -H "x-api-key: YOUR_MERIDIAN_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "Content-Type: application/json" \
    -d '{
        "model": "claude-sonnet-5",
        "max_tokens": 256,
        "stream": true,
        "messages": [
            {
                "role": "user",
                "content": "Reply with a short status message."
            }
        ]
    }'

If this works, authentication, Claude, Meridian, nginx, DNS, and TLS are all connected correctly. Debug a failed request from the inside out: check journalctl -u meridian, repeat the request against 127.0.0.1:3456, and only then inspect nginx.

4) Setting up Kilo Code and OpenCode

Both clients can use Meridian through its Anthropic Messages endpoint. Their setup is slightly different, however: Kilo Code uses a custom provider, while OpenCode uses its built-in Anthropic provider together with Meridian’s OpenCode plugin.

4.1) Setting up Kilo Code

Open Kilo Code’s settings, switch to Providers, and add a Custom provider.[8] Fill in the first fields as follows:

  • Provider ID: meridian. The ID may contain lowercase letters, numbers, hyphens, and underscores.
  • Display name: Meridian
  • Provider API: Anthropic Messages
  • Base URL: https://meridian.example.com/v1
  • API key: the value configured as MERIDIAN_API_KEY in the systemd service. With the example from this article, that value is x.

Next, add the models you want to make available in Kilo Code. Anthropic custom providers do not fetch their model list automatically, so enter each model manually. For example:

  • ID: claude-sonnet-5
  • Name: Claude Sonnet 5
  • Reasoning: enabled
  • Image: enabled

Use one of the model IDs returned by the /v1/models request from the previous section. The model names available through Meridian can change, so do not assume that the example above will remain current indefinitely. Enable Reasoning and Image for Claude models that support these capabilities.

The Headers section is optional. Leave it empty when MERIDIAN_API_KEY is the only authentication layer. If your nginx reverse proxy requires a separate Bearer token, add Authorization as the header name and Bearer YOUR_REVERSE_PROXY_TOKEN as its value. Kilo Code will then send the Meridian key through Anthropic’s x-api-key header and the separate proxy credential through Authorization.

Press Submit, then select the newly added Meridian model in Kilo Code’s model picker. The /v1 suffix in the Base URL is intentional: the Anthropic Messages provider appends /messages, resulting in a request to Meridian’s /v1/messages endpoint.

4.2) Setting up OpenCode

OpenCode should use its built-in anthropic provider and the Anthropic Messages API.[9] Meridian also supplies an OpenCode plugin for session tracking, safe model defaults, and subagent model selection. Run the setup command once on the workstation where OpenCode is installed:

meridian setup

If the meridian command is only installed on the proxy server, install the Meridian package on the OpenCode workstation as well. The workstation does not need its own Claude login or Meridian service; the package is only needed there to install and load the plugin:

npm install --global @rynfar/meridian --allow-scripts=@rynfar/meridian
meridian setup

The setup command adds Meridian’s plugin to OpenCode’s global configuration at ~/.config/opencode/opencode.json. Do not remove the plugin entry afterwards.

ANTHROPIC_API_KEY=x \
    ANTHROPIC_BASE_URL=https://meridian.example.com \
    opencode

Replace x with the value of MERIDIAN_API_KEY when you changed it in the systemd service. Unlike Kilo Code’s custom-provider field, ANTHROPIC_BASE_URL points to the host root without /v1; OpenCode’s Anthropic provider appends /v1/messages itself.

You can export both variables in your shell profile instead of supplying them for every launch:

export ANTHROPIC_API_KEY=x
export ANTHROPIC_BASE_URL=https://meridian.example.com

After OpenCode starts, use /models and select a model from the anthropic provider, for example anthropic/claude-sonnet-5. Keeping the provider ID as anthropic is important because Meridian’s OpenCode plugin attaches its session and agent metadata to that provider.

If the nginx proxy requires an additional Authorization header, add it under provider.anthropic.options.headers in the existing OpenCode configuration. Merge the following provider block into the file created by meridian setup; do not overwrite or remove its existing plugin entry:

{
    "$schema": "https://opencode.ai/config.json",
    "provider": {
        "anthropic": {
            "options": {
                "baseURL": "https://meridian.example.com",
                "apiKey": "{env:MERIDIAN_API_KEY}",
                "headers": {
                    "Authorization": "Bearer {env:MERIDIAN_PROXY_TOKEN}"
                }
            }
        }
    },
    "model": "anthropic/claude-sonnet-5"
}

Set MERIDIAN_API_KEY to the Meridian key and MERIDIAN_PROXY_TOKEN to the separate token expected by the reverse proxy. If the proxy has no additional authentication layer, omit the headers object and the second variable.

5) Inspecting telemetry

Meridian exposes telemetry endpoints that are useful when a client appears to hang or consumes more quota than expected. For example:

curl --fail --silent --show-error \
    -H "Authorization: Bearer YOUR_MERIDIAN_API_KEY" \
    https://meridian.example.com/telemetry/summary

The dashboard is available below https://meridian.example.com/telemetry. It exposes operational data and uses the same powerful API key as inference, so keep it on a private network or access it through an SSH tunnel rather than publishing it broadly.

6) Wrapping up

That is the basic workflow. Claude Code provides the subscription login, Meridian translates Anthropic Messages requests into Claude Agent SDK calls, systemd keeps the proxy running, and nginx optionally adds a stable TLS endpoint for other machines.

Kilo Code and OpenCode now access Claude through an Anthropic provider while token usage is still accounted against the normal Claude subscription quota. Keep an eye on Anthropic’s Agent SDK billing documentation, though. The June change was paused rather than permanently cancelled, and a future version of this setup may require separate usage credits or regular API billing.

Sources

  1. The Register: Anthropic closes door on third-party subscription use
  2. Mike Codeur: Claude Max third-party harness and extra credit offer
  3. Collective Brain: Claude-Agenten und Billing im Juni 2026
  4. Cost Botzone: The AI pricing subsidy is ending
  5. Anthropic Help Center: Use the Claude Agent SDK with your Claude plan
  6. Meridian source code and documentation
  7. npm documentation: allow-scripts
  8. Kilo Code source code and documentation
  9. OpenCode source code and documentation
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like