使用说明
Solana人工智能注册
Solana区块链上用于自主AI代理和模型上下文协议(MCP)服务器的全面链上注册系统。
🚀 在Devnet上直播
代理注册表: BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr | 探索者
MCP服务器注册表: BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX5CrXQ2sR2SR | 探索者
🌟 概述
Solana AI注册表协议为发现、验证和与自主AI代理和模型上下文协议(MCP)服务器交互提供了必要的基础设施。该实现由两个相互连接的链上注册表组成:
- 代理注册表:遵循自主经济代理(AEA)和代理到代理(A2A)范式的自主代理去中心化目录
- MCP服务器注册表:一个符合模型上下文协议的服务器目录,可以发现人工智能工具、资源和提示
🏗️ 建筑
核心设计原则
- 混合存储模型:链上的基本数据,带验证哈希的链下详细元数据
- 事件驱动架构:用于链下索引和查询的综合事件
- 协议遵从:符合A2A、AEA和MCP规范
- 安全第一:所有权验证和全面的输入验证
- 可扩展性:专为高通量发现和交互而设计
主要特点
- ✅ 100%协议合规性 符合A2A、AEA和MCP规范
- ✅ 混合数据模型 实现经济高效的存储和丰富的元数据
- ✅ 全面验证 以安全为重点的输入净化
- ✅ 事件排放 用于强大的链下索引功能
- ✅ 基于所有者的访问控制 通过加密验证
- ✅ 100%测试覆盖率 具有全面的边缘情况测试
🚀 快速开始
先决条件
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install Solana CLI
curl --proto '=https' --tlsv1.2 -sSfL https://solana-install.solana.workers.dev | bash
# Set up Solana for local development
solana config set --url localhost
solana-test-validator
建筑
# Clone the repository
git clone https://github.com/openSVM/aeamcp.git
cd aeamcp
# Build all programs
./scripts/build.sh
# Or build manually
cargo build --all
cargo test --all
测试
# Run comprehensive test suite
cargo test --all
# Run specific registry tests
cargo test agent_registry_tests
cargo test mcp_server_registry_tests
# Run with verbose output
cargo test -- --nocapture
📋 项目结构
aeamcp/
├── programs/
│ ├── common/ # Shared utilities and types
│ ├── agent-registry/ # Agent Registry program
│ └── mcp-server-registry/ # MCP Server Registry program
├── tests/ # Integration tests
├── scripts/ # Build and deployment scripts
├── docs/ # Protocol documentation
└── README.md # This file
🔧 使用示例
代理注册表
注册代理
use solana_ai_registries_common::*;
use agent_registry::instruction::AgentRegistryInstruction;
// Create registration instruction
let instruction = AgentRegistryInstruction::RegisterAgent {
agent_id: "my-trading-agent".to_string(),
name: "Advanced Trading Agent".to_string(),
description: "AI agent for automated trading strategies".to_string(),
agent_version: "1.0.0".to_string(),
provider_name: Some("TradingCorp".to_string()),
provider_url: Some("https://tradingcorp.com".to_string()),
documentation_url: Some("https://docs.tradingcorp.com/agent".to_string()),
service_endpoints: vec![
ServiceEndpointInput {
protocol: "a2a_http_jsonrpc".to_string(),
url: "https://api.tradingcorp.com/agent".to_string(),
is_default: true,
}
],
capabilities_flags: 0x01, // Streaming support
supported_input_modes: vec!["application/json".to_string()],
supported_output_modes: vec!["application/json".to_string()],
skills: vec![
AgentSkillInput {
id: "market-analysis".to_string(),
name: "Market Analysis".to_string(),
description_hash: Some([0u8; 32]), // Hash of detailed description
tags: vec!["trading".to_string(), "analysis".to_string()],
}
],
security_info_uri: Some("https://tradingcorp.com/security".to_string()),
aea_address: None,
economic_intent_summary: Some("Maximize trading profits".to_string()),
supported_aea_protocols_hash: None,
extended_metadata_uri: Some("https://ipfs.io/ipfs/QmAgent...".to_string()),
tags: vec!["trading".to_string(), "defi".to_string()],
};
更新代理状态
let update_instruction = AgentRegistryInstruction::UpdateAgentStatus {
new_status: AgentStatus::Active as u8,
};
MCP服务器注册表
注册MCP服务器
use mcp_server_registry::instruction::McpServerRegistryInstruction;
let instruction = McpServerRegistryInstruction::RegisterMcpServer {
server_id: "financial-data-server".to_string(),
name: "Financial Data MCP Server".to_string(),
server_version: "2.1.0".to_string(),
service_endpoint: "https://api.findata.com/mcp".to_string(),
documentation_url: Some("https://docs.findata.com".to_string()),
server_capabilities_summary: Some("Real-time financial data and analysis tools".to_string()),
supports_resources: true,
supports_tools: true,
supports_prompts: false,
onchain_tool_definitions: vec![
McpToolDefinitionOnChainInput {
name: "get-stock-price".to_string(),
description_hash: [1u8; 32],
input_schema_hash: [2u8; 32],
output_schema_hash: [3u8; 32],
tags: vec!["stocks".to_string(), "price".to_string()],
}
],
onchain_resource_definitions: vec![
McpResourceDefinitionOnChainInput {
uri_pattern: "stock://symbol/*".to_string(),
description_hash: [4u8; 32],
tags: vec!["stocks".to_string()],
}
],
onchain_prompt_definitions: vec![],
full_capabilities_uri: Some("https://ipfs.io/ipfs/QmServer...".to_string()),
tags: vec!["finance".to_string(), "data".to_string()],
};
🔍 发现和查询
直接查找
// Derive PDA for direct agent lookup
let (agent_pda, _) = Pubkey::find_program_address(
&[AGENT_REGISTRY_PDA_SEED, "my-agent-id".as_bytes()],
&agent_registry::id(),
);
// Fetch agent data
let agent_data = client.get_account_data(&agent_pda)?;
let agent_entry = AgentRegistryEntryV1::try_from_slice(&agent_data)?;
基于事件的索引
// Listen for agent registration events
client.on_logs_subscribe(
RpcTransactionLogsFilter::Mentions(vec![agent_registry::id().to_string()]),
RpcTransactionLogsConfig {
commitment: Some(CommitmentConfig::confirmed()),
},
)?;
// Process events for off-chain indexing
for log in logs {
if log.contains("AgentRegistered") {
// Parse and index agent data
let event: AgentRegistered = parse_event(&log)?;
index_agent(event).await?;
}
}
🛡️ 安全功能
访问控制
- 业主权限:只有所有者可以修改注册表项
- 签名验证:所有修改都需要有效签名
- 基于PDA的安全:程序控制的帐户可防止未经授权的访问
输入验证
- 长度约束:根据最大长度验证所有字符串
- 格式验证:验证URL、ID和其他字段的格式是否正确
- 边界检查:根据限制检查数组长度和数值
数据完整性
- 哈希验证:使用链上哈希验证链下内容
- 不可变历史:保留注册时间戳和所有权记录
- 护租:防止收取租金的账户
📊 性能特征
帐户大小
- 代理注册表项:~2.5KB(针对免租进行了优化)
- MCP服务器注册表项:~2.2KB(针对免租进行了优化)
运营成本
- 注册:~0.02 SOL(免租金+交易费)
- 更新:~0.001 SOL(仅交易费)
- 查询:自由(只读操作)
可扩展性
- 吞吐量:仅受Solana网络容量限制(约65000 TPS)
- 存储:无限制输入(无全局状态限制)
- 索引:事件驱动的链下扩展
🧪 测试
测试覆盖率
- ✅ 100%指令覆盖率:所有程序指令都经过测试
- ✅ 边缘案例测试:边界条件和误差情况
- ✅ 安全性测试:授权和验证测试
- ✅ 集成测试:端到端工作流测试
运行测试
# Run all tests
cargo test --all
# Run with coverage
cargo test --all -- --test-threads=1
# Run specific test categories
cargo test validation_tests
cargo test authorization_tests
cargo test integration_tests
🚀 部署
地方发展
# Start local validator
solana-test-validator
# Deploy programs
./scripts/deploy-devnet.sh
Devnet部署
# Configure for devnet
solana config set --url devnet
# Deploy with verification
./scripts/deploy-devnet.sh
./scripts/verify.sh
🌐 实时开发网络部署
Solana AI注册表目前已部署并在Solana Devnet上运行:
程序地址
- 代理注册表:
BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr - MCP服务器注册表:
BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX5CrXQ2sR2SR
浏览器链接
查询示例
使用Solana CLI
# Configure for devnet
solana config set --url devnet
# Query Agent Registry program info
solana program show BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr
# Query MCP Server Registry program info
solana program show BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX5CrXQ2sR2SR
# List all agent accounts (requires custom RPC call)
solana account BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr --output json
# List all MCP server accounts (requires custom RPC call)
solana account BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX5CrXQ2sR2SR --output json
使用JavaScript/TypeScript
import { Connection, PublicKey } from '@solana/web3.js';
const connection = new Connection('https://api.devnet.solana.com');
// Program addresses
const AGENT_REGISTRY_PROGRAM_ID = new PublicKey('BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr');
const MCP_REGISTRY_PROGRAM_ID = new PublicKey('BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX5CrXQ2sR2SR');
// Query all agent accounts
async function getAllAgents() {
const accounts = await connection.getProgramAccounts(AGENT_REGISTRY_PROGRAM_ID);
return accounts.map(account => ({
pubkey: account.pubkey.toString(),
data: account.account.data,
owner: account.account.owner.toString()
}));
}
// Query all MCP server accounts
async function getAllMcpServers() {
const accounts = await connection.getProgramAccounts(MCP_REGISTRY_PROGRAM_ID);
return accounts.map(account => ({
pubkey: account.pubkey.toString(),
data: account.account.data,
owner: account.account.owner.toString()
}));
}
// Query specific agent by PDA
async function getAgentByOwner(ownerPubkey: PublicKey) {
const [agentPda] = PublicKey.findProgramAddressSync(
[Buffer.from("agent"), ownerPubkey.toBuffer()],
AGENT_REGISTRY_PROGRAM_ID
);
const accountInfo = await connection.getAccountInfo(agentPda);
return accountInfo;
}
// Query specific MCP server by PDA
async function getMcpServerByOwner(ownerPubkey: PublicKey) {
const [serverPda] = PublicKey.findProgramAddressSync(
[Buffer.from("mcp_server"), ownerPubkey.toBuffer()],
MCP_REGISTRY_PROGRAM_ID
);
const accountInfo = await connection.getAccountInfo(serverPda);
return accountInfo;
}
使用Python
from solana.rpc.api import Client
from solana.publickey import PublicKey
# Connect to devnet
client = Client("https://api.devnet.solana.com")
# Program addresses
AGENT_REGISTRY_PROGRAM_ID = PublicKey("BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr")
MCP_REGISTRY_PROGRAM_ID = PublicKey("BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX5CrXQ2sR2SR")
# Query all agent accounts
def get_all_agents():
response = client.get_program_accounts(AGENT_REGISTRY_PROGRAM_ID)
return response
# Query all MCP server accounts
def get_all_mcp_servers():
response = client.get_program_accounts(MCP_REGISTRY_PROGRAM_ID)
return response
# Query specific account
def get_account_info(pubkey_str):
pubkey = PublicKey(pubkey_str)
response = client.get_account_info(pubkey)
return response
使用Rust
use solana_client::rpc_client::RpcClient;
use solana_sdk::pubkey::Pubkey;
use std::str::FromStr;
// Connect to devnet
let rpc_client = RpcClient::new("https://api.devnet.solana.com");
// Program addresses
let agent_registry_program_id = Pubkey::from_str("BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr").unwrap();
let mcp_registry_program_id = Pubkey::from_str("BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX5CrXQ2sR2SR").unwrap();
// Query all agent accounts
let agent_accounts = rpc_client.get_program_accounts(&agent_registry_program_id)?;
// Query all MCP server accounts
let mcp_accounts = rpc_client.get_program_accounts(&mcp_registry_program_id)?;
// Query specific account
let account_info = rpc_client.get_account(&some_pubkey)?;
主网部署
# Configure for mainnet
solana config set --url mainnet-beta
# Deploy (requires security audit)
./scripts/deploy-mainnet.sh
📚 api参考
代理注册说明
RegisterAgent:创建新的代理条目UpdateAgentDetails:修改代理信息UpdateAgentStatus:更改代理操作状态DeregisterAgent:将代理标记为已注销
MCP服务器注册表说明
RegisterMcpServer:创建新的MCP服务器条目UpdateMcpServerDetails:修改服务器信息UpdateMcpServerStatus:更改服务器操作状态DeregisterMcpServer:将服务器标记为已注销
事件
代理注册表事件
AgentRegistered:新代理注册AgentUpdated:代理详细信息已修改AgentStatusChanged:代理状态已更新AgentDeregistered:代理已删除
MCP服务器注册表事件
McpServerRegistered:新服务器注册McpServerUpdated:服务器详细信息已修改McpServerStatusChanged:服务器状态已更新McpServerDeregistered:服务器已删除
🛠️ 发展
贡献
- 分叉存储库
- 创建要素分支:
git checkout -b feature/amazing-feature - 进行更改 通过全面测试
- 运行测试套件:
cargo test --all - 提交拉取请求 附有详细说明
代码规范
- 格式化:使用
cargo fmt用于一致的代码格式 - 掉毛:地址全部
cargo clippy警告 - 文档:包括全面的内联文档
- 测试:对新功能保持100%的测试覆盖率
开发工具
# Format code
cargo fmt --all
# Run linter
cargo clippy --all -- -D warnings
# Generate documentation
cargo doc --all --no-deps --open
# Security audit (requires cargo-audit)
cargo audit
🔮 路线图
第一阶段:生态系统工具(2024年第二季度)
- []Types/JavaScript SDK
- []Python SDK
- []用于注册表交互的CLI工具
- []用于浏览注册表的Web仪表板
第二阶段:高级功能(2024年第三季度)
- []链下索引器参考实现
- []用于复杂查询的GraphQL API
- []声誉和认证体系
- []跨链发现机制
第三阶段:企业功能(2024年第四季度)
- []高级分析和指标
- []企业管理工具
- []SLA监控和警报
- []专业支持服务
📄 许可证
此项目根据MIT许可证获得许可-请参阅 许可证 文件以获取详细信息。
🤝 社区
- GitHub: openSVM/aeamcp
- 文档: 协议规范
- 问题: GitHub问题
- 讨论: GitHub讨论
🙏 致谢
- 索拉纳基金会 强大的区块链基础设施
- 谷歌A2A团队 用于代理到代理协议规范
- Fetch.ai 自主经济主体框架
- Anthropic 用于模型上下文协议规范
- 开源社区 工具、库和灵感
📈 状态
当前状态: 🎉 核心实施完成
Solana AI注册表的实施已准备就绪,包括:
- ✅ 完全符合协议(A2A、AEA、MCP)
- ✅ 100%测试覆盖率
- ✅ 全面的安全验证
- ✅ 用于生态系统开发的事件驱动架构
- ✅ 优化的性能和可扩展性
为生态系统开发、客户端SDK创建和生产部署做好准备!
内置于❤️ Solana AI生态系统
