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

Setup

Create a rhai/ directory alongside your server configuration, 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.

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

Feedback

Edit on GitHub

Ask Community