mirror of
https://github.com/Sea-Haven-Industries/sh-mcp.git
synced 2026-10-07 16:18:58 +00:00
136 lines
4.3 KiB
TypeScript
136 lines
4.3 KiB
TypeScript
|
|
/**
|
||
|
|
* sh-mcp-ops tool registry — composition root.
|
||
|
|
*
|
||
|
|
* Registers exactly the ops-tier tools (design.md §3): internal-data,
|
||
|
|
* knowledge-base, google-maps, gmail, calendar, tasks, reminders. Each package
|
||
|
|
* factory is wired with the selected client — an in-memory dev client in
|
||
|
|
* `SH_MCP_ENV=local`, or the real (stub) client in `aws` mode.
|
||
|
|
*
|
||
|
|
* IMPORTANT: we deliberately call each package's *factory* with an explicit
|
||
|
|
* client rather than importing its pre-wired `tools` array, because some of
|
||
|
|
* those arrays construct AWS clients at import time. Building clients here keeps
|
||
|
|
* import-time side-effect-free (build-plan §7 "No I/O at import time").
|
||
|
|
*
|
||
|
|
* The package factory signatures are intentionally inconsistent (build-plan §1);
|
||
|
|
* each is wired to its own shape below.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { ToolRegistry, type ToolDef } from '@sh-mcp/shared';
|
||
|
|
|
||
|
|
// internal-data
|
||
|
|
import {
|
||
|
|
makeTools as makeInternalDataTools,
|
||
|
|
RealDynamoClient,
|
||
|
|
type InternalDataClient,
|
||
|
|
InMemoryInternalDataClient,
|
||
|
|
} from '@sh-mcp/internal-data';
|
||
|
|
// knowledge-base
|
||
|
|
import {
|
||
|
|
createKnowledgeBaseTools,
|
||
|
|
createBedrockClientFromEnv,
|
||
|
|
type KnowledgeBaseClient,
|
||
|
|
InMemoryKnowledgeBaseClient,
|
||
|
|
} from '@sh-mcp/knowledge-base';
|
||
|
|
// google-maps
|
||
|
|
import {
|
||
|
|
makeTools as makeMapsTools,
|
||
|
|
GooglePlacesClient,
|
||
|
|
type GoogleMapsClient,
|
||
|
|
InMemoryGoogleMapsClient,
|
||
|
|
} from '@sh-mcp/google-maps';
|
||
|
|
// gmail
|
||
|
|
import {
|
||
|
|
makeGmailTools,
|
||
|
|
GmailApiClient,
|
||
|
|
type GmailClient,
|
||
|
|
type GoogleTokenProvider as GmailTokenProvider,
|
||
|
|
InMemoryGmailClient,
|
||
|
|
} from '@sh-mcp/gmail';
|
||
|
|
// calendar
|
||
|
|
import {
|
||
|
|
buildCalendarTools,
|
||
|
|
GoogleCalendarClient,
|
||
|
|
type CalendarClient,
|
||
|
|
type GoogleTokenProvider as CalendarTokenProvider,
|
||
|
|
InMemoryCalendarClient,
|
||
|
|
} from '@sh-mcp/calendar';
|
||
|
|
// tasks
|
||
|
|
import {
|
||
|
|
buildTaskTools,
|
||
|
|
DynamoDBTasksClient,
|
||
|
|
type TasksClient,
|
||
|
|
InMemoryTasksClient,
|
||
|
|
} from '@sh-mcp/tasks';
|
||
|
|
// reminders
|
||
|
|
import {
|
||
|
|
buildReminderTools,
|
||
|
|
AwsSchedulerClient,
|
||
|
|
type SchedulerClient,
|
||
|
|
InMemorySchedulerClient,
|
||
|
|
} from '@sh-mcp/reminders';
|
||
|
|
|
||
|
|
import type { OpsConfig } from './config.js';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A Google per-user token provider stub for `aws` mode. The REAL provider
|
||
|
|
* (per-user OAuth refresh tokens, design.md §2.4) is a later phase; in this PR
|
||
|
|
* `aws` mode is not runtime-exercised, so this throws if actually used.
|
||
|
|
*/
|
||
|
|
class StubGoogleTokenProvider implements GmailTokenProvider, CalendarTokenProvider {
|
||
|
|
async getAccessToken(): Promise<string> {
|
||
|
|
throw new Error(
|
||
|
|
'Real per-user Google token provider is not implemented in Phase 1 ' +
|
||
|
|
'(design.md §2.4 — deferred). Run with SH_MCP_ENV=local for a working server.',
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Build the ops registry for the given environment. */
|
||
|
|
export async function buildOpsRegistry(config: OpsConfig): Promise<ToolRegistry> {
|
||
|
|
const local = config.env === 'local';
|
||
|
|
|
||
|
|
// --- select clients (dev vs real) ---
|
||
|
|
const internalDataClient: InternalDataClient = local
|
||
|
|
? new InMemoryInternalDataClient()
|
||
|
|
: await RealDynamoClient.create();
|
||
|
|
|
||
|
|
const kbClient: KnowledgeBaseClient = local
|
||
|
|
? new InMemoryKnowledgeBaseClient()
|
||
|
|
: createBedrockClientFromEnv();
|
||
|
|
|
||
|
|
const mapsClient: GoogleMapsClient = local
|
||
|
|
? new InMemoryGoogleMapsClient()
|
||
|
|
: new GooglePlacesClient(config.googleMapsApiKey ?? '');
|
||
|
|
|
||
|
|
const tokenProvider = new StubGoogleTokenProvider();
|
||
|
|
const gmailClient: GmailClient = local
|
||
|
|
? new InMemoryGmailClient()
|
||
|
|
: new GmailApiClient(tokenProvider);
|
||
|
|
const calendarClient: CalendarClient = local
|
||
|
|
? new InMemoryCalendarClient()
|
||
|
|
: new GoogleCalendarClient(tokenProvider);
|
||
|
|
|
||
|
|
const tasksClient: TasksClient = local ? new InMemoryTasksClient() : new DynamoDBTasksClient();
|
||
|
|
|
||
|
|
const schedulerClient: SchedulerClient = local
|
||
|
|
? new InMemorySchedulerClient()
|
||
|
|
: new AwsSchedulerClient({
|
||
|
|
targetArn: config.reminderTargetArn ?? '',
|
||
|
|
roleArn: config.schedulerRoleArn ?? '',
|
||
|
|
});
|
||
|
|
|
||
|
|
// --- register all ops-tier tools ---
|
||
|
|
const registry = new ToolRegistry();
|
||
|
|
const all: ToolDef<unknown, unknown>[] = [
|
||
|
|
...makeInternalDataTools(internalDataClient),
|
||
|
|
...createKnowledgeBaseTools(kbClient),
|
||
|
|
...makeMapsTools(mapsClient),
|
||
|
|
...makeGmailTools(gmailClient),
|
||
|
|
...buildCalendarTools(calendarClient),
|
||
|
|
...buildTaskTools(tasksClient),
|
||
|
|
...buildReminderTools({ client: schedulerClient }),
|
||
|
|
].map((t) => t as ToolDef<unknown, unknown>);
|
||
|
|
for (const tool of all) registry.register(tool);
|
||
|
|
return registry;
|
||
|
|
}
|