Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
with:
build: false

deploy-gateway:
deploy-app:
name: Gateway
needs: ci
permissions:
Expand All @@ -28,8 +28,8 @@ jobs:
uses: ./.github/workflows/__cloudrun-deploy.yml
with:
environment: production
service_name: director-production-gateway
working-directory: apps/gateway
service_name: director-production-app
working-directory: apps/app
migrations: true
seed_enabled: false

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
with:
build: false

deploy-gateway:
deploy-app:
name: Gateway
needs: ci
permissions:
Expand All @@ -29,7 +29,7 @@ jobs:
uses: ./.github/workflows/__cloudrun-deploy.yml
with:
environment: staging
service_name: director-staging-gateway
service_name: director-staging-app
working-directory: apps/gateway
migrations: true
seed_enabled: true
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ CORE COMMANDS
add <playbookId> [options] Add a server to a playbook.
remove <playbookId> <serverName> Remove a server from a playbook
update <playbookId> [serverName] [options] Update playbook attributes
http2stdio <url> Proxy an HTTP connection (sse or streamable) to a stdio stream
http2stdio <url> Proxy an HTTP connection to a stdio stream
env [options] Print environment variables
status Get the status of the director

Expand Down
4 changes: 1 addition & 3 deletions apps/cli/src/commands/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,7 @@ export function registerCoreCommands(program: DirectorCommand): void {

program
.command("http2stdio <url>")
.description(
"Proxy an HTTP connection (sse or streamable) to a stdio stream",
)
.description("Proxy an HTTP connection to a stdio stream")
.action(async (url) => {
await proxyHTTPToStdio(url);
});
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/commands/core/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function registerAddCommand(program: DirectorCommand) {
.addOption(
makeOption({
flags: "-u,--url <url>",
description: "add a streamable or sse server by specifying the url",
description: "add an HTTP server by specifying the url",
}),
)
.addOption(
Expand Down
5 changes: 1 addition & 4 deletions apps/cli/src/commands/core/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ export function registerConnectCommand(program: DirectorCommand) {
playbookId,
});

// Build full URLs with API key
// Build full URL with API key
const streamableUrlWithKey = `${connectionInfo.streamableUrl}?key=${connectionInfo.apiKey}`;
const sseUrlWithKey = `${connectionInfo.sseUrl}?key=${connectionInfo.apiKey}`;

// Build stdio command config
const stdioCommand = {
Expand All @@ -51,7 +50,6 @@ export function registerConnectCommand(program: DirectorCommand) {
clientId: options.target as ClientId,
name: connectionInfo.playbookId,
connectionDetails: {
sseUrl: sseUrlWithKey,
streamableUrl: streamableUrlWithKey,
},
});
Expand All @@ -71,7 +69,6 @@ export function registerConnectCommand(program: DirectorCommand) {
console.log(
whiteBold("HTTP Streamable:") + " " + streamableUrlWithKey,
);
console.log(whiteBold("HTTP SSE:") + " " + sseUrlWithKey);
console.log(
whiteBold("Stdio:"),
JSON.stringify(stdioCommand, null, 2),
Expand Down
1 change: 0 additions & 1 deletion apps/cli/src/commands/core/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ export function printPlaybookDetails(
name,
description: description ?? "--",
streamableURL: joinURL(env.GATEWAY_URL, playbook.paths.streamable),
sseURL: joinURL(env.GATEWAY_URL, playbook.paths.sse),
}),
);

Expand Down
40 changes: 8 additions & 32 deletions apps/cli/src/commands/mcp/prompts.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,34 @@
import { HTTPClient } from "@director.run/mcp/client/http-client";
import { yellow } from "@director.run/utilities/cli/colors";
import {
DirectorCommand,
makeOption,
} from "@director.run/utilities/cli/director-command";
import { DirectorCommand } from "@director.run/utilities/cli/director-command";
import { actionWithErrorHandler } from "@director.run/utilities/cli/index";
import { makeTable } from "@director.run/utilities/cli/index";
import type { Prompt } from "@modelcontextprotocol/sdk/types.js";
import { gatewayClient } from "../../client";
import { title } from "../../common";
import type { TransportType } from "./tools";

/**
* Creates an authenticated MCP client for a playbook.
*/
async function createPlaybookClient(
playbookId: string,
transport: TransportType = "streamable",
): Promise<HTTPClient> {
async function createPlaybookClient(playbookId: string): Promise<HTTPClient> {
const connectionInfo = await gatewayClient.store.getConnectionInfo.query({
playbookId,
});
// Build URL with API key
const baseUrl =
transport === "sse" ? connectionInfo.sseUrl : connectionInfo.streamableUrl;
const urlWithKey = `${baseUrl}?key=${connectionInfo.apiKey}`;
const urlWithKey = `${connectionInfo.streamableUrl}?key=${connectionInfo.apiKey}`;
return HTTPClient.createAndConnectToHTTP(urlWithKey);
}

function transportOption() {
return makeOption({
flags: "--transport <type>",
description: "Transport type to use for connection",
defaultValue: "streamable",
choices: ["streamable", "sse"],
});
}

export function registerPromptsCommand(program: DirectorCommand) {
program
.command("list-prompts <playbookId>")
.description("List prompts on a playbook")
.addOption(transportOption())
.action(
actionWithErrorHandler(
async (playbookId: string, options: { transport: TransportType }) => {
const client = await createPlaybookClient(
playbookId,
options.transport,
);
await printPrompts(client);
await client.close();
},
),
actionWithErrorHandler(async (playbookId: string) => {
const client = await createPlaybookClient(playbookId);
await printPrompts(client);
await client.close();
}),
);
}

Expand Down
89 changes: 18 additions & 71 deletions apps/cli/src/commands/mcp/tools.ts
Original file line number Diff line number Diff line change
@@ -1,110 +1,57 @@
import { HTTPClient } from "@director.run/mcp/client/http-client";
import { blue, yellow } from "@director.run/utilities/cli/colors";
import {
DirectorCommand,
makeOption,
} from "@director.run/utilities/cli/director-command";
import { DirectorCommand } from "@director.run/utilities/cli/director-command";
import { actionWithErrorHandler } from "@director.run/utilities/cli/index";
import { makeTable } from "@director.run/utilities/cli/index";
import { input } from "@inquirer/prompts";
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
import { gatewayClient } from "../../client";
import { title } from "../../common";

export type TransportType = "streamable" | "sse";

/**
* Creates an authenticated MCP client for a playbook.
*/
async function createPlaybookClient(
playbookId: string,
transport: TransportType = "streamable",
): Promise<HTTPClient> {
async function createPlaybookClient(playbookId: string): Promise<HTTPClient> {
const connectionInfo = await gatewayClient.store.getConnectionInfo.query({
playbookId,
});
// Build URL with API key
const baseUrl =
transport === "sse" ? connectionInfo.sseUrl : connectionInfo.streamableUrl;
const urlWithKey = `${baseUrl}?key=${connectionInfo.apiKey}`;
const urlWithKey = `${connectionInfo.streamableUrl}?key=${connectionInfo.apiKey}`;
return HTTPClient.createAndConnectToHTTP(urlWithKey);
}

function transportOption() {
return makeOption({
flags: "--transport <type>",
description: "Transport type to use for connection",
defaultValue: "streamable",
choices: ["streamable", "sse"],
});
}

export function registerToolsCommand(program: DirectorCommand) {
program
.command("list-tools <playbookId>")
.description("List tools on a playbook")
.addOption(transportOption())
.action(
actionWithErrorHandler(
async (playbookId: string, options: { transport: TransportType }) => {
const client = await createPlaybookClient(
playbookId,
options.transport,
);
await printTools(client);
await client.close();
},
),
actionWithErrorHandler(async (playbookId: string) => {
const client = await createPlaybookClient(playbookId);
await printTools(client);
await client.close();
}),
);

program
.command("get-tool <playbookId> <toolName>")
.description("Get the details of a tool")
.addOption(transportOption())
.action(
actionWithErrorHandler(
async (
playbookId: string,
toolName: string,
options: { transport: TransportType },
) => {
const client = await createPlaybookClient(
playbookId,
options.transport,
);
await printTool(client, toolName);
await client.close();
},
),
actionWithErrorHandler(async (playbookId: string, toolName: string) => {
const client = await createPlaybookClient(playbookId);
await printTool(client, toolName);
await client.close();
}),
);

program
.command("call-tool <playbookId> <toolName>")
.addOption(
makeOption({
flags: "-a,--argument <key=value>",
description:
"set arguments in key=value format (can be used multiple times)",
variadic: true,
}),
)
.addOption(transportOption())
.description("Call a tool on a playbook")
.action(
actionWithErrorHandler(
async (
playbookId: string,
toolName: string,
options: { transport: TransportType },
) => {
const client = await createPlaybookClient(
playbookId,
options.transport,
);
await callTool(client, toolName);
await client.close();
},
),
actionWithErrorHandler(async (playbookId: string, toolName: string) => {
const client = await createPlaybookClient(playbookId);
await callTool(client, toolName);
await client.close();
}),
);
}

Expand Down
Loading
Loading