# Architecture Source: https://docs.director.run/concepts/architecture Understand the main components of the middleware. Director is a service that sits between your AI agents and MCP servers. It acts as a middleware for organizing and managing MCP capabilities. It's transparent to clients, requiring no additional tokens or configuration changes. ## Core Concepts ### Playbooks A **playbook** is a set of tools, prompts, and configuration that gives your AI agent new skills. Think of playbooks as portable, declarative skill sets that can be: * Shared across teams via version control (YAML files) * Connected to multiple clients (Claude, Cursor, VSCode) with 1-click * Configured to include only the tools needed for specific tasks * Enforced declaratively (like Terraform for AI agents) ### Gateway The `Gateway` implements a proxy pattern in order to: * Aggregate multiple MCP servers into a single playbook endpoint * Support all MCP transports (HTTP Streamable, Stdio, SSE) * Provide tool filtering to preserve context * Offer unified OAuth for centralized authentication ### Client Integration Director provides multiple ways to connect MCP clients: * **1-Click Integration**: Automatically configure Claude, Cursor, or VSCode via the `ClientConfigurator` * **Manual Integration**: Use standard MCP connection details for any MCP-compliant client * **Declarative Mapping**: Define client-to-playbook connections in config that are enforced on startup ## Management Interfaces Director can be managed through multiple interfaces: * [CLI](../concepts/cli): Primary management tool (npm installable) - `director serve`, `director create`, etc. * [Studio](../concepts/studio): Web interface for visual playbook and server management * **SDK**: Programmatic control via TypeScript SDK for advanced use cases * **Config File**: Direct YAML editing at `~/.director/director.config.yaml` ## Architecture Components * **Gateway**: Core service that runs the playbooks and serves MCP clients * **Controller**: HTTP API (TRPC) for dynamic playbook management * **ClientConfigurator**: Automates client connection setup without manual JSON editing * **Registry**: Discover and add MCP servers from the community registry # CLI Reference Source: https://docs.director.run/concepts/cli The CLI, along with the [Studio](./studio), are the primary ways to interact with director. The CLI is distributed as a standalone package, and can be installed via [npm](https://www.npmjs.com/package/@director.run/cli). # Installation ```bash theme={null} $ curl -LsSf https://director.run/install.sh | sh ``` # Usage ```bash theme={null} $ director --help Playbooks for your AI agent USAGE director [subcommand] [flags] CORE COMMANDS quickstart Start the gateway and open the studio in your browser serve Start the web service studio Open the UI in your browser ls List playbooks get [serverName] Show playbook details auth Authenticate a server create Create a new playbook destroy Delete a playbook connect [options] Connect a playbook to a MCP client disconnect [options] Disconnect a playbook from an MCP client add [options] Add a server to a playbook remove Remove a server from a playbook update [serverName] [options] Update playbook attributes http2stdio Proxy an HTTP connection (sse or streamable) to a stdio stream env [options] Print environment variables status Get the status of the director REGISTRY registry ls List all available servers in the registry registry get Get detailed information about a registry item registry readme Print the readme for a registry item MCP mcp list-tools List tools on a playbook mcp get-tool Get the details of a tool mcp call-tool [options] Call a tool on a playbook PROMPTS prompts ls List all prompts for a playbook prompts add Add a new prompt to a playbook prompts edit Edit an existing prompt prompts remove Remove a prompt from a playbook prompts get Show the details of a specific prompt FLAGS -V, --version output the version number EXAMPLES $ director create my-playbook Create a new playbook $ director add my-playbook --entry fetch Add a server to a playbook $ director connect my-playbook --target claude Connect my-playbook to claude ``` # Examples ## Start the gateway ```bash theme={null} $ director serve _ _ _ | (_) | | __| |_ _ __ ___ ___| |_ ___ _ __ / _' | | '__/ _ \/ __| __/ _ \| '__| | (_| | | | | __/ (__| || (_) | | \__,_|_|_| \___|\___|\__\___/|_| [18:16:21] INFO (Gateway): starting director gateway [18:16:21] INFO (Gateway): director gateway running on port 3673 ``` ## Create a playbook ```bash theme={null} $ director create my-first-playbook playbook my-first-playbook created ``` ## Add a server to the playbook ```bash theme={null} $ director add my-first-playbook --entry fetch adding fetch to my-first-playbook ✔ Entry fetched. ✔ Registry entry fetch added to my-first-playbook ``` ## Connect the playbook to a client ```bash theme={null} # connect the playbook to Claude automatically $ director connect my-first-playbook -t claude [18:19:06] INFO (client-configurator/claude): reading config from /Users/barnaby/Library/Application Support/Claude/claude_desktop_config.json [18:19:06] INFO (client-configurator/claude): installing my-first-playbook [18:19:06] INFO (client-configurator/claude): writing config to /Users/barnaby/Library/Application Support/Claude/claude_desktop_config.json [18:19:06] INFO (client-configurator/claude): restarting claude [18:19:06] INFO (restartApp): restarting Claude... [18:19:08] INFO (restartApp): Claude has been restarted undefined # print the manual connection details $ director connect my-first-playbook -------------------------------- Connection Details for 'my-first-playbook' -------------------------------- Note: if you'd like to connect to a client automatically, run: director connect my-first-playbook --target HTTP Streamable: http://localhost:3673/my-first-playbook/mcp HTTP SSE: http://localhost:3673/my-first-playbook/sse Stdio: { "command": "npx", "args": [ "-y", "@director.run/cli", "http2stdio", "http://localhost:3673/my-first-playbook/mcp" ], "env": { "LOG_LEVEL": "silent" } } ``` ## Get the details of a playbook ```bash theme={null} # list all the playbooks $ director ls ┌──────────────────┬──────────────────┬────────────────────────────────────────────┐ │ id │ name │ path │ │ my-first-playbook │ my-first-playbook │ http://localhost:3673/my-first-playbook/mcp │ └──────────────────┴──────────────────┴────────────────────────────────────────────┘ # get the details of a single playbook $ director get my-first-playbook id=my-first-proxy name=my-first-proxy ┌───────┬───────────┬──────────────────────┐ │ name │ transport │ url/command │ │ fetch │ stdio │ uvx mcp-server-fetch │ └───────┴───────────┴──────────────────────┘ ``` # Configuration Files Source: https://docs.director.run/concepts/configuration Learn about Director's configuration files. Director doesn't use a database, everything is stored in a `director.config.yaml` file. The easiest way to manage this file is via the [Studio UI](https://studio.director.run) or the [CLI](../concepts/cli). But you can of course edit it manually. *Note: If you'd like to manually edit the configuration files, you'll need to make sure you restart the service for the changes to take effect.* # Search Paths Director will search for the configuration file in the following paths (in order): * `./director.config.yaml` * `~/.director/director.config.yaml` # Configuration File Reference ## Example Your configuration file is a YAML file that defines playbooks and client connections. Here's a example of how to structure it: ```yaml theme={null} # # Server config # server: # Defaults to 3673 port: 1234 # # Client <> Playbook mappings (enforced on startup) # clients: cursor: [ demo ] # # Playbooks (MCP servers, prompts, etc.) # playbooks: - id: demo name: demo description: A demonstration playbook # # Prompts # prompts: - name: changelog title: changelog description: "" body: "write a short changelog based on recent changes on the director-run/director repository and the post it to to the slack #general channel. Make sure the message will format correctly inside of slack" # # MCP Servers # servers: # GitHub server - name: github type: http url: https://api.githubcopilot.com/mcp/ headers: Authorization: Bearer # This server is enabled disabled: false # Only include the tools you need tools: include: - list_commits - search_pull_requests - get_latest_release # Prompts from MCP server are disabled by default prompts: include: [] - name: slack type: stdio command: npx args: - -y - "@modelcontextprotocol/server-slack" env: SLACK_TEAM_ID: SLACK_BOT_TOKEN: SLACK_CHANNEL_IDS: # This server is enabled disabled: false # Only include the tools you need tools: include: - slack_list_channels - slack_post_message # Prompts from MCP server are disabled by default prompts: include: [] ``` ## Server Configuration By default, Director will start a server on port 3673. You can change this by setting the `port` option in the `server` section. ```yaml theme={null} server: port: 1234 ``` ## Client Connections The `clients` section defines which playbooks are available to which MCP clients. This mapping is enforced on startup: ```yaml theme={null} clients: claude-code: [my-playbook, another-playbook] cursor: [my-playbook] vscode: [development-tools] ``` Supported client identifiers: * `claude-code` - Claude Code (command-line tool) * `claude` - Claude Desktop app * `cursor` - Cursor IDE * `vscode` - Visual Studio Code ## Playbooks Each playbook supports the following fields: * **id** (required): A unique identifier for the playbook * **name** (required): The name of the playbook * **description** (optional): The description of the playbook * **servers** (optional): The MCP servers to include in the playbook * **prompts** (optional): The prompts to include in the playbook ### Prompts Prompts are used to invoke the playbook from a MCP client. Each prompt supports the following fields: * **name** (required): The name of the prompt * **title** (optional): The title of the prompt * **description** (optional): The description of the prompt * **body** (optional): The body of the prompt ### MCP Servers MCP servers are used to provide the tools and prompts to the playbook. Each server supports the following fields: * **name** (required): The name of the server * **type** (required): The type of the server (either `stdio` or `http`). * **url** (optional): The URL of the server (only for http servers) * **headers** (optional): The headers to pass to the server (only for http servers) * **command** (optional): The command to execute for stdio-based servers * **args** (optional): The command-line arguments for stdio-based servers * **env** (optional): The environment variables to pass to the server * **disabled** (optional): Whether the server is disabled (default: false) * **tools** (optional): The tools to include in the server * **prompts** (optional): The prompts to include in the server #### Tools The `tools.include` option allows you to select only specific tools from an MCP server, which helps preserve context by limiting the available tool set: ```yaml theme={null} servers: - name: github type: http url: https://api.githubcopilot.com/mcp/ tools: include: [create_pr, search_code] # Only expose these specific tools ``` This is particularly useful when: * You want to limit capabilities for security reasons (e.g., read-only access) * You need to preserve context by only exposing relevant tools for a specific task * You want to prevent accidental use of destructive operations #### Prompts The `prompts.include` option allows you to select only specific prompts from an MCP server, which helps preserve context by limiting the available prompt set: ```yaml theme={null} servers: - name: github prompts: include: [create_pr, search_code] # Only expose these specific prompts ``` # Registry Source: https://docs.director.run/concepts/registry The registry is a collection of servers that are available to be used in the Gateway. It is fully [open source](https://github.com/director-run/director/tree/main/apps/registry) and does not require authentication. We are currently prioritising other parts of director until the official [MCP Registry](https://github.com/modelcontextprotocol/registry) matures. ## Accessing the Registry The best way to access the registry is in your browser via the [Studio](https://studio.director.run/library). Or alternatively, you can use the [CLI](./cli): ```bash theme={null} # List all servers in the registry director registry ls # Adding a server from the registry director add my-proxy --entry google-drive ``` ## Adding a server to the Registry We re-populate the registry on a regular basis from the [seed file](https://github.com/director-run/director/tree/main/apps/registry/src/seed/entries.ts). If you'd like to add a new entry, please add it to the file and open a PR. Here's an example of an entry: ```js theme={null} { name: "notion", title: "Notion", description: "Connect to Notion API, enabling advanced automation and interaction capabilities for developers and tools.", isOfficial: true, icon: "https://registry.director.run/notion.svg", homepage: "https://github.com/makenotion/notion-mcp-server", transport: { type: "stdio", command: "npx", args: ["-y", "@notionhq/notion-mcp-server"], env: { OPENAPI_MCP_HEADERS: '{"Authorization": "Bearer ", "Notion-Version": "2022-06-28" }', }, }, parameters: [ { name: "notion-bearer-token", description: "Get a bearer token from [Notion Settings](https://www.notion.so/profile/integrations)", type: "string", required: true, password: true, }, ], } ``` # Studio Source: https://docs.director.run/concepts/studio The visual interface for managing and deploying MCP servers The [Studio](https://studio.director.run), along with the [CLI](./cli), are the primary ways to interact with director. The easiest way to get started is to run `director quickstart` which will start the gateway and open the studio in your browser. # Usage ```bash theme={null} $ npm install -g @director.run/cli $ director serve # start the gateway $ director studio # open the studio - https://studio.director.run ``` # Running in Docker Source: https://docs.director.run/experimental/docker We currently have an experimental Docker image that you can use to run the gateway in a containerized environment. **Note:** Automatic client connections are not supported in the Docker image. You will need to connect manually using the connect command. ```bash theme={null} # Start the gateway container, listening on port 8080 # Mount the data directory to persist the gateway's state (config files, etc) docker run \ -d -p 3673:8080 \ -v ./data:/root/.director \ --name director \ barnaby/director:latest # Tail the logs docker logs -f director # Interact with the gateway using the CLI, on the host machine director create my-playbook director add my-playbook --entry fetch director connect my-playbook # print connection details ``` # Quickstart Source: https://docs.director.run/getting-started/quickstart Getting started with Director # Prerequisites * Works on latest **MacOS** and **Ubuntu Linux**. * `node` & `npm` for the CLI. * `uvx` for most of the servers. * [Claude](https://claude.ai/download), [Cursor](https://www.cursor.com/downloads) or [VSCode](https://code.visualstudio.com/download) installed. (if you'd like director to configure them automatically). # Quickstart The fastest way to try director is to use the install script. This will download the dependencies, run the latest version of director and open up the studio in your browser: ```bash theme={null} curl -LsSf https://director.run/install.sh | sh director quickstart ``` # Alternative Methods ## Installing Locally If you'd like to install director locally, you can do so via `npm`. ```bash theme={null} npm install -g @director.run/cli director serve # start the gateway director studio # open the studio in your browser ``` ## Getting started with the CLI If you'd like to set up director without going through the UI, you can do so via the CLI. For more detailed information, check out the [CLI Reference](../concepts/cli). ```bash theme={null} npm install -g @director.run/cli director serve # start the gateway director create my-first-playbook # create a playbook director add my-first-playbook --entry fetch # add the fetch server to the playbook director connect my-first-playbook --target claude # connect the playbook to Claude director connect my-first-playbook --target cursor # connect the playbook to Cursor director connect my-first-playbook # print the manual connection details ``` # Welcome to Director! Source: https://docs.director.run/getting-started/welcome MCP Playbooks for AI agents export const BetaBadge = () => { return Director is in BETA and is not yet production ready.; }; [Director](https://director.run) allows you to provide **playbooks** to AI Agents. A playbook is a set of **MCP tools**, **prompts** and **configuration** that give agents new **skills**. You can connect Claude, Cursor and VSCode in 1-click, or integrate manually through a single MCP endpoint. Playbooks are portable, declarative YAML files that can easily be shared (or committed to version control). Director is local-first - installation and client integration takes 30 seconds. Director provides all the MCP management functionality you'd expect: tool filtering, logging, strong isolation, and unified OAuth. ## Key Features #### 📚 Playbooks Maintain sets of tools, prompts and config for different tasks or environments. #### 🚀 1-Click Integration Switch playbooks with a single click. Currently supports Claude Code, Claude Desktop, Cursor, VSCode. #### 🔗 Shareable Playbooks are flat files which can be shared or committed to version control easily. #### 🏠 Local-First Director is local-first, designed to easily run on your own machine or infrastructure. #### 🔑 Unified OAuth Connect to OAuth MCPs centrally, and use them across all of your agents. #### 🎯 Tool Filtering Select only the MCP tools that are required for the specific task, preserving context. #### 📋 Declarative Like terraform for AI agents, Director will enforce playbook to client mapping on startup. #### 🔧 Flexibility Configure director through the UI, by editing the config file, through the CLI or using the Typescript SDK. #### 📊 Observability Centralized JSON logging that allows you to understand exactly what your agent is doing. #### 🔌 MCP Compliant Just works with any MCP server or client. Up to date with the latest MCP spec. #### MCP Registry Discover and evaluate MCP servers securely. Browse available servers through the [Studio](./studio) or CLI. # Contributing Source: https://docs.director.run/project/contributing Hello! We welcome any and all contributions and we'd be more than happy to help you get started with the codebase. *Note: This project is under active development and the code will likely change pretty significantly. We'll update this message once that's complete!* ## Prerequisites * [Bun](https://bun.sh/) (tested on 1.2.14+) * [Docker](https://docker.com) ## Development workflow ### Setup Environment ```bash theme={null} # clone the repo git clone https://github.com/director-run/director cd director # Setup environment bun install docker compose up -d ./scripts/setup-development.sh bun run test # confirm everything is working # Teardown environment docker compose down -v ``` ### Running in Development ```bash theme={null} # Running cli in development bun cli serve # start the gateway bun cli:dev # watches for changes # Working with the registry # Uncomment the lines in this file vim apps/cli/.director/development/config.env bun registry bun cli registry populate # populate the development database with server entries bun cli registry enrich # populate the development database with server entries bun cli registry enrich-tools # populate the development database with server entries ``` ### Running Tests ```bash theme={null} # from project root $ bun run lint $ bun run typecheck $ bun run test # Automatically fix lint + prettier issues $ bun run format ``` ## Writing code changes When you make code changes, please remember 1. **Add or update tests.** Every new feature or bug‑fix should come with test coverage that fails before your change and passes afterwards. 100 % coverage is not required, but aim for meaningful assertions. 2. **Document behaviour.** If your change affects user‑facing behaviour, update the `README.md` or the relevant `apps/docs` page. 3. **Keep commits atomic.** Each commit should compile and the tests should pass. This makes reviews and potential rollbacks easier. ## Opening a pull request * Fill in the PR template (or include similar information) – **What? Why? How?** * Run **all** checks locally (`bun run test && bun run lint && bun run check-types`). CI failures that could have been caught locally slow down the process. * Make sure your branch is up‑to‑date with `main` and that you have resolved merge conflicts. * Mark the PR as **Ready for review** only when you believe it is in a merge‑able state. ## Releasing `director` ```bash theme={null} # Bump the version $ ./scripts/print-version.sh 0.0.1 $ ./scripts/bump-version.sh 0.0.2 # Merge the PR in GitHub $ git checkout main && git pull $ ./scripts/release.sh ``` # null Source: https://docs.director.run/project/roadmap Below is our tentative roadmap for the next few months. We're actively working on the following: #### Now * **Secret Management**: Store secrets outside of the config file. * **Hosting**: Support for hosting director instances in the cloud. #### Next * **ACL**: Support for ACLs to control access to the director instance. * **Desktop Application**: OSX Desktop application for managing director instances. #### Later * **Plugins**: Support for plugins to extend the functionality of director. If you'd like to contribute, please see the [contributing guide](./contributing). # Client API Reference Source: https://docs.director.run/sdk/client-configurator The Client Configurator is a library that helps manage MCP Client configuration (checking client status, adding / removing servers, etc). Currently it supports Claude, Cursor & VSCode. The source code is available in [packages/client-configurator](https://github.com/director-run/director/tree/main/packages/client-configurator). ## API ```ts theme={null} import { ConfiguratorTarget, getConfigurator } from "@director.run/client-configurator/index"; const claudeConfigurator = getConfigurator(ConfiguratorTarget.Claude); // Is Claude installed on this machine? await claudeConfigurator.isClientPresent(); await claudeConfigurator.isInstalled("my-proxy"); // Install an MCP server using a URL. If the client doesn't support HTTP, we use proxies. await claudeConfigurator.install({ name: "my-proxy", sseURL: "http://localhost:3673/my-proxy/sse", streamableURL: "http://localhost:3673/my-proxy/streamable", }); await claudeConfigurator.uninstall("my-proxy"); // Clear the config file. Useful for development await claudeConfigurator.reset(); ``` ## Adding support for a new client ```ts theme={null} // Create a new configurator in ./src/ export class NewClientConfigurator extends AbstractConfigurator { // Implement the protected methods } ``` # Gateway API Reference Source: https://docs.director.run/sdk/gateway The Gateway API allows you to start and manage a director instance programmatically. The source code is available in [apps/gateway](https://github.com/director-run/director/tree/main/apps/gateway). ## Examples ```typescript theme={null} import { Gateway, GatewayConfig } from "@director.run/sdk"; // Start the gateway const gateway = await Gateway.start({ config: await GatewayConfig.createMemoryBasedConfig({ defaults: { server: { port: 3673, }, registry: { url: "https://registry.director.run", }, telemetry: { writeKey: "", enabled: false, }, }, }), baseUrl: "http://localhost:3673", }); // Add a new playbook await gateway.playbookStore.create({ name: "test", servers: [ { name: "notion", type: "http", url: "https://mcp.notion.com/mcp", }, ], }); ``` # MCP API Reference Source: https://docs.director.run/sdk/mcp The Director MCP API provides a simple interface for creating MCP servers, proxies and clients. It extends the official [Typescript SDK](https://github.com/modelcontextprotocol/typescript-sdk). The source code is available in [packages/mcp](https://github.com/director-run/director/tree/main/packages/mcp). ## API ```typescript theme={null} import { HTTPClient } from "@director.run/sdk"; import { StdioClient } from "@director.run/sdk"; import { ProxyServer } from "@director.run/sdk"; import { serveOverSSE, serveOverStdio, serveOverStreamable } from "@director.run/sdk"; const proxy = new ProxyServer({ id: "my-proxy", servers: [ new StdioClient({ name: "stdio-server", command: "npx", args: ["-y", "@director.run/cli", "http2stdio", "http://example.com/sse"], }), new HTTPClient({ name: "http-server", // supports SSE & Streamable url: "http://example.com/mcp", }), ], }); // Connect to the servers await proxy.connectTargets(); // Helper methods to serve the proxy await serveOverStreamable(proxy, 3673); await serveOverSSE(proxy, 3674); await serveOverStdio(proxy); // Connect over Streamable or SSE const httpClient = await HTTPClient.createAndConnectToHTTP( "http://localhost:3673/mcp", ); // Connect over Stdio const stdioClient = await StdioClient.createAndConnectToStdio( "server-command", ["server-args"], ); // List the tools via HTTP client console.log(await httpClient.listTools()); // List the tools via Stdio client console.log(await stdioClient.listTools()); ```