# Model Context Protocol Server

> Turns scripts into Model Context Protocol Tools

![Logo of the Model Context Protocol project.](/genaiscript/_astro/mcp.CBnQ_GM8_1eWG7e.webp)

The [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) defines a protocol that allows to share [tools](https://modelcontextprotocol.io/docs/concepts/tools) and consume them regardless of the underlying framework/runtime.

**GenAIScript implements a server that turns scripts into MCP tools**.

Tip

GenAIScript also implements a client for MCP tools which allows you to consume MCP tools in script. See [MCP tools](/genaiscript/reference/scripts/mcp-tools) for more details.

## Scripts as MCP Tools

[Section titled “Scripts as MCP Tools”](#scripts-as-mcp-tools)

GenAIScript launches a MCP server that exposes each GenAIScript script as a MCP tool (not to be confused with `defTool`).

The MCP tool description is the script description. **Make sure to carefully craft the description** as it is how the LLM decides which tool to use when running a script. If your tool does not get picked up by the LLM, it’s probably a description issue.

The MCP tool parameters is inferred from the [script parameters](/genaiscript/reference/scripts/parameters) and files automatically. The MCP parameters will then populate the `env.vars` object in the script as usual.

The MCP tool output is the script output. That is, typically, the last assistant message for a script that uses the top-level context. Or any content that was passed in [env.output](/genaiscript/reference/scripts/output-builder).

Let’s see an example. Here is a script `task.genai.mjs` that takes a `task` parameter input, builds a prompt and the LLM output is sent back.

task.genai.mjs

```js
script({
    description: "You MUST provide a description!",
    parameters: {
        task: {
            type: "string",
            description: "The task to perform",
            required: true
        }
    }
})


const { task } = env.vars // extract the task parameter


... // genaiscript logic
$`... prompt ... ${task}` // output the result
```

A more advanced script might not use the top-level context and instead use the `env.output` to pass the result.

task.genai.mjs

```js
script({
    description: "You MUST provide a description!",
    accept: "none", // this script does not use 'env.files'
    parameters: {
        task: {
            type: "string",
            description: "The task to perform",
            required: true
        }
    }
})


const { output } = env // store the output builder
const { task } = env.vars // extract the task parameter


... // genaiscript logic with inline prompts
const res = runPrompt(_ => `... prompt ... ${task}`) // run some inner the prompt
...


// build the output
output.fence(`The result is ${res.text}`)
```

### Sampling

[Section titled “Sampling”](#sampling)

Clients that support [Sampling](https://modelcontextprotocol.io/docs/concepts/sampling) will allow servers to request completions from LLMs. Recently, Visual Studio Code Copilot Chat has added support for MCP tools sampling.

In GenAIScript script, you can use the `mcp` llm provider to explicitly use the MCP tool sampling.

task.genai.mjs

```js
script({ model: "mcp:claude" });
```

The model name (`claude`) is a hint for the client which LLM to use for sampling. It is just a hint and the client may decide to use a different LLM. This provider is only available when the script is run as a MCP tool with a client that supports sampling.

### Annotations

[Section titled “Annotations”](#annotations)

[Tool annotations](https://modelcontextprotocol.io/docs/concepts/tools#tool-annotations) provide additional metadata about a tool’s behavior, helping clients understand how to present and manage tools. These annotations are hints that describe the nature and impact of a tool, but should not be relied upon for security decisions.

```js
script({
    ...,
    annotations: {
        readOnlyHint: true,
        openWorldHint: true,
    },
})
```

* `title` is populated from the script title.
* `readOnlyHint`: `boolean`, default: `false`\
  If true, indicates the tool does not modify its environment.
* `destructiveHint`: `boolean`, default: `true`\
  If true, the tool may perform destructive updates (only meaningful when `readOnlyHint` is false).
* `idempotentHint`: `boolean`, default: `false`\
  If true, calling the tool repeatedly with the same arguments has no additional effect (only meaningful when `readOnlyHint` is false).
* `openWorldHint`: `boolean`, default: `true`\
  If true, the tool may interact with an “open world” of external entities.

## Resources

[Section titled “Resources”](#resources)

[Resources](https://modelcontextprotocol.io/docs/concepts/resources) are a core primitive in the Model Context Protocol (MCP) that allow servers to expose data and content that can be read by clients and used as context for LLM interactions.

### Publishing Resources

[Section titled “Publishing Resources”](#publishing-resources)

In GenAIScript, you can create a resource using `host.publishResource` and it will automatically be exposed as a MCP resource.

task.genai.mjs

```js
const id = await host.publishResource("important data", file);
```

The return value is the resource uri which can be used in the prompt output. `publishResource` supports files, buffers and strings.

The resource will be available for the lifetime of the MCP server.

### Reading Resources with Tools

[Section titled “Reading Resources with Tools”](#reading-resources-with-tools)

GenAIScript provides built-in tools for working with resources through the `system.resources` system script:

* **`resource_list`**: List available resources from the host. Returns a list of available resource URIs and their descriptions.
* **`resource_read`**: Read the content of a resource from a URL. Resolves various protocols and returns the content of the files found at the URL.

These tools support various protocols including HTTPS, file, git, gist, and VSCode URLs using the host’s `resolveResource` function.

script-using-resources.genai.mjs

```js
script({
    title: "Script that uses resource tools",
    system: ["system.resources"]
})


$`Use the resource_read tool to read content from https://raw.githubusercontent.com/microsoft/genaiscript/main/README.md`
```

The `resource_read` tool automatically handles:

* **Protocol Support**: HTTPS URLs, GitHub blob URLs, Git repositories, Gists, VSCode URLs
* **Content Formatting**: Returns well-formatted output with file headers and code blocks
* **Binary Content**: Detects base64 encoding and provides appropriate metadata
* **Multiple Files**: Supports URLs that resolve to multiple files (e.g., repository directories)

### Images

[Section titled “Images”](#images)

Using `env.output.image`, script can output images that will be part of the tool response.

```js
await env.output.image("...filename.png");
```

### Secret scanning

[Section titled “Secret scanning”](#secret-scanning)

GenAIScript has a built-in [secret scanning feature](/genaiscript/reference/scripts/secret-scanning) that will scan your resources for secrets. To turn off the secret scanning feature, you can set the `secretScanning` option to `false` in `publishResource`.

```js
const id = await host.publishResource("important data", file, {
  secretScanning: false,
});
```

## Startup script

[Section titled “Startup script”](#startup-script)

You can specify a startup script id in the command line using the `--startup` option. It will run after the server is started.

```sh
genaiscript mcp --startup load-resources
```

## Transport Options

[Section titled “Transport Options”](#transport-options)

The MCP server supports two transport methods:

### Stdio Transport (Default)

[Section titled “Stdio Transport (Default)”](#stdio-transport-default)

The default transport uses stdio (standard input/output) for communication. This is the standard way to run MCP servers with most clients.

```sh
genaiscript mcp
```

### HTTP Transport

[Section titled “HTTP Transport”](#http-transport)

You can also run the MCP server with HTTP transport using the `--http` flag:

```sh