Rhai Scripting

Customize Apollo MCP Server behavior with Rhai scripts


Apollo MCP Server supports Rhai, a lightweight embedded scripting language. Rhai scripts let you hook into the server's request lifecycle to inspect and modify outgoing GraphQL requests without needing to recompile or rebuild the server.

Common use-cases include:

  • Forwarding authentication headers from incoming MCP requests to your GraphQL endpoint

  • Routing requests to different GraphQL endpoints based on request properties

  • Rejecting requests that don't meet certain criteria

Security

caution
Treat Rhai scripts as trusted code, not as a security sandbox. The server loads scripts from the configured directory and runs their lifecycle hooks while processing requests. Scripts can read server environment variables, make outbound HTTP requests, and change the endpoint or headers of an outgoing GraphQL request.Restrict write access to the script directory, require review before deploying script changes, and monitor outbound destinations. Incoming MCP request metadata is provided to hooks as data rather than compiled as Rhai source, but a script can still copy or interpolate that metadata into headers, URLs, logs, or HTTP request bodies. Validate and allow values from an allowlist before using them.

Setup

Create a rhai/ directory in the server's working directory, and add a main.rhai file inside it:

Text
1your-project/
2├── config.yaml
3└── rhai/
4    └── main.rhai

The rhai/main.rhai file is the entry point for all Rhai scripting. The server loads the file on startup. If the file doesn't exist, the server starts normally, without any scripting.

To load scripts from a different directory, set rhai.scripts in your configuration file:

YAML
mcp.yaml
1rhai:
2  scripts: /config/rhai

Writing your first hook

Hooks are regular Rhai functions with specific names. When a lifecycle event occurs on the server, it calls the matching function if one is defined.

This example adds a custom header to every outgoing GraphQL request:

Rhai
1fn on_execute_graphql_operation(ctx) {
2    ctx.headers["x-custom-header"] = "my-value";
3}

For a full list of available hooks and their context objects, see Lifecycle Hooks.

Logging

Rhai's built-in print and debug statements write to the server's log output. Use them to debug your scripts:

Rhai
1fn on_execute_graphql_operation(ctx) {
2    print("Outgoing request to: " + ctx.endpoint);
3}

Global variables

Variables defined at the top level of main.rhai persist across all hook invocations. Use it to store the configuration or state that your hooks need:

Rhai
1// Top-level variables persist across hook calls
2let api_key = Env::get("MY_API_KEY");
3
4fn on_execute_graphql_operation(ctx) {
5    ctx.headers["x-api-key"] = api_key;
6}

Modules

Organize your scripts into multiple files using Rhai's module system. Place additional .rhai files in the rhai/ directory and import them:

Rhai
1// rhai/main.rhai
2import "helpers" as helpers;
3
4fn on_execute_graphql_operation(ctx) {
5    helpers::add_auth_headers(ctx);
6}
Rhai
1// rhai/helpers.rhai
2fn add_auth_headers(ctx) {
3    ctx.headers["authorization"] = "Bearer " + Env::get("AUTH_TOKEN");
4}

Next steps