Skip to content

Commit 649e855

Browse files
committed
feat(mcp): introduce context storage
1 parent 75bd743 commit 649e855

File tree

3 files changed

+50
-11
lines changed

3 files changed

+50
-11
lines changed

doit-mcp-server/src/index.ts

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import app from "./app";
22
import { McpAgent } from "agents/mcp";
33
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
44
import { z } from "zod";
5+
import { DurableObject } from "cloudflare:workers";
56

67
// Import DoiT tool handlers
78
import {
@@ -58,6 +59,24 @@ import { executeToolHandler } from "../../src/utils/toolsHandler.js";
5859
import { zodSchemaToMcpTool } from "../../src/utils/util.js";
5960
import { prompts } from "../../src/utils/prompts.js";
6061

62+
// Context Storage Durable Object
63+
export class ContextStorage extends DurableObject {
64+
constructor(ctx: DurableObjectState, env: Env) {
65+
super(ctx, env);
66+
}
67+
68+
async saveContext(customerContext: string): Promise<void> {
69+
console.log("Saving customer context:", customerContext, this.ctx.id);
70+
await this.ctx.storage.put("customerContext", customerContext);
71+
}
72+
73+
async loadContext(): Promise<string | null> {
74+
const context = await this.ctx.storage.get<string>("customerContext");
75+
console.log("Loaded customer context:", context, this.ctx.id);
76+
return context || null;
77+
}
78+
}
79+
6180
// Helper function to convert DoiT handler response to MCP format
6281
function convertToMcpResponse(doitResponse: any) {
6382
if (doitResponse.content && Array.isArray(doitResponse.content)) {
@@ -80,35 +99,44 @@ export class DoitMCPAgent extends McpAgent {
8099
return this.props.apiKey as string;
81100
}
82101

83-
// Persist props to Durable Object storage
102+
// Persist props to Context Storage Durable Object
84103
private async saveProps(): Promise<void> {
85-
if (this.ctx?.storage) {
86-
await this.ctx.storage.put("persistedProps", this.props.customerContext);
104+
const env = this.env as Env;
105+
const apiKey = this.props.apiKey as string;
106+
const customerContext = this.props.customerContext as string;
107+
if (apiKey && env?.CONTEXT_STORAGE) {
108+
const id = env.CONTEXT_STORAGE.idFromName(apiKey);
109+
const contextStorage = env.CONTEXT_STORAGE.get(id);
110+
await contextStorage.saveContext(customerContext);
87111
}
88112
}
89113

90-
// Load props from Durable Object storage
91-
private async loadPersistedProps(): Promise<void> {
92-
if (this.ctx?.storage) {
93-
const persistedProps = await this.ctx.storage.get<string>(
94-
"persistedProps"
95-
);
114+
// Load props from Context Storage Durable Object
115+
private async loadPersistedProps(): Promise<string | null> {
116+
const env = this.env as Env;
117+
const apiKey = this.props.apiKey as string;
118+
if (apiKey && env?.CONTEXT_STORAGE) {
119+
const id = env.CONTEXT_STORAGE.idFromName(apiKey);
120+
const contextStorage = env.CONTEXT_STORAGE.get(id);
121+
const persistedProps = await contextStorage.loadContext();
96122
if (persistedProps) {
97-
console.log("Loading persisted props:", persistedProps);
98123
// Update props with persisted values
99124
this.props.customerContext = persistedProps;
125+
return persistedProps;
100126
}
101127
}
128+
return (this.props.customerContext as string) || null;
102129
}
103130

104131
// Generic callback factory for tools
105132
private createToolCallback(toolName: string) {
106133
return async (args: any) => {
107134
const token = this.getToken();
135+
const customerContext = await this.loadPersistedProps();
108136

109137
const argsWithCustomerContext = {
110138
...args,
111-
customerContext: this.props.customerContext,
139+
customerContext,
112140
};
113141
return await executeToolHandler(
114142
toolName,

doit-mcp-server/worker-configuration.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ declare namespace Cloudflare {
55
interface Env {
66
OAUTH_KV: KVNamespace;
77
MCP_OBJECT: DurableObjectNamespace<import("./src/index").DoitMCPAgent>;
8+
CONTEXT_STORAGE: DurableObjectNamespace<
9+
import("./src/index").ContextStorage
10+
>;
811
ASSETS: Fetcher;
912
}
1013
}

doit-mcp-server/wrangler.jsonc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,21 @@
1818
{
1919
"new_sqlite_classes": ["DoitMCPAgent"],
2020
"tag": "v1"
21+
},
22+
{
23+
"new_sqlite_classes": ["ContextStorage"],
24+
"tag": "v2"
2125
}
2226
],
2327
"durable_objects": {
2428
"bindings": [
2529
{
2630
"class_name": "DoitMCPAgent",
2731
"name": "MCP_OBJECT"
32+
},
33+
{
34+
"class_name": "ContextStorage",
35+
"name": "CONTEXT_STORAGE"
2836
}
2937
]
3038
},

0 commit comments

Comments
 (0)