npm package: @northcognitive/agentpack
Description: TypeScript SDK for building Agentpack tools
Author: @ielm
Latest version: 0.1.5

# @agentpack/sdk

**Zero-Config TypeScript SDK for Agentpack Tools**

Drop a `.ts` file in your repo and get a production-ready, containerized, gRPC-enabled tool—instantly. No servers. No Docker. No infrastructure code.

## Installation

```bash
npm install @agentpack/sdk zod
# or
pnpm add @agentpack/sdk zod
# or
yarn add @agentpack/sdk zod
```

## Quick Start

### 1. Write ONLY Business Logic

```typescript
// tools/greet.ts
import { tool, z } from '@agentpack/sdk';

export default tool({
  name: 'greet',
  description: 'Greet a person by name',
  input: z.object({
    name: z.string(),
  }),
  output: z.object({
    greeting: z.string(),
  }),
  async handler(input, ctx) {
    ctx.logger.info('Greeting user', { name: input.name });
    return { greeting: `Hello, ${input.name}!` };
  },
});
```

### 2. That's It!

No step 2. **Agentpack Builder** automatically:
- Discovers tools in `tools/` directory
- Generates `.agentpack-manifest.json`
- Creates optimized Dockerfile
- Builds OCI image with gRPC runtime
- Deploys to container backend

**Agentpack Runtime** automatically:
- Loads tools from manifest
- Starts gRPC server (port 50051)
- Handles execution via Rust core
- Provides full observability

## Zero-Config Architecture

```
┌─────────────────────────────────────────────────┐
│  YOU: Write tools/calculator.ts                 │
│  ↓                                              │
│  BUILDER: Scan → Manifest → Dockerfile → Image │
│  ↓                                              │
│  RUNTIME: Load → gRPC Server → Execute         │
│  ↓                                              │
│  RUST CORE: Orchestrate with Tower middleware  │
└─────────────────────────────────────────────────┘
```

**You own**: Business logic (100% focus)
**Agentpack owns**: Servers, containers, orchestration, observability

## Features

### Built-In, Zero Setup:
- ✅ **Type-Safe**: Full TypeScript inference from Zod schemas
- ✅ **Validated**: Automatic input/output validation
- ✅ **Observable**: OpenTelemetry tracing (no config)
- ✅ **Secure**: Secret management via dashboard
- ✅ **Resilient**: HTTP client with automatic retries
- ✅ **Structured Logging**: Request-scoped context
- ✅ **gRPC**: High-performance protocol (auto-configured)
- ✅ **Containerized**: OCI images with base runtime
- ✅ **Sandboxed**: gVisor/Firecracker isolation

## Execution Context

Every tool handler receives `ctx` with production-ready utilities:

### Secrets

```typescript
// Get optional secret
const apiKey = await ctx.secrets.get('API_KEY');

// Get required secret (throws if missing)
const apiKey = await ctx.secrets.require('API_KEY');

// Secrets configured via Agentpack Dashboard:
// - vault://kv/my-secret
// - aws-sm://secret-name
// - gcp-sm://projects/*/secrets/*
```

### HTTP Client

```typescript
// GET with automatic retries
const response = await ctx.http.get('https://api.example.com/data', {
  params: { limit: 10 },
  headers: { 'Authorization': `Bearer ${token}` },
});

// POST, PUT, DELETE also available
const response = await ctx.http.post('https://api.example.com/data', {
  name: 'value',
});
```

### Logger

```typescript
ctx.logger.info('Processing request', { userId: '123' });
ctx.logger.error('Something went wrong', { error: err.message });

// Logs automatically include:
// - Request ID
// - Trace ID
// - Tool name
// - Timestamp
```

### Tracer (OpenTelemetry)

```typescript
const span = ctx.trace.startSpan('external-api-call');
try {
  // ... do work ...
  span.setAttribute('items.count', items.length);
} finally {
  span.end();
}

// Traces sent to OpenTelemetry Collector automatically
```

## Examples

See `examples/` directory:

### Simple Tool (`examples/calculator`)
```typescript
export default tool({
  name: 'calculator',
  description: 'Perform arithmetic operations',
  input: z.object({
    operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
    a: z.number(),
    b: z.number(),
  }),
  output: z.object({
    result: z.number(),
  }),
  async handler(input, ctx) {
    // Pure business logic
    let result: number;
    switch (input.operation) {
      case 'add': result = input.a + input.b; break;
      case 'subtract': result = input.a - input.b; break;
      case 'multiply': result = input.a * input.b; break;
      case 'divide':
        if (input.b === 0) throw new Error('Division by zero');
        result = input.a / input.b;
        break;
    }
    return { result };
  },
});
```

### External API Tool (`examples/weather`)
Demonstrates:
- Secret management (`ctx.secrets.require()`)
- HTTP client with retries (`ctx.http.get()`)
- Structured logging
- Input validation with Zod enums

## API Reference

### `tool(definition)`

Create a tool definition.

```typescript
interface ToolDefinition<TInput, TOutput> {
  name: string;              // Unique tool identifier
  description: string;       // Human-readable description
  input: ZodSchema<TInput>;  // Zod input validation schema
  output: ZodSchema<TOutput>; // Zod output validation schema
  handler: ToolHandler<TInput, TOutput>; // Async execution function
}

type ToolHandler<TInput, TOutput> = (
  input: TInput,
  ctx: ExecutionContext
) => Promise<TOutput>;
```

**Returns**: `Tool` instance (internal use by runtime)

## Error Handling

```typescript
import {
  ToolError,
  ValidationError,
  SecretNotFoundError,
  HttpError,
} from '@agentpack/sdk';

async handler(input, ctx) {
  // Validation errors thrown automatically

  // Secret not found
  const key = await ctx.secrets.require('API_KEY'); // throws SecretNotFoundError

  // HTTP errors
  const response = await ctx.http.get('...'); // throws HttpError on failure

  // Custom errors
  if (!input.valid) {
    throw new ToolError('Invalid input', 'INVALID_INPUT');
  }
}
```

## Multi-File Tools

Tools can have dependencies:

```
tools/
├── calculator/
│   ├── index.ts         # Entry point (exports default tool)
│   ├── operations.ts    # Helper functions
│   └── types.ts         # Shared types
└── weather.ts           # Single-file tool
```

**Builder discovers both patterns automatically**:
- Single-file: `tools/weather.ts`
- Multi-file: `tools/calculator/index.ts`

## Testing

```typescript
import { describe, it, expect } from 'vitest';
import { tool, z } from '@agentpack/sdk';

describe('my tool', () => {
  it('should work', async () => {
    const myTool = tool({
      name: 'test',
      description: 'Test tool',
      input: z.object({ value: z.number() }),
      output: z.object({ result: z.number() }),
      async handler(input, ctx) {
        return { result: input.value * 2 };
      },
    });

    // Create mock context
    const mockCtx = {
      secrets: {
        get: async () => undefined,
        require: async (k) => k
      },
      http: { get: async () => ({ data: {} }) },
      logger: { info: () => {}, error: () => {} },
      trace: { startSpan: () => ({ end: () => {} }) },
      metadata: { requestId: '123' },
    };

    const result = await myTool.execute({ value: 5 }, mockCtx);
    expect(result.result).toBe(10);
  });
});
```

## Deployment

**Nothing to do!** Builder + Runtime handle everything:

1. **Build**: `agentpack build` (or automatic via GitHub App)
2. **Deploy**: Automatic to Agentpack infrastructure
3. **Scale**: Automatic based on load
4. **Monitor**: Traces/logs in dashboard

### Configuration

Optional `agentpack.yaml` for advanced settings:

```yaml
version: 0.1
project: my-tools

agents:
  - name: default
    model: { provider: anthropic, name: claude-3-5-sonnet }
    tools: ["*"]  # All tools in tools/

resources:
  - name: stripe_secret
    type: secret
    source: vault://kv/stripe

policies:
  outbound_network:
    allow: ["*.stripe.com", "*.openai.com"]
```

## Thin SDK Philosophy

This SDK is **intentionally minimal**:
- ✅ `tool()` function for definitions
- ✅ `ExecutionContext` types
- ✅ Error classes
- ❌ NO server creation
- ❌ NO Docker setup
- ❌ NO deployment code

**All orchestration lives in Rust core** for:
- Consistent cross-language behavior
- Performance (Tower middleware)
- Security (policy enforcement)
- Observability (OpenTelemetry)

## Troubleshooting

### "Tool not found" error
- Ensure tool is in `tools/` directory
- Check file exports `default tool({...})`
- Verify `.agentpack-manifest.json` was generated

### Validation errors
- Check Zod schema matches input
- Use `.optional()` or `.default()` for optional fields
- Test with mock data

### Secret not found
- Configure secrets in Agentpack Dashboard
- Use correct secret key name
- Check environment variables in development

## Related Packages

- `@agentpack/runtime-typescript` - Internal gRPC runtime (private)
- `agentpack` - Python SDK (same zero-config approach)

## License

Copyright © 2025 North Cognitive Inc. All Rights Reserved.

This software is proprietary and confidential. Unauthorized copying, distribution, or use is strictly prohibited.