Getting Started
Install ZAP and build your first AI agent
Getting Started
This guide walks you through installing ZAP and building your first AI agent.
Prerequisites
- Cap'n Proto compiler (
capnp) - Language-specific toolchain (Rust, Go, Python, etc.)
brew install capnp# Debian/Ubuntu
sudo apt-get install capnproto libcapnp-dev
# Fedora
sudo dnf install capnproto capnproto-devel# Using Chocolatey
choco install capnproto
# Or download from https://capnproto.org/install.htmlInstallation
cargo add zap-protocol[dependencies]
zap-protocol = "0.1"
tokio = { version = "1", features = ["full"] }go get github.com/zap-protocol/zap-gopip install zap-protocolOr with uv:
uv add zap-protocolnpm install @zap-protocol/zapOr with pnpm:
pnpm add @zap-protocol/zapQuick Start
Create a ZAP Client
use zap_protocol::{Zap, ClientInfo};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Connect to ZAP server
let client = Zap::connect("zap://localhost:9000").await?;
// Initialize with client info
let server_info = client.init(ClientInfo {
name: "my-agent".into(),
version: "1.0.0".into(),
}).await?;
println!("Connected to: {} v{}", server_info.name, server_info.version);
println!("Capabilities: {:?}", server_info.capabilities);
Ok(())
}package main
import (
"context"
"fmt"
"log"
zap "github.com/zap-protocol/zap-go"
)
func main() {
ctx := context.Background()
// Connect to ZAP server
client, err := zap.Connect(ctx, "zap://localhost:9000")
if err != nil {
log.Fatal(err)
}
defer client.Close()
// Initialize with client info
serverInfo, err := client.Init(ctx, &zap.ClientInfo{
Name: "my-agent",
Version: "1.0.0",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Connected to: %s v%s\n", serverInfo.Name, serverInfo.Version)
}import asyncio
from zap_protocol import Zap, ClientInfo
async def main():
# Connect to ZAP server
client = await Zap.connect("zap://localhost:9000")
# Initialize with client info
server_info = await client.init(ClientInfo(
name="my-agent",
version="1.0.0"
))
print(f"Connected to: {server_info.name} v{server_info.version}")
print(f"Capabilities: {server_info.capabilities}")
asyncio.run(main())import { Zap, ClientInfo } from '@zap-protocol/zap';
async function main() {
// Connect to ZAP server
const client = await Zap.connect('zap://localhost:9000');
// Initialize with client info
const serverInfo = await client.init({
name: 'my-agent',
version: '1.0.0'
});
console.log(`Connected to: ${serverInfo.name} v${serverInfo.version}`);
console.log('Capabilities:', serverInfo.capabilities);
}
main().catch(console.error);List and Call Tools
// List available tools
let tools = client.list_tools().await?;
for tool in &tools {
println!("Tool: {} - {}", tool.name, tool.description);
}
// Call a tool
let result = client.call_tool(&ToolCall {
id: uuid::Uuid::new_v4().to_string(),
name: "read_file".into(),
args: serde_json::to_vec(&json!({
"path": "/etc/hosts"
}))?,
metadata: Default::default(),
}).await?;
if let Some(error) = result.error {
eprintln!("Tool error: {}", error);
} else {
let content: serde_json::Value = serde_json::from_slice(&result.content)?;
println!("Result: {}", content);
}// List available tools
tools, err := client.ListTools(ctx)
if err != nil {
log.Fatal(err)
}
for _, tool := range tools {
fmt.Printf("Tool: %s - %s\n", tool.Name, tool.Description)
}
// Call a tool
result, err := client.CallTool(ctx, &zap.ToolCall{
ID: uuid.New().String(),
Name: "read_file",
Args: []byte(`{"path": "/etc/hosts"}`),
})
if err != nil {
log.Fatal(err)
}
if result.Error != "" {
log.Printf("Tool error: %s", result.Error)
} else {
fmt.Printf("Result: %s\n", result.Content)
}# List available tools
tools = await client.list_tools()
for tool in tools:
print(f"Tool: {tool.name} - {tool.description}")
# Call a tool
result = await client.call_tool(ToolCall(
id=str(uuid.uuid4()),
name="read_file",
args=json.dumps({"path": "/etc/hosts"}).encode()
))
if result.error:
print(f"Tool error: {result.error}")
else:
content = json.loads(result.content)
print(f"Result: {content}")// List available tools
const tools = await client.listTools();
for (const tool of tools) {
console.log(`Tool: ${tool.name} - ${tool.description}`);
}
// Call a tool
const result = await client.callTool({
id: crypto.randomUUID(),
name: 'read_file',
args: JSON.stringify({ path: '/etc/hosts' })
});
if (result.error) {
console.error('Tool error:', result.error);
} else {
const content = JSON.parse(result.content);
console.log('Result:', content);
}Bridge MCP Servers
use zap_protocol::{Gateway, ServerConfig, Transport};
// Create gateway
let gateway = Gateway::new().await?;
// Add MCP filesystem server
let fs_id = gateway.add_server(
"filesystem",
"stdio://npx -y @modelcontextprotocol/server-filesystem /tmp",
ServerConfig {
transport: Transport::Stdio,
..Default::default()
},
).await?;
// Add MCP GitHub server
let gh_id = gateway.add_server(
"github",
"stdio://npx -y @modelcontextprotocol/server-github",
ServerConfig {
transport: Transport::Stdio,
auth: Some(Auth::Bearer(std::env::var("GITHUB_TOKEN")?)),
..Default::default()
},
).await?;
// Now use gateway.list_tools() to get tools from all servers
let all_tools = gateway.list_tools().await?;// Create gateway
gateway := zap.NewGateway()
// Add MCP filesystem server
fsID, err := gateway.AddServer(ctx, "filesystem",
"stdio://npx -y @modelcontextprotocol/server-filesystem /tmp",
&zap.ServerConfig{
Transport: zap.TransportStdio,
})
if err != nil {
log.Fatal(err)
}
// Add MCP GitHub server
ghID, err := gateway.AddServer(ctx, "github",
"stdio://npx -y @modelcontextprotocol/server-github",
&zap.ServerConfig{
Transport: zap.TransportStdio,
Auth: &zap.Auth{
Bearer: os.Getenv("GITHUB_TOKEN"),
},
})
if err != nil {
log.Fatal(err)
}
// Get tools from all servers
allTools, _ := gateway.ListTools(ctx)from zap_protocol import Gateway, ServerConfig, Transport, Auth
import os
# Create gateway
gateway = Gateway()
# Add MCP filesystem server
fs_id = await gateway.add_server(
"filesystem",
"stdio://npx -y @modelcontextprotocol/server-filesystem /tmp",
ServerConfig(transport=Transport.STDIO)
)
# Add MCP GitHub server
gh_id = await gateway.add_server(
"github",
"stdio://npx -y @modelcontextprotocol/server-github",
ServerConfig(
transport=Transport.STDIO,
auth=Auth(bearer=os.environ["GITHUB_TOKEN"])
)
)
# Get tools from all servers
all_tools = await gateway.list_tools()import { Gateway, ServerConfig, Transport, Auth } from '@zap-protocol/zap';
// Create gateway
const gateway = new Gateway();
// Add MCP filesystem server
const fsId = await gateway.addServer(
'filesystem',
'stdio://npx -y @modelcontextprotocol/server-filesystem /tmp',
{ transport: Transport.STDIO }
);
// Add MCP GitHub server
const ghId = await gateway.addServer(
'github',
'stdio://npx -y @modelcontextprotocol/server-github',
{
transport: Transport.STDIO,
auth: { bearer: process.env.GITHUB_TOKEN }
}
);
// Get tools from all servers
const allTools = await gateway.listTools();Next Steps
- Schema Language - Learn the Cap'n Proto schema format
- Protocol Specification - Understand the wire format
- Language Bindings - SDK documentation for your language
- Post-Quantum Security - Enable PQ cryptography
Overview
Understanding ZAP architecture and core concepts
Schema Language
Cap'n Proto schema reference for ZAP
Protocol Specification
ZAP wire format, encoding, and RPC semantics
Language Bindings
ZAP SDK documentation for all supported languages
Advanced Topics
Post-quantum cryptography, consensus, identity, and blockchain integration
How is this guide?
Last updated on