Metadata-Version: 2.4
Name: poke
Version: 0.2.0
Summary: Poke.com Developer SDK
Project-URL: Homepage, https://poke.com
Project-URL: Documentation, https://poke.com/docs
Project-URL: Repository, https://github.com/InteractionCo/poke
Author-email: Poke <poke@interaction.co>
License-Expression: MIT
License-File: LICENSE
Keywords: ai,assistant,poke,sdk,webhooks
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# poke

The official [Poke](https://poke.com) Python SDK for sending messages to your Poke agent, creating webhook triggers, and firing webhooks.

Built by [Interaction Company](https://poke.com) in California.

## Installation

```bash
pip install poke
```

Zero dependencies. Works with Python 3.8+.

## Quick start

```python
from poke import Poke

client = Poke(api_key="pk_...")

# Send a message to your agent
client.send_message("Summarize my unread emails")

# Create a webhook trigger
webhook = client.create_webhook(
    condition="When a deploy fails",
    action="Send me a summary of the error",
)

# Fire the webhook with data
client.send_webhook(
    webhook_url=webhook["webhookUrl"],
    webhook_token=webhook["webhookToken"],
    data={"event": "deploy_failed", "repo": "my-app", "error": "OOM killed"},
)
```

### Authentication

The SDK resolves credentials in this order:

1. `api_key` passed to the constructor
2. `POKE_API_KEY` environment variable
3. Credentials from `poke login` (`~/.config/poke/credentials.json`)

```python
# Option 1: Pass directly
client = Poke(api_key="pk_...")

# Option 2: Set POKE_API_KEY in your environment
client = Poke()

# Option 3: Run `poke login` first, then
client = Poke()
```

Get your API key at [poke.com/kitchen/api-keys](https://poke.com/kitchen/api-keys).

### Methods

#### `client.send_message(message)`

Send a text message to your Poke agent.

```python
result = client.send_message("What meetings do I have today?")
# {"success": True, "message": "..."}
```

#### `client.create_webhook(condition, action)`

Create a webhook trigger. Returns a `webhookUrl` and `webhookToken` that you use with `send_webhook`.

```python
webhook = client.create_webhook(
    condition="When a new user signs up",
    action="Send me a welcome summary in Slack",
)
# {
#     "triggerId": "...",
#     "webhookUrl": "https://poke.com/api/v1/inbound/webhook",
#     "webhookToken": "eyJhbG..."
# }
```

#### `client.send_webhook(webhook_url, webhook_token, data)`

Fire a webhook trigger with data. Use the `webhook_url` and `webhook_token` returned by `create_webhook`.

```python
client.send_webhook(
    webhook_url=webhook["webhookUrl"],
    webhook_token=webhook["webhookToken"],
    data={"event": "new_signup", "email": "user@example.com", "plan": "pro"},
)
# {"success": True}
```

### Configuration

| Option | Environment Variable | Default |
|--------|---------------------|---------|
| `api_key` | `POKE_API_KEY` | — |
| `base_url` | `POKE_API` | `https://poke.com/api/v1` |

### Error handling

```python
from poke import Poke, AuthenticationError, ForbiddenError, RateLimitError, PokeError

client = Poke()

try:
    client.send_message("hello")
except AuthenticationError:
    print("Bad API key")
except ForbiddenError:
    print("Key lacks required scopes")
except RateLimitError:
    print("Slow down")
except PokeError as e:
    print(f"API error ({e.status}): {e}")
```

## MCP Callback Sugar

For Python MCP server developers: `poke.mcp` lets long-running tools send asynchronous progress updates back to Poke. Requires Python 3.10+.

```bash
pip install poke fastmcp
```

```python
from poke.mcp import with_callbacks, PokeCallbackMiddleware
from fastmcp import FastMCP

mcp = FastMCP("my-server")

@mcp.tool()
@with_callbacks
async def deploy_and_notify(repo: str, branch: str):
    """Deploy a repo and send progress updates to Poke."""
    yield f"Starting deployment of {repo}@{branch}..."
    await run_deploy(repo, branch)
    yield f"Deploy complete. Running tests..."
    await run_tests(repo)
    yield f"All done!"  # last yield → sent with hasMore=False

# ASGI middleware extracts X-Poke-Callback-Token/Url headers
app = PokeCallbackMiddleware(mcp.http_app())
```

The **first yield** is returned immediately as the MCP tool result. Subsequent yields are POSTed to the Poke callback URL in the background. The **last yield** is sent with `hasMore=False` to signal completion.

If the request doesn't include callback headers, remaining yields are silently discarded — your tool still works as a normal single-response tool.

### Non-ASGI servers

For Flask, Django, or other frameworks, use `extract_callback_context` and `set_callback_context` manually:

```python
from poke.mcp import extract_callback_context, set_callback_context, reset_callback_context

ctx = extract_callback_context(dict(request.headers))
if ctx:
    token = set_callback_context(ctx)
    try:
        result = await my_tool(args)
    finally:
        reset_callback_context(token)
```

## Configuration

Credentials are stored in `~/.config/poke/credentials.json` (respects `$XDG_CONFIG_HOME`).

| Environment Variable | Description | Default |
|---------------------|-------------|---------|
| `POKE_API_KEY` | API key for SDK usage | — |
| `POKE_API` | API base URL | `https://poke.com/api/v1` |
