Skip to content
← Public packages

@cameronpak/raycast-kodys-pouch

Your Kody Skills and Tools, one command away.

src/list-capabilities.ts

109 lines · 2.3 KB · TypeScript
import { kody } from 'kody:runtime'

export type CapabilitySource =
	| 'builtin'
	| 'remote-connector'
	| 'mcp-server'
	| 'openapi'

type SlimCapability = ListCapabilitiesResult['capabilities'][number]

type MetaCapability = {
	name: string
	description: string
	source: CapabilitySource
	mcpServer?: {
		kodyName: string
		serverName: string
		toolName: string
	}
	openApi?: {
		bindingName: string
		operationSlug: string
	}
	remoteConnector?: {
		connectorName: string
		toolName: string
	}
}

export type ListCapabilitiesResult = {
	capabilities: Array<{
		name: string
		description: string
		source: CapabilitySource
		mcpServer?: {
			kodyName: string
			serverName: string
			toolName: string
		}
		openApi?: {
			bindingName: string
			operationSlug: string
		}
		remoteConnector?: {
			connectorName: string
			toolName: string
		}
	}>
}

function slimCapability(cap: MetaCapability): SlimCapability {
	return {
		name: cap.name,
		description: cap.description,
		source: cap.source,
		...(cap.mcpServer
			? {
					mcpServer: {
						kodyName: cap.mcpServer.kodyName,
						serverName: cap.mcpServer.serverName,
						toolName: cap.mcpServer.toolName,
					},
				}
			: {}),
		...(cap.openApi
			? {
					openApi: {
						bindingName: cap.openApi.bindingName,
						operationSlug: cap.openApi.operationSlug,
					},
				}
			: {}),
		...(cap.remoteConnector
			? {
					remoteConnector: {
						connectorName: cap.remoteConnector.connectorName,
						toolName: cap.remoteConnector.toolName,
					},
				}
			: {}),
	}
}

async function collectCapabilities(): Promise<MetaCapability[]> {
	const index = await kody.metaListCapabilities({})
	if (Array.isArray(index.capabilities)) {
		return index.capabilities as MetaCapability[]
	}

	const domains = index.domains ?? []
	const pages = await Promise.all(
		domains.map(async domain => {
			const page = await kody.metaListCapabilities({ domain: domain.id })
			return (page.capabilities ?? []) as MetaCapability[]
		}),
	)
	return pages.flat()
}

/**
 * List callable capabilities for the Pouch inventory.
 * Includes built-ins, connected MCP servers, OpenAPI bindings, and remote connectors.
 */
export default async function listCapabilities(): Promise<ListCapabilitiesResult> {
	const capabilities = await collectCapabilities()
	return {
		capabilities: capabilities.map(slimCapability),
	}
}