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

# Plugins (JavaScript)

> The Hedera Agent Kit implements a plugin architecture to include features and functionality for both Hedera Network functions and Services, as well as third party apps and projects.

## Summary

### Available Third-Party Plugins

* [Memejob Plugin](https://www.npmjs.com/package/@buidlerlabs/hak-memejob-plugin) provides a streamlined interface to the [**memejob**](https://memejob.fun/) protocol, exposing the core actions (`create`, `buy`, `sell`) for interacting with meme tokens on Hedera. See the [**GitHub repository**](https://github.com/buidler-labs/hak-memejob-plugin) for more information.

***

## Plugin Architecture

The tools are organized into plugins, each containing a set of functionality related to the Hedera service or project they are created for.

### Plugin Interface

Every plugin must implement the Plugin interface:

```typescript theme={null}
export interface Plugin {
  name: string;
  version?: string;
  description?: string;
  tools: (context: Context) => Tool[];
}
```

### Tool Interface

Each tool must implement the Tool interface:

```typescript theme={null}
export type Tool = {
  method: string;
  name: string;
  description: string;
  parameters: z.ZodObject<any, any>;
  execute: (client: Client, context: Context, params: any) => Promise<any>;
  // transactionToolOutputParser and untypedQueryOutputParser can be used. If required, define a custom parser
  outputParser?: (rawOutput: string) => { raw: any; humanMessage: string };
};
```

> **Note:** The `outputParser` is important for **LangChain v1** tools. It extracts tool output into `{ raw, humanMessage }` format. Two built-in parsers are available:
>
> * `transactionToolOutputParser` - For transaction tools (handles RETURN\_BYTES and EXECUTE\_TRANSACTION modes)
> * `untypedQueryOutputParser` - For query tools (generic parser)
>
> If not defined, a default parser is used.

See [typescript/src/shared/tools.ts](https://github.com/hashgraph/hedera-agent-kit-js/blob/main/typescript/src/shared/tools.ts) for the full definition.

***

## Step-by-Step Guide

### **Step 1: Create Plugin Directory Structure**

```
  my-custom-plugin/
  ├── index.ts                    # Plugin definition and exports
  ├── tools/
  │   └── my-service/
  │       └── my-tool.ts         # Individual tool implementation
```

### **Step 2: Implement Your Tool**

Create your tool file (e.g., `tools/my-service/my-tool.ts`):

```typescript theme={null}
  import { z } from 'zod';
  import { Context, Tool, handleTransaction } from 'hedera-agent-kit';
  import { Client, PrivateKey, AccountId } from '@hashgraph/sdk';
  import dotenv from 'dotenv';
  
  // Load environment variables
  dotenv.config();

  // Define parameter schema
  const myToolParameters = (context: Context = {}) =>
    z.object({
      requiredParam: z.string().describe('Description of required parameter'),
      optionalParam: z.string().optional().describe('Description of optional parameter'),
    });

  // Create prompt function
  const myToolPrompt = (context: Context = {}) => {
    return `
  This tool performs a specific operation.

  Parameters:
  - requiredParam (string, required): Description
  - optionalParam (string, optional): Description
  `;
  };

  // Implement tool logic
  const myToolExecute = async (
    client: Client,
    context: Context,
    params: z.infer<ReturnType<typeof myToolParameters>>,
  ) => {
    try {
      // Your implementation here
      const result = await someHederaOperation(params);
      return result;
    } catch (error) {
      if (error instanceof Error) {
        return error.message;
      }
      return 'Operation failed';
    }
  };

  export const MY_TOOL = 'my_tool';

  const tool = (context: Context): Tool => ({
    method: MY_TOOL,
    name: 'My Custom Tool',
    description: myToolPrompt(context),
    parameters: myToolParameters(context),
    execute: myToolExecute,
  });

  export default tool;
```

### **Step 3: Create Plugin Definition**

Create your plugin index file (index.ts):

```typescript index.ts theme={null}
import { Context } from '@/shared';
import { Plugin } from '@/shared/plugin';
import myTool, { MY_TOOL } from './tools/my-service/my-tool';

export const myCustomPlugin: Plugin = {
  name: 'my-custom-plugin',
  version: '1.0.0',
  description: 'A plugin for custom functionality',
  tools: (context: Context) => {
    return [myTool(context)];
  },
};

export const myCustomPluginToolNames = {
  MY_TOOL,
} as const;

export default { myCustomPlugin, myCustomPluginToolNames }; 
```

### Step 4: Register Your Plugin

Add your plugin to the main plugins index (`src/plugins/index.ts`):

```typescript theme={null}
import { myCustomPlugin, myCustomPluginToolNames } from './my-custom-plugin';

export {
// ... existing exports
  myCustomPlugin,
  myCustomPluginToolNames,
};
```

### **Best Practices**

**Parameter Validation**

* Use Zod schemas for robust input validation
* Provide clear descriptions for all parameters
* Mark required vs optional parameters appropriately

**Tool Organization**

* Group related tools by service type
* Use consistent naming conventions
* Follow the established directory structure

**Transaction Handling**

* Use handleTransaction() to facilitate human-in-the-loop and autonomous execution flows
* Respect the AgentMode (AUTONOMOUS vs. RETURN\_BYTES)
* Implement proper transaction building patterns

***

## Using Your Custom Plugin

### LangChain v0.3 (Classic)

```typescript theme={null}
import { HederaLangchainToolkit } from "hedera-agent-kit";
import {
  myCustomPlugin,
  myCustomPluginToolNames,
} from "./plugins/my-custom-plugin";

const toolkit = new HederaLangchainToolkit({
  client,
  configuration: {
    tools: [myCustomPluginToolNames.MY_TOOL],
    plugins: [myCustomPlugin],
    context: {
      mode: AgentMode.AUTONOMOUS,
    },
  },
});
```

### LangChain v1 (New)

```typescript theme={null}
import { HederaLangchainToolkit, ResponseParserService } from "hedera-agent-kit";
import {
  myCustomPlugin,
  myCustomPluginToolNames,
} from "./plugins/my-custom-plugin";

// Initialize toolkit
const toolkit = new HederaLangchainToolkit({
  client,
  configuration: {
    tools: [myCustomPluginToolNames.MY_TOOL],
    plugins: [myCustomPlugin],
    context: {
      mode: AgentMode.AUTONOMOUS,
    },
  },
});

// Initialize response parser
const responseParsingService = new ResponseParserService(toolkit.getTools());

// ... inside your agent loop ...
const response = await agent.invoke({ messages: [/* ... */] });

// Parse tool outputs
const parsedToolData = responseParsingService.parseNewToolMessages(response);
const toolCall = parsedToolData[0]; // assuming only one tool was called

if (toolCall) {
  console.log('Human Message:', toolCall.parsedData.humanMessage);
  console.log('Raw Data:', toolCall.parsedData.raw);
}
```

***

## Publish and Register Your Plugin

See [How To: Publish & Register Your Plugin](/solutions/ai/agent-kit/js/create-plugins) for instructions on creating, publishing, and registering your plugin with the Hedera Agent Kit ecosystem.

***

## Examples and References

* See existing core plugins in [typescript/src/plugins/core-\*-plugin/](https://github.com/hashgraph/hedera-agent-kit-js/tree/main/typescript/src/plugins)
* Follow the patterns established in tools like [transfer-hbar.ts](https://github.com/hashgraph/hedera-agent-kit-js/blob/main/typescript/src/plugins/core-account-plugin/tools/account/transfer-hbar.ts)
* See [plugin-tool-calling-agent.ts](https://github.com/hashgraph/hedera-agent-kit-js/blob/main/typescript/examples/langchain-v1/plugin-tool-calling-agent.ts) for usage examples
