Skip to main content
This is the complete gRPC contract between SDKs and the Bindu core. Everything on this page is defined in proto/agent_handler.proto — the single source of truth for how SDKs register agents, send heartbeats, expose handler callbacks, and keep the language-agnostic runtime aligned with the Python core.

Why This API Matters

The gRPC layer is not an add-on around Bindu. It is the contract that keeps registration, liveness, handler execution, and capability discovery consistent across SDKs while the core continues to run the shared infrastructure. To understand why this matters, compare what happens without it:
Ad-hoc SDK integrationBindu gRPC contract
Each SDK invents its own registration and callback shapeOne protocol defines the shared contract between SDKs and the core
Liveness and capability checks vary across languagesHeartbeat, HealthCheck, and GetCapabilities are standardized
Remote handlers can drift from local bindufy behaviorRegisterAgent preserves the same bindufy pipeline in the core
Message execution contracts become SDK-specificHandleMessages keeps one handler request/response model
Operational behavior becomes harder to debugPorts, methods, and message schemas stay explicit and testable
The proto turns the language boundary into a stable interface. SDKs and the core can evolve around one shared contract instead of growing separate integration logic.
The reference here is not just a list of RPCs. It is the runtime boundary that allows remote SDKs to participate in the same bindufy lifecycle as local Python agents.

How The gRPC Contract Works

The contract is split across two services that face opposite directions. Understanding which service lives where is the key to reading the rest of this page.

The Service Split

BinduService runs on port 3774 in the Bindu core. SDKs use it to register and manage agents. AgentHandler runs on a dynamic port in the SDK. The core uses it to execute the developer’s handler and query runtime status.

Registration

BinduService is the control plane for agent registration, heartbeats, and shutdown.

Execution

AgentHandler is the runtime callback plane for message handling and health checks.

Shared Proto

Both sides follow the same message schema from proto/agent_handler.proto.

The Lifecycle: Register, Execute, Maintain

Every SDK follows the same three-phase lifecycle. First the SDK registers with the core. Then the core calls the SDK when work arrives. Finally, the SDK keeps the connection alive and shuts down cleanly. Let’s walk through each phase and look at the exact message shapes involved.
1

Register

RegisterAgent is the main entry point. The SDK sends config, skills, and its callback address. The core runs the full bindufy pipeline and returns the agent’s identity.
message RegisterAgentRequest {
  string config_json = 1;              // Full config as JSON string
  repeated SkillDefinition skills = 2; // Skills with file content
  string grpc_callback_address = 3;    // SDK's AgentHandler address
}
config_json matches the Python bindufy() config format:
{
  "author": "dev@example.com",
  "name": "my-agent",
  "description": "What it does",
  "deployment": {"url": "http://localhost:3773", "expose": true},
  "execution_cost": {"amount": "1000000", "token": "USDC"}
}
The core validates config, generates agent ID using SHA256 of author+name, creates Ed25519 DID keys, sets up x402 payments, creates the manifest with GrpcAgentClient as handler, and starts the HTTP/A2A server on the configured URL.
2

Execute

HandleMessages is how the core invokes the SDK handler once work arrives. This is the hot path — every user message passes through this RPC.
message HandleRequest {
  repeated ChatMessage messages = 1;  // Conversation history
  string task_id = 2;
  string context_id = 3;
}

message ChatMessage {
  string role = 1;     // "user", "assistant", or "system"
  string content = 2;
}
Response rules:
  • Normal response: {content: "answer", state: ""} → task completes
  • Need more info: {state: "input-required", prompt: "Can you clarify?"} → task stays open
  • Need auth: {state: "auth-required"} → task stays open
  • Error: Return gRPC INTERNAL status → task fails
3

Maintain

Heartbeat and UnregisterAgent handle liveness and clean shutdown. The heartbeat keeps the core informed that your SDK is still running. Unregister tells it you are leaving on purpose.
message HeartbeatRequest {
  string agent_id = 1;
  int64 timestamp = 2;   // Unix timestamp in milliseconds
}

message HeartbeatResponse {
  bool acknowledged = 1;      // true if agent_id is registered
  int64 server_timestamp = 2;
}
SDKs send Heartbeat every 30 seconds and call UnregisterAgent before exiting.

Service Reference

Here are the two services summarized for quick lookup.

BinduService (port 3774)

Lives in the Bindu core. SDKs call this to register and manage agents.
MethodWhat it does
RegisterAgentSDK sends config + skills, core runs the full bindufy pipeline and returns the agent’s identity
HeartbeatKeep-alive signal sent every 30 seconds
UnregisterAgentClean shutdown call before SDK exit

AgentHandler (dynamic port)

Lives in the SDK. The core calls this when work arrives.
MethodWhat it does
HandleMessagesCore sends conversation history, SDK runs the developer’s handler and returns the response
HandleMessagesStreamServer-side streaming variant — supported in GrpcAgentClient via use_streaming=True
GetCapabilitiesCore queries what the SDK agent supports
HealthCheckCore verifies the SDK is responsive
HandleMessagesStream is fully supported. GrpcAgentClient calls it when initialized with use_streaming=True. The SDK’s AgentHandler must implement this RPC to use streaming. The TypeScript SDK currently returns supports_streaming: false from GetCapabilities, but the proto contract and Python core are both fully ready for it.

Shared Message Types

These message types are used across both services. Understanding them helps when building Custom SDKs or debugging registration issues.

SkillDefinition

SkillDefinition is sent during registration and carries the skill file content so the core does not need filesystem access. The name, description, and tags fields describe the skill for discovery. The input_modes and output_modes declare what formats the skill accepts and produces. The raw_content and format fields carry the original file content so the core can process it directly.
message SkillDefinition {
  string name = 1;
  string description = 2;
  repeated string tags = 3;
  repeated string input_modes = 4;
  repeated string output_modes = 5;
  string version = 6;
  string author = 7;
  string raw_content = 8;   // Full skill.yaml or SKILL.md content
  string format = 9;        // "yaml" or "markdown"
}
Sending skill content during registration lets the SDK remain the source of truth for skill files while the core receives the exact material it needs to build the manifest.

Capability and Health Responses

These are the responses the core gets when it queries your SDK about what it can do and whether it is still running.
message GetCapabilitiesResponse {
  string name = 1;
  string description = 2;
  string version = 3;
  bool supports_streaming = 4;
  repeated SkillDefinition skills = 5;
}

Configuration

These environment variables control the gRPC server in the Bindu core. You typically do not need to change them unless you are running in a non-standard environment or debugging port conflicts.
VariableDefaultDescription
GRPC__ENABLEDfalseEnable gRPC server
GRPC__HOST0.0.0.0Bind address
GRPC__PORT3774Server port
GRPC__MAX_WORKERS10Thread pool size
GRPC__MAX_MESSAGE_LENGTH4194304Max message size (4MB)
GRPC__HANDLER_TIMEOUT30.0HandleMessages timeout (seconds)
GRPC__HEALTH_CHECK_INTERVAL30Health check interval (seconds)

Practical gRPC Calls

If you want to test the contract directly without writing SDK code, grpcurl lets you call any of these RPCs from the command line. This is useful for debugging registration issues or verifying that the core is running correctly.
grpcurl -plaintext \
  -import-path proto \
  -proto agent_handler.proto \
  localhost:3774 list
grpcurl -plaintext -emit-defaults \
  -proto proto/agent_handler.proto -import-path proto \
  -d '{"agent_id": "test", "timestamp": 1711234567890}' \
  localhost:3774 bindu.grpc.BinduService.Heartbeat
grpcurl -plaintext -emit-defaults \
  -proto proto/agent_handler.proto -import-path proto \
  -d '{
    "config_json": "{\"author\":\"test@example.com\",\"name\":\"test\",\"deployment\":{\"url\":\"http://localhost:3773\",\"expose\":true}}",
    "skills": [],
    "grpc_callback_address": "localhost:50052"
  }' \
  localhost:3774 bindu.grpc.BinduService.RegisterAgent

Operational Guarantees

Stable Contract

The proto keeps SDK registration, handler execution, and liveness signaling aligned across languages.

Explicit Interfaces

Ports, message types, and RPC boundaries stay visible and testable with tools like grpcurl.
Sunflower LogoBindu keeps the runtime contract explicit at the boundary, so SDKs and the core can behave like one system across languages.