返回市场
企业级MCP服务器

企业级MCP服务器

作者:openSVM10 星标更新:2025-11-05

项目介绍

Solana AI 注册表

在 Solana 区块链上为自主 AI 代理和模型上下文协议(MCP)服务器提供全面的链上注册系统。

构建状态 测试覆盖率 许可证 Solana

🚀 在开发网运行

代理注册表: BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr | 浏览器 MCP 服务器注册表: BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX5CrXQ2sR2SR | 浏览器

🌟 概览

Solana AI 注册表协议提供了发现、验证和与自主 AI 代理及模型上下文协议(MCP)服务器交互的基本基础设施。此实现包括两个相互连接的链上注册表:

  1. 代理注册表: 遵循自主经济代理(AEA)和代理到代理(A2A)范式的去中心化目录
  2. MCP 服务器注册表: 符合 MCP 协议的服务器目录,使 AI 工具、资源和提示的发现成为可能

🏗️ 架构

核心设计原则

  • 混合存储模型: 关键数据在链上,详细元数据在链下并带有验证哈希
  • 事件驱动架构: 全面的事件用于链下索引和查询
  • 协议合规性: 与 A2A、AEA 和 MCP 规范一致
  • 安全第一: 所有权验证和全面的输入验证
  • 可扩展性: 设计用于高吞吐量的发现和交互

主要功能

  • 100% 协议合规性与 A2A、AEA 和 MCP 规范一致
  • 混合数据模型以节省成本并丰富元数据
  • 全面验证以安全为中心的输入清理
  • 事件发射以强大的链下索引能力
  • 基于所有者的访问控制带有加密验证
  • 100% 测试覆盖率包含全面的边界情况测试

🚀 快速开始

前提条件

# 安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 安装 Solana CLI
curl --proto '=https' --tlsv1.2 -sSfL https://solana-install.solana.workers.dev | bash

# 设置本地开发环境
solana config set --url localhost
solana-test-validator

构建

# 克隆仓库
git clone https://github.com/openSVM/aeamcp.git
cd aeamcp

# 构建所有程序
./scripts/build.sh

# 或手动构建
cargo build --all
cargo test --all

测试

# 运行全面测试套件
cargo test --all

# 运行特定注册表测试
cargo test agent_registry_tests
cargo test mcp_server_registry_tests

# 使用详细输出运行
cargo test -- --nocapture

📋 项目结构

aeamcp/
├── programs/
│   ├── common/                    # 共享工具和类型
│   ├── agent-registry/            # 代理注册表程序
│   └── mcp-server-registry/       # MCP 服务器注册表程序
├── tests/                         # 集成测试
├── scripts/                       # 构建和部署脚本
├── docs/                          # 协议文档
└── README.md                      # 此文件

🔧 使用示例

代理注册表

注册一个代理

use solana_ai_registries_common::*;
use agent_registry::instruction::AgentRegistryInstruction;

// 创建注册指令
let instruction = AgentRegistryInstruction::RegisterAgent {
    agent_id: "my-trading-agent".to_string(),
    name: "高级交易代理".to_string(),
    description: "自动化交易策略的 AI 代理".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, // 支持流式传输
    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: "市场分析".to_string(),
            description_hash: Some([0u8; 32]), // 详细描述的哈希
            tags: vec!["交易".to_string(), "分析".to_string()],
        }
    ],
    security_info_uri: Some("https://tradingcorp.com/security".to_string()),
    aea_address: None,
    economic_intent_summary: Some("最大化交易利润".to_string()),
    supported_aea_protocols_hash: None,
    extended_metadata_uri: Some("https://ipfs.io/ipfs/QmAgent...".to_string()),
    tags: vec!["交易".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: "金融数据服务器".to_string(),
    name: "金融数据 MCP 服务器".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("实时金融数据和分析工具".to_string()),
    supports_resources: true,
    supports_tools: true,
    supports_prompts: false,
    onchain_tool_definitions: vec![
        McpToolDefinitionOnChainInput {
            name: "获取股票价格".to_string(),
            description_hash: [1u8; 32],
            input_schema_hash: [2u8; 32],
            output_schema_hash: [3u8; 32],
            tags: vec!["股票".to_string(), "价格".to_string()],
        }
    ],
    onchain_resource_definitions: vec![
        McpResourceDefinitionOnChainInput {
            uri_pattern: "股票://符号/*".to_string(),
            description_hash: [4u8; 32],
            tags: vec!["股票".to_string()],
        }
    ],
    onchain_prompt_definitions: vec![],
    full_capabilities_uri: Some("https://ipfs.io/ipfs/QmServer...".to_string()),
    tags: vec!["金融".to_string(), "数据".to_string()],
};

🔍 发现和查询

直接查找

// 导出 PDA 以直接查找代理
let (agent_pda, _) = Pubkey::find_program_address(
    &[AGENT_REGISTRY_PDA_SEED, "my-agent-id".as_bytes()],
    &agent_registry::id(),
);

// 获取代理数据
let agent_data = client.get_account_data(&agent_pda)?;
let agent_entry = AgentRegistryEntryV1::try_from_slice(&agent_data)?;

基于事件的索引

// 监听代理注册事件
client.on_logs_subscribe(
    RpcTransactionLogsFilter::Mentions(vec![agent_registry::id().to_string()]),
    RpcTransactionLogsConfig {
        commitment: Some(CommitmentConfig::confirmed()),
    },
)?;

// 处理事件以进行链下索引
for log in logs {
    if log.contains("AgentRegistered") {
        // 解析并索引代理数据
        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 网络容量限制(~65,000 TPS)
  • 存储: 无限条目(无全局状态限制)
  • 索引: 基于事件的链下扩展

🧪 测试

测试覆盖率

  • 100% 指令覆盖率: 所有程序指令已测试
  • 边缘情况测试: 边界条件和错误场景
  • 安全测试: 授权和验证测试
  • 集成测试: 端到端工作流程测试

运行测试

# 运行所有测试
cargo test --all

# 运行带覆盖率的测试
cargo test --all -- --test-threads=1

# 运行特定测试类别
cargo test validation_tests
cargo test authorization_tests
cargo test integration_tests

🚀 部署

本地开发

# 启动本地验证器
solana-test-validator

# 部署程序
./scripts/deploy-devnet.sh

开发网部署

# 配置为开发网
solana config set --url devnet

# 验证部署
./scripts/deploy-devnet.sh
./scripts/verify.sh

🌐 实时开发网部署

Solana AI 注册表目前在 Solana 开发网上部署并运行:

程序地址

  • 代理注册表: BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr
  • MCP 服务器注册表: BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX5CrXQ2sR2SR

浏览器链接

查询示例

使用 Solana CLI
# 配置为开发网
solana config set --url devnet

# 查询代理注册表程序信息
solana program show BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr

# 查询 MCP 服务器注册表程序信息
solana program show BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX5CrXQ2sR2SR

# 列出所有代理账户(需要自定义 RPC 调用)
solana account BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr --output json

# 列出所有 MCP 服务器账户(需要自定义 RPC 调用)
solana account BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX2sR2SR --output json
使用 JavaScript/TypeScript
import { Connection, PublicKey } from '@solana/web3.js';

const connection = new Connection('https://api.devnet.solana.com');

// 程序地址
const AGENT_REGISTRY_PROGRAM_ID = new PublicKey('BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr');
const MCP_REGISTRY_PROGRAM_ID = new PublicKey('BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX5CrXQ2sR2SR');

// 查询所有代理账户
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()
  }));
}

// 查询所有 MCP 服务器账户
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()
  }));
}

// 通过 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;
}

// 通过 PDA 查询特定 MCP 服务器
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

# 连接到开发网
client = Client("https://api.devnet.solana.com")

# 程序地址
AGENT_REGISTRY_PROGRAM_ID = PublicKey("BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr")
MCP_REGISTRY_PROGRAM_ID = PublicKey("BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX5CrXQ2sR2SR")

# 查询所有代理账户
def get_all_agents():
    response = client.get_program_accounts(AGENT_REGISTRY_PROGRAM_ID)
    return response

# 查询所有 MCP 服务器账户
def get_all_mcp_servers():
    response = client.get_program_accounts(MCP_REGISTRY_PROGRAM_ID)
    return response

# 查询特定账户
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;

// 连接到开发网
let rpc_client = RpcClient::new("https://api.devnet.solana.com");

// 程序地址
let agent_registry_program_id = Pubkey::from_str("BruRLHGfNaf6C5HKUqFu6md5ePJNELafm1vZdhctPkpr").unwrap();
let mcp_registry_program_id = Pubkey::from_str("BCBVehUHR3yhbDbvhV3QHS3s27k3LTbpX5CrXQ2sR2SR").unwrap();

// 查询所有代理账户
let agent_accounts = rpc_client.get_program_accounts(&agent_registry_program_id)?;

// 查询所有 MCP 服务器账户
let mcp_accounts = rpc_client.get_program_accounts(&mcp_registry_program_id)?;

// 查询特定账户
let account_info = rpc_client.get_account(&some_pubkey)?;

主网部署

# 配置为主网
solana config set --url mainnet-beta

# 部署(需要安全审计)
./scripts/deploy-mainnet.sh

📚 API 参考

代理注册表指令

  • RegisterAgent: 创建新的代理条目
  • UpdateAgentDetails: 修改代理信息
  • UpdateAgentStatus: 更改代理操作状态
  • DeregisterAgent: 标记代理为已注销

MCP 服务器注册