Skip to main content
This guide will walk you through the complete process of creating a simple, monetizable AI agent from scratch using Nevermined. We’ll build a basic Express.js server for our agent and use the Nevermined TypeScript SDK to handle payments.

1. Project Setup

First, let’s set up a new Node.js project.
# Create a new directory for your project
mkdir my-simple-agent
cd my-simple-agent

# Initialize a Node.js project
npm init -y

# Install necessary dependencies
npm install express dotenv @nevermined-io/payments
npm install --save-dev typescript @types/node @types/express ts-node nodemon

# Initialize TypeScript configuration
npx tsc --init
For a clean project structure, create a src directory for your source code.

2. Environment Configuration

Create a .env file in your project root to store your credentials and configuration. You’ll need an API key from the Nevermined App.
.env
# Nevermined API Key
NVM_API_KEY="your-nevermined-api-key"

# Your wallet address for receiving payments
BUILDER_ADDRESS="your-wallet-address"

# Environment: 'testing' for development, 'production' for live
ENVIRONMENT="testing"

# Server port
PORT=4000

3. Creating the Agent Server

Now, let’s create a basic Express.js server. This server will have a public /health endpoint and a protected /query endpoint for our AI service.
src/index.ts
import express from 'express';
import dotenv from 'dotenv';
import { Payments } from '@nevermined-io/payments';
import { authMiddleware } from './middleware';

// Load environment variables
dotenv.config();

// Initialize Express
const app = express();
app.use(express.json());

// Initialize Nevermined SDK
export const payments = Payments.getInstance({
  nvmApiKey: process.env.NVM_API_KEY!,
  environment: process.env.ENVIRONMENT as any || 'testing'
});

// Health check endpoint (public)
app.get('/health', (req, res) => {
  res.json({ status: 'ok' });
});

// Protected AI endpoint
app.post('/query', authMiddleware, (req, res) => {
  // Your AI logic goes here
  const result = { response: `Your AI processed: ${req.body.prompt}` };

  // TODO: Redeem credits after processing
  
  res.json(result);
});

// Start the server
const PORT = process.env.PORT || 4000;
app.listen(PORT, () => {
  console.log(`🚀 Agent server running at http://localhost:${PORT}`);
});
We’ve referenced a middleware for authentication, so let’s create that next.

4. Implementing Authentication Middleware

This middleware will protect our /query endpoint by validating every incoming request using the Nevermined SDK.
src/middleware.ts
import { Request, Response, NextFunction } from 'express';
import { payments } from './index';

export const authMiddleware = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { planId, agentId, subscriberAddress } = req.body;
    const signature = req.headers['x-nvm-query-signature'] as string;

    if (!planId || !agentId || !subscriberAddress || !signature) {
      return res.status(400).json({ error: 'Missing authentication parameters.' });
    }

    const isValid = await payments.isValidRequest(
      planId,
      agentId,
      subscriberAddress,
      signature
    );

    if (!isValid) {
      const paymentCard = await payments.getAgentPaymentCard(agentId);
      return res.status(402).json({ error: 'Payment required.', ...paymentCard });
    }
    
    // Attach details to request for later use
    (req as any).nevermined = { planId, agentId, subscriberAddress };
    next();
  } catch (error) {
    console.error(`Auth Error: ${(error as Error).message}`);
    return res.status(401).json({ error: 'Authentication failed.' });
  }
};

5. Registering the Agent on Nevermined

Your agent needs to be registered with Nevermined to be discoverable and monetizable. Let’s create a separate script for this.
src/register.ts
import dotenv from 'dotenv';
import { Payments, getERC20PriceConfig, getFixedCreditsConfig } from '@nevermined-io/payments';

dotenv.config();

async function registerSimpleAgent() {
  const payments = Payments.getInstance({
    nvmApiKey: process.env.NVM_API_KEY!,
    environment: process.env.ENVIRONMENT as any || 'testing'
  });

  const agentMetadata = {
    name: 'Simple AI Assistant',
    tags: ['simple', 'assistant'],
    dateCreated: new Date(),
    description: 'A basic but powerful AI assistant.'
  };

  const agentApi = {
    endpoints: [{ POST: `http://localhost:${process.env.PORT}/query` }],
    openEndpoints: [`http://localhost:${process.env.PORT}/health`]
  };

  // Plan: 5 USDC for 100 credits
  const priceConfig = getERC20PriceConfig(
    5_000_000n, // 5 USDC
    '0xYourTestUSDCAddress', // Replace with a testnet USDC address
    process.env.BUILDER_ADDRESS!
  );
  const creditsConfig = getFixedCreditsConfig(100n, 1n);

  const { agentId, planId } = await payments.registerAgentAndPlan(
    agentMetadata,
    agentApi,
    priceConfig,
    creditsConfig
  );

  console.log('🎉 Agent Registered Successfully!');
  console.log(`AGENT_ID=${agentId}`);
  console.log(`PLAN_ID=${planId}`);
  console.log('\nAdd these to your .env file to use in your application.');
}

registerSimpleAgent();
To run this, you’ll execute ts-node src/register.ts from your terminal.

6. Redeeming Credits

The final step in the backend is to redeem credits after successfully processing a request. Let’s update our /query endpoint.
src/index.ts (updated)
// ... (imports and setup)

app.post('/query', authMiddleware, async (req, res) => {
  const { planId } = (req as any).nevermined;
  
  // Your AI logic
  const result = { response: `Your AI processed: ${req.body.prompt}` };

  // Redeem 1 credit for the request
  try {
    await payments.redeemCredits(planId, 1n, {
      request: req.body,
      timestamp: new Date()
    });
  } catch (error) {
    console.error(`Credit redemption failed: ${(error as Error).message}`);
    // Decide if you still want to send the response or return an error
  }
  
  res.json(result);
});

// ... (server startup)

7. Running and Testing

Add scripts to your package.json to make running your agent easier.
package.json
"scripts": {
  "start": "node dist/index.js",
  "dev": "nodemon src/index.ts",
  "build": "tsc",
  "register-agent": "ts-node src/register.ts"
}
Now you can run npm run dev to start your agent server. Congratulations! You’ve built a simple, monetizable AI agent with Nevermined. You can now use the Quickstart guide for subscribers to test purchasing and accessing your new agent.