> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getbindu.com/llms.txt
> Use this file to discover all available pages before exploring further.

# gRPC Quickstart

> The fastest path to your first working gRPC agent

This is the fastest path to the aha moment. You will build a simple TypeScript agent, call `bindufy()`, and watch the Bindu Core sidecar turn it into a real microservice.

You write the driver. The sidecar brings the engine: DID identity, A2A protocol compliance, x402 payment support, scheduling, storage, and an HTTP server.

Time to complete: \~10 minutes

<CardGroup cols={2}>
  <Card title="DID Identity" icon="fingerprint">
    The core generates and manages agent identity for you.
  </Card>

  <Card title="A2A Protocol" icon="globe">
    Your handler is exposed as a production-ready A2A service.
  </Card>

  <Card title="Payments" icon="credit-card">
    x402 support can be added without changing the transport model.
  </Card>

  <Card title="Scheduling + Storage" icon="database">
    The sidecar handles task orchestration and persistence.
  </Card>
</CardGroup>

***

## Prerequisites

Before you start, make sure the local machine can run both halves of the sidecar model. You need a JavaScript runtime for your code and a Python runtime for the core.

<CardGroup cols={2}>
  <Card title="Node.js" icon="node-js">
    Version 18 or higher
  </Card>

  <Card title="Python" icon="python">
    Version 3.12+ with Bindu installed
  </Card>

  <Card title="OpenAI API Key" icon="key">
    Get one at platform.openai.com/api-keys
  </Card>

  <Card title="Terminal" icon="terminal">
    Basic command line knowledge
  </Card>
</CardGroup>

### Install Bindu Python Core

The TypeScript SDK needs the Bindu Core installed on the machine. This is the engine half of the sidecar — your SDK will launch it automatically, but it needs to be available first.

```bash theme={null}
pip install bindu
# or with uv:
uv pip install bindu
```

<Info>
  The SDK launches the Python core automatically as a child process. You never start
  the sidecar manually during normal SDK use.
</Info>

***

## Step 1: Create Your Project

Start with a clean project directory. Nothing special here — just a standard Node.js project.

```bash theme={null}
mkdir my-first-agent
cd my-first-agent
npm init -y
```

***

## Step 2: Install Dependencies

Now install the packages your agent needs. The Bindu SDK handles the sidecar lifecycle, and you can use any LLM library you like alongside it.

```bash theme={null}
npm install @bindu/sdk openai dotenv
npm install -D tsx typescript @types/node
```

* `@bindu/sdk` — Bindu TypeScript SDK (gRPC, registration, sidecar lifecycle)
* `openai` — OpenAI Node.js SDK
* `dotenv` — Loads environment variables from `.env`
* `tsx` — TypeScript executor (dev dependency)
* `typescript` — TypeScript compiler (dev dependency)

***

## Step 3: Create Your Environment File

Your agent needs an API key to talk to OpenAI. Store it in a `.env` file so it stays out of your code.

```bash theme={null}
touch .env
```

```env theme={null}
OPENAI_API_KEY=sk-your-openai-api-key-here
OPENAI_MODEL=gpt-4o
```

<Warning>
  Never commit your `.env` file to git.

  ```bash theme={null}
  echo ".env" >> .gitignore
  ```
</Warning>

***

## Step 4: Create a Skill Definition

Skills tell the A2A protocol what your agent can do. Think of them as the agent's resume — other agents and clients read this to decide whether to talk to yours.

```bash theme={null}
mkdir -p skills/question-answering
```

Create `skills/question-answering/skill.yaml`:

```yaml theme={null}
name: question-answering
description: General question answering using GPT-4o
tags:
  - qa
  - assistant
  - general-knowledge
input_modes:
  - text/plain
output_modes:
  - text/plain
version: 1.0.0
author: dev@example.com
```

<Tip>
  You can also use Markdown format (`SKILL.md`) instead of YAML. Both formats are
  supported.
</Tip>

***

## Step 5: Write Your Agent Code

This is the core of what you are building. Your code defines the driver — the handler function that receives messages and returns responses. `bindufy()` attaches the engine around it.

```typescript theme={null}
import { bindufy, ChatMessage } from "@bindu/sdk";
import OpenAI from "openai";
import * as dotenv from "dotenv";

dotenv.config();

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

bindufy(
  {
    author: "dev@example.com",
    name: "my-first-agent",
    description: "A helpful assistant powered by GPT-4o",
    version: "1.0.0",
    deployment: {
      url: "http://localhost:3773",
      expose: true,
      cors_origins: ["http://localhost:5173"],
    },
    skills: ["skills/question-answering"],
  },
  async (messages: ChatMessage[]) => {
    const response = await openai.chat.completions.create({
      model: process.env.OPENAI_MODEL || "gpt-4o",
      messages: messages.map((m) => ({
        role: m.role as "user" | "assistant" | "system",
        content: m.content,
      })),
    });

    return response.choices[0].message.content || "";
  }
);
```

Notice what you did *not* write: no server setup, no DID key generation, no authentication middleware, no protocol handling. That is the sidecar doing its job.

***

## Step 6: Run Your Agent

Everything is in place. Start your agent with a single command:

```bash theme={null}
npx tsx index.ts
```

You should see output like this:

```text theme={null}
  Bindufy: my-first-agent
  Author: dev@example.com

Starting Bindu core: /usr/local/bin/bindu serve --grpc --grpc-port 3774
Waiting for Bindu core gRPC on port 3774...
[bindu-core] gRPC server started on grpc://0.0.0.0:3774
[bindu-core] Waiting for SDK agent registrations...
Bindu core is ready.
  AgentHandler gRPC server on :54321
  Registering with Bindu core at localhost:3774...

  Agent registered successfully!
  Agent ID: 91547067-c183-e0fd-c150-27a3ca4135ed
  DID:      did:bindu:dev_at_example_com:my-first-agent:91547067...
  A2A URL:  http://localhost:3773

  Waiting for messages...
```

<Info>
  Lines prefixed `[bindu-core]` come from the spawned Python core's stdout. Lines without
  a prefix come from the SDK itself. The exact port after `AgentHandler gRPC server on :`
  is OS-assigned (`callbackPort: 0` in your config), so it will differ each run.
</Info>

<Check>Your agent is now running as a full microservice.</Check>

That is a lot of infrastructure that just appeared from one function call. Your agent has a DID identity, an A2A-compliant HTTP server, authentication, and is ready to receive messages.

***

## Step 7: Verify It Works

Let's make sure everything is working by sending your first message. Open a new terminal and try these commands.

### Send a message

```bash theme={null}
curl -s -X POST http://localhost:3773 \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "message/send",
    "params": {
      "message": {
        "role": "user",
        "parts": [{"kind": "text", "text": "What is the capital of France?"}],
        "messageId": "11111111-1111-1111-1111-111111111111",
        "contextId": "22222222-2222-2222-2222-222222222222",
        "taskId": "33333333-3333-3333-3333-333333333333",
        "kind": "message"
      },
      "configuration": {
        "acceptedOutputModes": ["text/plain"],
        "blocking": true
      }
    },
    "id": "11111111-1111-1111-1111-111111111111"
  }' | python3 -m json.tool
```

<Info>
  `messageId`, `contextId`, and `taskId` are required fields in the A2A Message schema.
  You must pass valid UUIDs. Omitting any of them will result in a validation error from
  the core.
</Info>

If everything is working, you should see a JSON response with the answer. That response traveled from your curl command, through the A2A HTTP server, across gRPC to your TypeScript handler, out to OpenAI, and back the same way.

### Check the agent card

Every Bindu agent exposes a machine-readable identity card. This is how other agents discover what yours can do.

```bash theme={null}
curl -s http://localhost:3773/.well-known/agent.json | python3 -m json.tool
```

### Check health

```bash theme={null}
curl -s http://localhost:3773/health
```

***

## What Just Happened?

Your agent is running. Let's slow down and understand what `bindufy()` actually did behind the scenes, because quite a lot happened in that one function call.

<Steps>
  <Step title="Launched the Python core">
    Spawned `bindu serve --grpc` as a child process.
  </Step>

  <Step title="Started a gRPC server">
    For your handler on a dynamic, OS-assigned port.
  </Step>

  <Step title="Read your skill files">
    Loaded `skills/question-answering/skill.yaml`.
  </Step>

  <Step title="Registered your agent">
    Called `RegisterAgent` on the core with your config.
  </Step>

  <Step title="Core ran full bindufy logic">
    * Generated deterministic agent ID: `SHA256("{author}:{name}")` → first 32 hex chars → UUID format ([`bindufy.py:74-76`](https://github.com/getbindu/Bindu/blob/main/bindu/penguin/bindufy.py#L74))
    * Created Ed25519 DID keys and sanitized the DID identifiers (`@` → `_at_`, `.` → `_`, spaces → `_`, lowercased — see [`did_agent_extension.py:124`](https://github.com/getbindu/Bindu/blob/main/bindu/extensions/did/did_agent_extension.py#L124))
    * Set up authentication via Hydra OAuth2 (when `AUTH_ENABLED=true`; the paywall example explicitly disables this for local dev)
    * Created the manifest with `GrpcAgentClient` as `agent_function` (passed through `_bindufy_core(..., handler_callable=grpc_client)`)
    * Started HTTP/A2A server on `:3773`
  </Step>

  <Step title="Returned registration result">
    Agent ID, DID, and A2A URL.
  </Step>

  <Step title="Started heartbeat loop">
    Pings core every 30 seconds to signal liveness (SDK convention — the cadence
    is not enforced by the core).
  </Step>
</Steps>

Your code became the driver, and the sidecar brought the engine online around it.

***

## Project Structure

Here is what your project looks like now:

```text theme={null}
my-first-agent/
├── index.ts
├── package.json
├── .env
├── .gitignore
├── skills/
│   └── question-answering/
│       └── skill.yaml
└── node_modules/
```

***

## Troubleshooting

If something did not work, check the common issues below. Most problems come from missing prerequisites or port conflicts.

<AccordionGroup>
  <Accordion title="&#x22;Bindu not found&#x22;">
    ```bash theme={null}
    pip install bindu
    bindu --version
    ```
  </Accordion>

  <Accordion title="&#x22;Port 3773 already in use&#x22;">
    ```bash theme={null}
    lsof -ti:3773 -ti:3774 | xargs kill 2>/dev/null
    ```
  </Accordion>

  <Accordion title="&#x22;OPENAI_API_KEY not set&#x22;">
    ```bash theme={null}
    cat .env
    # Should show: OPENAI_API_KEY=sk-...
    ```
  </Accordion>

  <Accordion title="Agent starts but no response">
    Common causes:

    * Invalid API key
    * Model not available on your OpenAI plan
    * Rate limiting
    * Network connectivity
  </Accordion>

  <Accordion title="&#x22;Registration failed&#x22;">
    Common causes:

    * Missing `author` or `name` in config
    * Invalid `deployment.url` format
    * Port conflicts
  </Accordion>
</AccordionGroup>

***

## Next Steps

You have a working agent. From here, the natural next question is: how do I make it smarter?

<CardGroup cols={2}>
  <Card title="Agent Implementation" icon="messages" href="/bindu/grpc/agent-client">
    Handler patterns (multi-turn, LangChain, payments), state transitions, configuration, and how the bridge works under the hood
  </Card>

  <Card title="Custom SDKs" icon="code" href="/bindu/grpc/custom-sdks">
    Build SDKs for Rust, Go, Swift, or any language with gRPC
  </Card>

  <Card title="API Reference" icon="book" href="/bindu/grpc/api-reference">
    The complete gRPC contract: services, messages, ports, and env vars
  </Card>

  <Card title="Overview" icon="diagram-project" href="/bindu/grpc/overview">
    Revisit the sidecar architecture, tradeoffs, and current limitations
  </Card>
</CardGroup>

<span className="brand-quote">
  <img src="https://mintcdn.com/pebbling/x2BFCGEbWywg69kQ/logo/light.svg?fit=max&auto=format&n=x2BFCGEbWywg69kQ&q=85&s=a69e734bb925e661b3c2ca2a20a050a9" alt="Sunflower Logo" width="32" className="clean-icon" data-path="logo/light.svg" />

  <span className="brand-quote-text">
    Get your first language-agnostic agent running in minutes without writing{" "}

    <span className="brand-quote-highlight">
      a single line of infrastructure code
    </span>

    .
  </span>
</span>
