|
| 1 | +# Functions as Tools |
| 2 | + |
| 3 | +The "Functions as Tools" feature allows the StreamNative MCP Server to dynamically discover Apache Pulsar Functions deployed in your cluster and expose them as invokable MCP tools for AI agents. This significantly enhances the capabilities of AI agents by allowing them to interact with custom business logic encapsulated in Pulsar Functions without manual tool registration for each function. |
| 4 | + |
| 5 | +## How it Works |
| 6 | + |
| 7 | +### 1. Function Discovery |
| 8 | +The MCP Server automatically discovers Pulsar Functions available in the connected Pulsar cluster. It periodically polls for functions and identifies those suitable for exposure as tools. |
| 9 | + |
| 10 | +By default, if no custom name is provided (see Customizing Tool Properties), the MCP tool name might be derived from the Function's Fully Qualified Name (FQN), such as `pulsar_function_$tenant_$namespace_$name`. |
| 11 | + |
| 12 | +### 2. Schema Conversion |
| 13 | +For each discovered function, the MCP Server attempts to extract its input and output schema definitions. Pulsar Functions can be defined with various schema types for their inputs and outputs (e.g., primitive types, AVRO, JSON). |
| 14 | + |
| 15 | +The server then converts these native Pulsar schemas into a format compatible with MCP tools. This allows the AI agent to understand the expected input parameters and the structure of the output. |
| 16 | + |
| 17 | +Supported Pulsar schema types for automatic conversion include: |
| 18 | +* Primitive types (String, Boolean, Numbers like INT8, INT16, INT32, INT64, FLOAT, DOUBLE) |
| 19 | +* AVRO |
| 20 | +* JSON |
| 21 | + |
| 22 | +If a function uses an unsupported schema type for its input or output, or if schemas are not clearly defined, it might not be exposed as an MCP tool. |
| 23 | + |
| 24 | +## Enabling the Feature |
| 25 | +To enable this functionality, you need to specific the default `--pulsar-instance` and `--pulsar-cluster`, and include `functions-as-tools` in the `--features` flag when starting the StreamNative MCP Server. |
| 26 | + |
| 27 | +Example: |
| 28 | +```bash |
| 29 | +snmcp stdio --organization my-org --key-file /path/to/key-file.json --features pulsar-admin,pulsar-client,functions-as-tools --pulsar-instance instance --pulsar-cluster cluster |
| 30 | +``` |
| 31 | +If `functions-as-tools` is part of a broader feature set like `all` and `streamnative-cloud`, enabling `all` or `streamnative-cloud` would also activate this feature. |
| 32 | + |
| 33 | +## Customizing Tool Properties |
| 34 | +You can customize how your Pulsar Functions appear as MCP tools (their name and description) by providing specific runtime options when deploying or updating your functions. This is done using the `--custom-runtime-options` flag with `pulsar-admin functions create` or `pulsar-admin functions update`. |
| 35 | + |
| 36 | +The MCP Server looks for the following environment variables within the custom runtime options: |
| 37 | +* `MCP_TOOL_NAME`: Specifies the desired name for the MCP tool. |
| 38 | +* `MCP_TOOL_DESCRIPTION`: Provides a description for the MCP tool, which helps the AI agent understand its purpose. |
| 39 | + |
| 40 | +**Format for `--custom-runtime-options`**: |
| 41 | +The options should be a JSON string where you define an `env` map containing `MCP_TOOL_NAME` and `MCP_TOOL_DESCRIPTION`. |
| 42 | + |
| 43 | +**Example**: |
| 44 | +When deploying a Pulsar Function, you can set these properties as follows: |
| 45 | +```bash |
| 46 | +pulsar-admin functions create \ |
| 47 | + --tenant public \ |
| 48 | + --namespace default \ |
| 49 | + --name my-custom-logic-function \ |
| 50 | + --inputs "persistent://public/default/input-topic" \ |
| 51 | + --output "persistent://public/default/output-topic" \ |
| 52 | + --py my_function.py \ |
| 53 | + --classname my_function.MyFunction \ |
| 54 | + --custom-runtime-options \ |
| 55 | + ''' |
| 56 | + { |
| 57 | + "env": { |
| 58 | + "MCP_TOOL_NAME": "CustomObjectFunction", |
| 59 | + "MCP_TOOL_DESCRIPTION": "Takes an input number and returns the value incremented by 100." |
| 60 | + } |
| 61 | + } |
| 62 | + ''' |
| 63 | +``` |
| 64 | +In this example: |
| 65 | +- The MCP tool derived from `my-custom-logic-function` will be named `CustomObjectFunction`. |
| 66 | +- Its description will be "Takes an input number and returns the value incremented by 100." |
| 67 | + |
| 68 | +If these custom options are not provided, the MCP tool name might default to a derivative of the function's FQN, and the description might be generic and cannot help AI Agent to understand the purpose of the MCP tool. |
| 69 | + |
| 70 | +## Considerations and Limitations |
| 71 | + |
| 72 | +* **Schema Definition**: For reliable schema conversion, ensure your Pulsar Functions have clearly defined input and output schemas using Pulsar's schema registry capabilities. Functions with ambiguous or `BYTES` schemas might not be converted effectively or might default to generic byte array inputs/outputs. |
| 73 | +* **Function State**: This feature primarily focuses on the stateless request/response invocation pattern of functions. |
| 74 | +* **Discovery Latency**: There might be a slight delay between deploying/updating a function and it appearing as an MCP tool, due to the server's polling interval for function discovery. |
| 75 | +* **Error Handling**: The MCP Server will attempt to relay errors from function executions, but the specifics might vary. |
| 76 | +* **Security**: Ensure that only intended functions are exposed by managing permissions within your Pulsar cluster. The MCP Server will operate with the permissions of its Pulsar client. |
0 commit comments