npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@elastic/mockopampserver

v0.5.0

Published

A mock OpAMP server, useful for dev and testing

Readme

@elastic/mockopampserver

A mock Open Agent Management Protocol (OpAMP, https://github.com/open-telemetry/opamp-spec) server for development and testing. The intent is that this is something useful to maintainers of OpAMP clients, especially for Elastic's Node.js OpAMP client (package @elastic/opamp-client-node).

Features:

  • It is a Node.js server (this may or may not be a feature to you :)
  • It supports the OpAMP HTTP transport.
  • Remote config (i.e. the OffersRemoteConfig server capability).
  • It logs the received AgentToServer and sent ServerToAgent protobuf messages in a somewhat readable format.
  • A way to use this in Node.js testing (see testMode: true and test* methods). See example usage in "packages/opamp-client-node/test/...".
  • "Bad mode": the MockOpAMPServer can be configured to be in one of a number of "bad modes" where it responds in an atypical way, to support testing error cases / failure modes. See badMode usages in "packages/opamp-client-node/test/client.test.js".

Limitations:

  • It only supports the HTTP transport of OpAMP, not the WebSocket Transport. (The spec says "Server implementations SHOULD accept both plain HTTP connections and WebSocket connections.")
  • Most of the optional server capabilities are not implemented: effective config, packages, connection settings, command, custom capabilities.

Usage

CLI usage with Docker

Releases of mockopampserver include published Docker images. You can start a server via:

docker run --rm -it -p 4320:4320 --name mockopampserver \
    ghcr.io/elastic/elastic-otel-node/mockopampserver:latest

CLI usage with npx

If you use npx, you can start a server via:

npx @elastic/mockopampserver

CLI usage from the repository

To build and use the server from this repository:

cd packages/mockopampserver
npm ci
npm start

Once the server is started, you can use it with an OpAMP client. For example:

cd ../packages/opamp-client-node
npm ci
npm run example

Or, if you don't have a particular OpAMP client to use, you can try sending a request via curl using the included simple AgentToServer protobuf file:

curl -si http://localhost:4320/v1/opamp -X POST \
    -H content-type:application/x-protobuf \
    --data-binary @./test/fixtures/AgentToServer.simple.bin \
    | ./scripts/ServerToAgent

(The ServerToAgent script will deserialize opamp.proto.ServerToAgent` binary content on stdin and dump a representation to stdout.)

Module usage

See the block comment for class MockOpAMPServer for docs on all config options.

Here is an example showing how MockOpAMPServer could be used in a JS test case:

const {MockOpAMPServer} = require('@elastic/mockopampserver');

test('some OpAMP client test', async (t) => {
    opampServer = new MockOpAMPServer({
        logLevel: 'warn', // use 'debug' for some debugging of the server
        hostname: '127.0.0.1',
        port: 0,
        testMode: true,
    });
    await opampServer.start();
    t.comment(`MockOpAMPServer started: ${opampServer.endpoint}`);

    // Reset test data in the OpAMP server for each test, if re-using the same
    // mock server for multiple tests.
    opampServer.testReset();

    // Use an OpAMP client with `opampServer.endpoint`.
    // ...

    // Get details of every request/response from the server's point of view.
    // Each entry can include the following fields:
    // - `req`: some fields from the incoming HTTP request
    // - `res`: some fields from the outgoing HTTP response
    // - `a2s`: the parsed AgentToServer protobuf object sent by the client
    // - `s2a`: the parsed ServerToAgent protobuf object sent by the server
    // - `err`: an Error instance, in some failure cases
    const reqs = opampServer.testGetRequests();
    // console.dir(reqs, {depth: 50});
});

An example "test request" object:

[
  {
    req: {
      method: 'POST',
      headers: {
        host: '127.0.0.1:51204',
        connection: 'keep-alive',
        'user-agent': '@elastic/opamp-client-node/0.1.0',
        'content-type': 'application/x-protobuf',
        'content-length': '39'
      }
    },
    res: {
      statusCode: 200,
      _header: 'HTTP/1.1 200 OK\r\n' +
        'Content-Type: application/x-protobuf\r\n' +
        'Content-Length: 20\r\n' +
        'Date: Tue, 27 May 2025 21:49:36 GMT\r\n' +
        'Connection: keep-alive\r\n' +
        'Keep-Alive: timeout=5\r\n' +
        '\r\n'
    },
    a2s: {
      '$typeName': 'opamp.proto.AgentToServer',
      instanceUid: Buffer(16) [Uint8Array] [
          1, 151,  19, 184, 240, 118,
        118, 159, 172,  57,  91,  52,
         29, 167,  17,  41
      ],
      sequenceNum: 1n,
      capabilities: 8193n,
      flags: 0n,
      agentDescription: {
        '$typeName': 'opamp.proto.AgentDescription',
        identifyingAttributes: [
          {
            '$typeName': 'opamp.proto.KeyValue',
            key: 'foo',
            value: {
              '$typeName': 'opamp.proto.AnyValue',
              value: { case: 'stringValue', value: 'bar' }
            }
          }
        ],
        nonIdentifyingAttributes: []
      }
    },
    s2a: {
      '$typeName': 'opamp.proto.ServerToAgent',
      instanceUid: Buffer(16) [Uint8Array] [
          1, 151,  19, 184, 240, 118,
        118, 159, 172,  57,  91,  52,
         29, 167,  17,  41
      ],
      flags: 0,
      capabilities: 3
    },
    err: undefined
  }
]

Remote config

Remote config is an important use case for OpAMP. Here is how it can be used with MockOpAMPServer.

The CLI supports a -F key=./some-file.json option. This will setup the mock server to offer that file as remote config to requesting clients/agents, resulting in a server response with:

      ...
      remoteConfig: {
        '$typeName': 'opamp.proto.AgentRemoteConfig',
        configHash: Uint8Array(32) [ ... ],
        config: {
          '$typeName': 'opamp.proto.AgentConfigMap',
          configMap: {
            'key': {                            // <--- given "key" is here
              '$typeName': 'opamp.proto.AgentConfigFile',
              body: Uint8Array(...) [ ... ],    // <--- content of ./some-file.json is here
              contentType: 'application/json'
            }
          }
        }
      }

To see an example:

# Run the server with config.
cd packages/mockopampserver
npm run example:remote-config

# Run the client.
cd packages/opamp-client-node
npm run example

The equivalent setup of the server in code is:

    const config = {foo: 42};
    const opampServer = new MockOpAMPServer({
        agentConfigMap: {
            configMap: {
                '': {
                    contentType: 'application/json',
                    body: Buffer.from(JSON.stringify(config), 'utf8'),
                },
            },
        },
        // ... other config options.
    });
    await opampServer.start();

Test mode API to live-update agent config

In addition to the agentConfigMap constructor option, the MockOpAMPServer supports a POST /api/agentConfigMap HTTP endpoint to update the Agent Config that the server will use. This endpoint is not part of the OpAMP spec. The endpoint is only enabled when testMode: true.

Here are some curl examples showing how to live-update the Agent Config offered by a running MockOpAMPServer

# Set `logging_level` for the "elastic" configMap key.
curl -i http://127.0.0.1:4320/api/agentConfigMap -F 'elastic={"logging_level":"debug"}'

# Set empty config for the "elastic" key.
curl -i http://127.0.0.1:4320/api/agentConfigMap -F 'elastic={}'

# Set the config to the contents of a local JSON file.
curl -i http://127.0.0.1:4320/api/agentConfigMap -F 'elastic=@./my-agent-config.json'

See SetAgentConfigMap in "lib/mockopampserver.js" for more examples.

mTLS example

This section shows how to use the mockopampserver and opamp-client-node for mTLS, where both client and server must have valid certs. In these examples we'll be using certificate data generated for the packages/opamp-client-node test suite.

Let's start the mockopampserver using CLI options to set TLS server options:

  • Custom CA certs (--cacert), a server certificate (--cert) and private key (--key). These option names match those from curl
  • Configure the TLS server to request client certificates from connecting clients (--request-client-cert).
cd packages/mockopampserver
npm ci
node lib/cli.js --cacert ../opamp-client-node/test/certs/ca.crt --cert ../opamp-client-node/test/certs/server.crt --key ../opamp-client-node/test/certs/server.key --request-client-cert

First, let's use curl as the client, as we did in a section above. The only differences are:

  • the server is now using HTTPS, and
  • we need to add the --cacert, --cert, and --key TLS options.
curl -v https://localhost:4320/v1/opamp -X POST \
    --cacert ../opamp-client-node/test/certs/ca.crt --cert ../opamp-client-node/test/certs/client.crt --key ../opamp-client-node/test/certs/client.key \
    -H content-type:application/x-protobuf \
    --data-binary @./test/fixtures/AgentToServer.simple.bin \
    | ./scripts/ServerToAgent

If that works you should see something like:

% curl -sv https://localhost:4320/v1/opamp -X POST \
    --cacert ../opamp-client-node/test/certs/ca.crt --cert ../opamp-client-node/test/certs/client.crt --key ../opamp-client-node/test/certs/client.key \
    -H content-type:application/x-protobuf \
    --data-binary @./test/fixtures/AgentToServer.simple.bin \
    | ./scripts/ServerToAgent
* Host localhost:4320 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:4320...
* Connected to localhost (::1) port 4320
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
} [314 bytes data]
*  CAfile: ../opamp-client-node/test/certs/ca.crt
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* (304) (IN), TLS handshake, Unknown (8):
{ [21 bytes data]
* (304) (IN), TLS handshake, Request CERT (13):   <-- This is the TLS server requesting the client provide a TLS cert.
{ [143 bytes data]
* (304) (IN), TLS handshake, Certificate (11):
{ [2849 bytes data]
* (304) (IN), TLS handshake, CERT verify (15):
{ [520 bytes data]
* (304) (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* (304) (OUT), TLS handshake, Certificate (11):
} [1415 bytes data]
* (304) (OUT), TLS handshake, CERT verify (15):
} [520 bytes data]
* (304) (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384 / [blank] / UNDEF
* ALPN: server accepted http/1.1
* Server certificate:
*  subject: C=CL; ST=RM; L=EDOTTest; O=Test; OU=Server; CN=localhost
*  start date: Nov  3 23:18:29 2025 GMT
*  expire date: Nov  3 23:18:29 2026 GMT
*  common name: localhost (matched)
*  issuer: C=CL; ST=RM; L=EDOTTest; O=Root; OU=Test; CN=ca
*  SSL certificate verify ok.
* using HTTP/1.x                                <-- The TLS connection has successfully been established.
> POST /v1/opamp HTTP/1.1
> Host: localhost:4320
> User-Agent: curl/8.7.1
> Accept: */*
> content-type:application/x-protobuf
> Content-Length: 18
>
} [18 bytes data]
* upload completely sent off: 18 bytes
< HTTP/1.1 200 OK
< Content-Type: application/x-protobuf
< Content-Length: 22
< Date: Tue, 04 Nov 2025 00:46:07 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
<
{ [22 bytes data]
* Connection #0 to host localhost left intact
{                                               <-- The decoded ServerToAgent message starts here.
  '$typeName': 'opamp.proto.ServerToAgent',
  instanceUid: Buffer(16) [Uint8Array] [
     84, 108,  42, 240,  68,
    144,  68, 201, 175, 144,
     55, 194,  38,  98, 130,
    102
  ],
  flags: 1n,
  capabilities: 3n
}

Second, we can use @elastic/opamp-client-node as the client. See the opamp-client-node example using mTLS.

cd packages/opamp-client-node
npm run examples:mTLS