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

# Apify Actors

> Add Agnost AI analytics to your Apify Actors

## What are Apify Actors?

[Apify Actors](https://docs.apify.com/platform/actors) are serverless cloud programs that can perform anything from a simple action, like filling out a web form, to a complex operation, like crawling an entire website. They are programs packaged as Docker images, which accept a well-defined JSON input, perform an action, and optionally produce a well-defined JSON output.

### Key Features

* **Serverless Execution**: No infrastructure management required, just deploy and run
* **Stateful Operations**: Actors can maintain state across executions, enabling runs from seconds to hours, or even indefinitely
* **Flexible I/O**: Accept JSON input and produce JSON output with well-defined schemas
* **Built-in Storage**: Access to datasets, key-value stores, and request queues
* **Composable**: Actors can call and interact with each other to build complex systems

### Actor Structure

Each Apify Actor consists of:

1. **Dockerfile**: Manages code location, build process, and execution instructions
2. **Source Code**: Your application logic (Python, Node.js, or other languages)
3. **Input/Output Schemas**: Define required inputs and produced results
4. **README Documentation**: Explains functionality for users
5. **Metadata**: Actor name, description, author, and version

Actors can be run via the web console, API, CLI, or scheduled triggers. They can be private for personal use or published to the [Apify Store](https://apify.com/store) for monetization.

Learn more: [Apify Actors Development](https://docs.apify.com/platform/actors/development)

## Getting Started

Add Agnost analytics to your Apify Actor in four simple steps:

### 1. Get Your Organization ID

Get your organization ID from [app.agnost.ai](https://app.agnost.ai)

### 2. Install Agnost

<Tabs>
  <Tab title="Python">
    ```bash theme={null}
    pip install agnost-mcp
    ```
  </Tab>

  <Tab title="Node.js">
    ```bash theme={null}
    npm install agnost
    ```
  </Tab>
</Tabs>

### 3. Add One Line of Code

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from apify import Actor
    from agnost_mcp import track
    from mcp.server import Server

    async def main():
        async with Actor:
            # Create MCP server
            server = Server("your-mcp-server")

            # Enable analytics
            track(server, "your-org-id")

            # Your actor logic here
            actor_input = await Actor.get_input() or {}
            # ... rest of your code
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    import { Actor } from 'apify';
    import { Server } from '@modelcontextprotocol/sdk/server/index.js';
    import { trackMCP } from 'agnost';

    await Actor.main(async () => {
        // Create MCP server
        const server = new Server({ name: 'your-mcp-server', version: '1.0.0' },
                                   { capabilities: { tools: {} } });

        // Enable analytics
        trackMCP(server, "your-org-id");

        // Your actor logic here
        const input = await Actor.getInput();
        // ... rest of your code
    });
    ```
  </Tab>
</Tabs>

That's it! Your Apify Actor is now tracked with default settings.

### 4. View Metrics

Visit [app.agnost.ai](https://app.agnost.ai) to view your analytics:

* Monitor Actor runs in real-time
* Track performance and latency
* Analyze success and failure rates
* Identify optimization opportunities

## Configuration

Customize tracking behavior with configuration options:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from agnost_mcp import track, config
    from mcp.server import Server

    server = Server("your-mcp-server")

    track(server, "your-org-id", config(
        endpoint="https://api.agnost.ai",
        disable_input=False,
        disable_output=False
    ))
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    import { Server } from '@modelcontextprotocol/sdk/server/index.js';
    import { trackMCP, createConfig } from 'agnost';

    const server = new Server({ name: 'your-mcp-server', version: '1.0.0' },
                               { capabilities: { tools: {} } });

    trackMCP(server, "your-org-id", createConfig({
      endpoint: "https://api.agnost.ai",
      disableInput: false,
      disableOutput: false
    }));
    ```
  </Tab>
</Tabs>

### Configuration Options

| Option                             | Type     | Default                   | Description                                                                                                                       |
| ---------------------------------- | -------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `endpoint`                         | string   | `"https://api.agnost.ai"` | API endpoint URL                                                                                                                  |
| `disable_input` / `disableInput`   | boolean  | `false`                   | Disable tracking of input parameters                                                                                              |
| `disable_output` / `disableOutput` | boolean  | `false`                   | Disable tracking of output responses                                                                                              |
| `log_level`                        | string   | `"INFO"`                  | Python only. Log verbosity: `DEBUG`, `INFO`, `WARNING`, `ERROR`                                                                   |
| `identify`                         | function | `None` / `undefined`      | Function `(request, env) → UserIdentity` to identify users from request context. See [user identification](#user-identification). |

`UserIdentity` is a `dict` (Python) or object (Node) that **must contain a `userId` key**. Other fields (e.g. `email`, `role`) are optional and forwarded as user traits.

## User Identification

Track analytics per user to understand usage patterns across different customers or organizations running your Actor.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from agnost_mcp import track, config
    from mcp.server import Server

    async def main():
        async with Actor:
            server = Server("your-mcp-server")

            # With user identification
            track(server, "your-org-id", config(
                identify=lambda req, env: {
                    "userId": env.get("APIFY_USER_ID") or "anonymous",
                    "actorId": env.get("APIFY_ACT_ID"),
                    "runId": env.get("APIFY_ACT_RUN_ID"),
                }
            ))

            # Your actor logic here
    ```

    Using Actor input for identification:

    ```python theme={null}
    from agnost_mcp import track, config
    from mcp.server import Server

    async def main():
        async with Actor:
            actor_input = await Actor.get_input() or {}
            server = Server("your-mcp-server")

            track(server, "your-org-id", config(
                identify=lambda req, env: {
                    "userId": actor_input.get("customer_id", "anonymous"),
                    "email": actor_input.get("customer_email"),
                    "organization": actor_input.get("organization_name"),
                }
            ))

            # Your actor logic here
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    import { Actor } from 'apify';
    import { Server } from '@modelcontextprotocol/sdk/server/index.js';
    import { trackMCP } from 'agnost';

    await Actor.main(async () => {
        const server = new Server({ name: 'your-mcp-server', version: '1.0.0' },
                                   { capabilities: { tools: {} } });

        // With user identification
        trackMCP(server, "your-org-id", {
            identify: (req, env) => ({
                userId: env.APIFY_USER_ID || 'anonymous',
                actorId: env.APIFY_ACT_ID,
                runId: env.APIFY_ACT_RUN_ID
            })
        });

        // Your actor logic here
    });
    ```

    Using Actor input for identification:

    ```javascript theme={null}
    import { Actor } from 'apify';
    import { Server } from '@modelcontextprotocol/sdk/server/index.js';
    import { trackMCP } from 'agnost';

    await Actor.main(async () => {
        const input = await Actor.getInput();
        const server = new Server({ name: 'your-mcp-server', version: '1.0.0' },
                                   { capabilities: { tools: {} } });

        trackMCP(server, "your-org-id", {
            identify: (req, env) => ({
                userId: input.customer_id || 'anonymous',
                email: input.customer_email,
                organization: input.organization_name
            })
        });

        // Your actor logic here
    });
    ```
  </Tab>
</Tabs>

### Common Use Cases

* **Multi-tenant Actors**: Track which customer or organization is using the Actor
* **Subscription Tiers**: Segment analytics by free, pro, or enterprise users
* **Cost Attribution**: Understand usage and costs per customer
* **Customer Success**: Monitor individual customer health and engagement

See the full [Configuration guide](/configuration) for more advanced identification patterns.

## Complete Example

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from apify import Actor
    from agnost_mcp import track, config
    from mcp.server import Server

    async def main():
        async with Actor:
            actor_input = await Actor.get_input() or {}

            # Create MCP server
            server = Server("your-mcp-server")

            # Enable analytics with user identification
            track(server, "your-org-id", config(
                identify=lambda req, env: {
                    "userId": actor_input.get("customer_id", "anonymous"),
                    "organization": actor_input.get("org_name"),
                    "subscriptionTier": actor_input.get("tier", "free"),
                }
            ))

            # Your actor logic
            url = actor_input.get('url')
            Actor.log.info(f'Scraping URL: {url}')

            # Scraping logic
            data = []  # ... scrape data

            # Save results
            await Actor.push_data(data)

            Actor.log.info(f'Successfully scraped {len(data)} items')
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    import { Actor } from 'apify';
    import { Server } from '@modelcontextprotocol/sdk/server/index.js';
    import { trackMCP } from 'agnost';

    await Actor.main(async () => {
        const input = await Actor.getInput();

        // Create MCP server
        const server = new Server({ name: 'your-mcp-server', version: '1.0.0' },
                                   { capabilities: { tools: {} } });

        // Enable analytics with user identification
        trackMCP(server, "your-org-id", {
            identify: (req, env) => ({
                userId: input.customer_id || 'anonymous',
                organization: input.org_name,
                subscriptionTier: input.tier || 'free'
            })
        });

        // Your actor logic
        const { url } = input;
        console.log(`Scraping URL: ${url}`);

        // Scraping logic
        const data = [];  // ... scrape data

        // Save results
        await Actor.pushData(data);

        console.log(`Successfully scraped ${data.length} items`);
    });
    ```
  </Tab>
</Tabs>

## Why Add Analytics to Your Actor?

### Performance Optimization

* Identify slow operations and bottlenecks
* Track execution time trends over versions
* Optimize resource usage and costs

### Usage Insights

* Monitor how customers use your Actor
* Understand which features are most popular
* Identify usage patterns and trends

### Error Tracking

* Track failure rates and error patterns
* Debug issues faster with detailed context
* Monitor service reliability

### Business Intelligence

* Segment users by subscription tier
* Track adoption and retention
* Make data-driven decisions for features and pricing

## Resources

* [Configuration Guide](/configuration): Advanced configuration options
* [Apify Actors Documentation](https://docs.apify.com/platform/actors): Learn about Apify Actors
* [Apify Actors Development](https://docs.apify.com/platform/actors/development): Development guide

## Need Help?

* Email: [founders@agnost.ai](mailto:founders@agnost.ai)
* [Book a call](https://call.agnost.ai/)
