A comprehensive demonstration platform showcasing communication with external AI agents through multiple transport protocols, built with React, TypeScript, and Express.
- Overview
- Technical Architecture
- Installation Guide
- Project Modules
- Agent Communication
- External Resources
This project demonstrates a multi-agent communication platform that enables users to interact with external AI agents through different transport protocols. It serves as a comprehensive example of how to integrate Nevermined's payment system with various AI agent architectures.
The platform acts as a proxy and orchestration layer between frontend applications and external AI agents, handling:
- Authentication and authorization using Nevermined's payment system
- Credit management with blockchain-based transactions
- Agent communication via HTTP REST and MCP (Model Context Protocol)
- Intent synthesis using OpenAI's LLM services
- Response processing and user experience optimization
- Demonstration: Showcase Nevermined's agent ecosystem capabilities
- Integration Reference: Provide implementation patterns for agent communication
- Development Platform: Enable rapid prototyping of agent-based applications
- Payment Integration: Demonstrate blockchain-based credit systems for AI services
The external agents used in this demo are available in the Nevermined Tutorials repository, which contains comprehensive examples of how to build and integrate AI agents with Nevermined Payments:
- Financial Agent - HTTP REST agent for financial advice
- Weather MCP Agent - MCP agent for weather information
- Frontend: React 19, TypeScript, Vite, Tailwind CSS
- Backend: Node.js, Express, TypeScript
- Monorepo: Yarn Workspaces
- Agent Protocols: HTTP REST, MCP (Model Context Protocol)
- AI Services: OpenAI GPT-4
- Payment System: Nevermined Payments SDK
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β Frontend β β Backend β β External β
β (React) βββββΊβ (Express) βββββΊβ Agents β
β β β β β β
β β’ HTTP Client β β β’ API Routes β β β’ HTTP Agent β
β β’ MCP Client β β β’ Auth Service β β β’ MCP Agent β
β β’ UI Components β β β’ Payment Logic β β β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β
βΌ
ββββββββββββββββββββ
β External β
β Services β
β β
β β’ OpenAI API β
β β’ Nevermined β
β β’ Blockchain β
ββββββββββββββββββββ
- Node.js: Version 20 or higher
- Yarn: Version 1.22.22 (auto-configured via Corepack)
git clone <repository-url>
cd demo-ui-monorepo# Install all workspace dependencies
yarn installCreate a .env file in the project root:
OPENAI_API_KEY=your_openai_api_key_here
RPC_URL=https://base-sepolia.gateway.tenderly.co
NVM_ENVIRONMENT=sandbox
HTTP_AGENT_ID=did:nv:f82254a93e8486e102031b6567c2d734f21a71ca793358b1a07d03eb409a546a
HTTP_AGENT_ENDPOINT=http://localhost:3001/ask
MCP_AGENT_ID=did:nv:3fe43029c257aad4694ad037e4ceae5360d7f2061c7982117bf8da9c20614000
MCP_AGENT_ENDPOINT=http://localhost:3002/mcp# Build all packages and applications
yarn build# Start with default demo app
yarn dev
# Start with HTTP agent app
yarn serve:app:http
# Start with MCP agent app
yarn serve:app:mcp- Main Application: http://localhost:3000
- HTTP Agent App: http://localhost:3000/simple-agent/
- MCP Agent App: http://localhost:3000/mcp-agent/
# Build for production
yarn build
# Start production server
yarn start# Build Docker image
docker build -t demo-ui-monorepo .
# Run container
docker run -p 3000:3000 \
-e OPENAI_API_KEY=your_key \
-e RPC_URL=your_rpc_url \
... \
demo-ui-monorepo- Purpose: Landing page and application selector
- Technology: React + Vite
- Features: Navigation between different agent types
- Purpose: HTTP agent communication interface
- Technology: React + TypeScript
- Features: Financial advisor chat interface
- Purpose: MCP agent communication interface
- Technology: React + TypeScript
- Features: Weather agent with tool-based interactions
- Purpose: Main Express server and application orchestrator
- Technology: Node.js + Express + TypeScript
- Features: Static file serving, Vite middleware, route management
- Purpose: API endpoints and business logic
- Technology: Express + TypeScript
- Features: Agent communication, payment processing, LLM services
- Purpose: HTTP agent client implementation
- Technology: TypeScript
- Features: HTTP REST communication with external agents
- Purpose: MCP agent client implementation
- Technology: TypeScript + MCP SDK
- Features: Model Context Protocol communication
- Purpose: Shared UI components and utilities
- Technology: React + TypeScript + Tailwind
- Features: Reusable components, state management, API clients
- Purpose: Configuration management
- Technology: TypeScript
- Features: Environment variables, agent configurations
- Purpose: Type definitions and interfaces
- Technology: TypeScript
- Features: Shared types across the application
- Purpose: Nevermined payments integration
- Technology: TypeScript + Nevermined SDK
- Features: Credit management, payment processing
The platform implements a multi-layered communication architecture that abstracts different agent protocols behind a unified interface.
- Frontend Applications: User interface and interaction layer
- Backend Express Server: Orchestration and proxy layer
- External Agents: AI services running on different protocols
- Nevermined Payment System: Blockchain-based credit management
- OpenAI Services: LLM for intent synthesis and routing
Protocol: HTTP REST API Agent Type: Financial Advisor Capabilities: Conversational tasks, financial analysis
Flow:
User Input β Frontend β Backend β OpenAI (Intent Synthesis) β HTTP Agent β Response
Implementation:
- Uses standard HTTP POST requests
- Bearer token authentication
- JSON payload with
input_queryfield - Direct response from agent
Protocol: Model Context Protocol Agent Type: Weather Agent Capabilities: Tool-based interactions, structured responses
Flow:
User Input β Frontend β Backend β OpenAI (Tool Selection) β MCP Client β MCP Agent β Response
Implementation:
- Uses MCP SDK for protocol communication
- Tool discovery and execution
- Structured response parsing
- Connection management
// Frontend stores user credentials
const apiKey = localStorage.getItem("nvmApiKey");
const planId = localStorage.getItem("nvmPlanId_http"); // or _mcp
// If no credentials, redirect to Stripe checkout
if (!apiKey || !planId) {
const checkoutUrl = buildNeverminedCheckoutUrl(agentId, {
returnApiKey: true,
returnUrl: window.location.href
});
window.location.href = checkoutUrl;
}// After Stripe checkout, extract credentials from URL
useEffect(() => {
const parsedKey = extractApiKeyFromUrl(true);
if (parsedKey) {
setWithTTL("nvmApiKey", parsedKey);
setApiKey(parsedKey);
console.log("π Extracted API Key from URL:", parsedKey);
}
const parsedPlan = extractPlanIdFromUrl(true);
if (parsedPlan) {
setStoredPlanId(parsedPlan);
setPlanId(parsedPlan);
}
}, []);// Frontend sends request to backend
const response = await fetch("/api/agent", {
method: "POST",
headers: {
"Authorization": `Bearer ${apiKey}`,
"X-Plan-Id": planId,
"X-Agent-Mode": transport // "http" or "mcp"
},
body: JSON.stringify({ input_query: userMessage })
});// Backend validates credentials and determines agent type
const nvmApiKey = req.headers.authorization.replace("Bearer ", "");
const planId = req.headers["x-plan-id"];
const mode = req.headers["x-agent-mode"]; // "http" or "mcp"
// Load agent configuration
const agentConfig = loadAgentConfig(mode);// For HTTP agents: Synthesize user intent into clear instruction
const intent = await llmIntentSynthesizer(
history,
agentPrompt, // Agent-specific prompt
undefined // No tools for HTTP
);
// For MCP agents: Select appropriate tool and arguments
const toolCall = await llmIntentSynthesizer(
history,
agentPrompt,
toolsCatalog // Available MCP tools
);
// Returns: { tool: "weather.today", args: { city: "Madrid" } }// Get agent-specific access token from Nevermined
const { accessToken } = await getAgentAccessToken(
nvmApiKey,
planId,
agentId,
environment
);HTTP Agent:
const response = await fetch(agentEndpoint, {
method: "POST",
headers: {
"Authorization": `Bearer ${accessToken}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ input_query: intent })
});MCP Agent:
const transport = new StreamableHTTPClientTransport(new URL(endpoint), {
requestInit: { headers: { Authorization: `Bearer ${accessToken}` } }
});
const client = new McpClient({ name: "weather-mcp-client", version: "0.1.0" });
await client.connect(transport);
const result = await client.callTool({
name: toolCall.tool,
arguments: toolCall.args
});The platform integrates deeply with Nevermined's payment system for blockchain-based credit management with Stripe checkout integration:
// Check user credits before processing requests
const credits = await getUserCredits(nvmApiKey, planId);
const needsApiKey = !apiKey;
const insufficientCredits = credits !== null && credits <= 0;
if (needsApiKey || insufficientCredits) {
// Redirect to Stripe checkout via Nevermined
const checkoutUrl = buildNeverminedCheckoutUrl(agentId, {
returnApiKey: needsApiKey,
returnUrl: window.location.href
});
window.location.href = checkoutUrl;
}The platform uses Nevermined's Stripe-powered checkout for seamless credit purchases:
Checkout URL Structure:
https://nevermined.app/checkout/{agentId}?export=nvm-api-key&returnUrl={returnUrl}
Parameters:
agentId: The Nevermined agent identifierexport=nvm-api-key: Requests API key to be returned after purchasereturnUrl: Where to redirect after successful payment
Test Card for Development:
- Card Number:
4242 4242 4242 4242 - Expiry: Any future date
- CVC: Any 3-digit number
After successful Stripe payment, users are redirected back with credentials in URL parameters:
// Extract API key from URL after checkout return
const parsedKey = extractApiKeyFromUrl(true);
if (parsedKey) {
setWithTTL("nvmApiKey", parsedKey);
setApiKey(parsedKey);
console.log("π Extracted API Key from URL:", parsedKey);
}
// Extract Plan ID from URL after checkout return
const parsedPlan = extractPlanIdFromUrl(true);
if (parsedPlan) {
setStoredPlanId(parsedPlan);
setPlanId(parsedPlan);
}// Generate agent-specific access tokens using purchased credentials
const payments = initializePayments(nvmApiKey, environment);
const agentAccessParams = await payments.agents.getAgentAccessToken(
planId,
agentId
);// Credits are automatically consumed when agents respond
// The response includes redemption information
{
"output": "Agent response...",
"redemptionResult": {
"txHash": "0x123...",
"creditsRedeemed": 1
}
}// Monitor blockchain events for credit transactions
const mintEvent = await findMintEvent(
contractAddress,
walletAddress,
tokenId,
fromBlock
);Step-by-Step Process:
- User Interaction: User sends message requiring agent service
- Credit Check: System verifies if user has API key and sufficient credits
- Checkout Redirect: If missing, redirect to Nevermined Stripe checkout
- Stripe Payment: User completes payment with credit card
- Credential Return: Nevermined redirects back with API key and plan ID in URL
- Credential Storage: System extracts and stores credentials in localStorage
- Service Provision: Agent service is provided using purchased credits
- Credit Consumption: Credits are automatically deducted per usage
- User Authentication: Nevermined API keys
- Agent Authentication: Agent-specific access tokens
- Credit Verification: Blockchain-based validation
- Request Validation: Input sanitization and type checking
- User API Keys: Stored in localStorage with TTL
- Agent Access Tokens: Generated per request, not stored
- Plan IDs: Transport-specific namespacing
- Environment Isolation: Sandbox vs Production
- Agent Unavailable: Fallback to error messages
- Credit Insufficient: Prompt for credit purchase
- Network Issues: Retry mechanisms and timeouts
- Invalid Responses: Default error handling
- Request Tracking: Full request/response logging
- Error Reporting: Detailed error information
- Performance Metrics: Response time monitoring
- Credit Usage: Transaction tracking
- HTTP Agent Repository - Financial Advisor Agent
- MCP Agent Repository - Weather Agent
Apache License 2.0
(C) 2025 Nevermined AG
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
