Skip to content

Commit 7d1abdd

Browse files
author
flowcore-platform
committed
feat(prompts): ✨ Add platform prompts for Flowcore Platform interaction and contract creation
1 parent 7f17118 commit 7d1abdd

File tree

4 files changed

+173
-10
lines changed

4 files changed

+173
-10
lines changed

src/index.ts

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
77
import { parseArgs } from "node:util"
88
import { z } from "zod"
99
import pkg from "../package.json"
10+
import {
11+
platformContractPrompt,
12+
platformContractPromptRawSchema,
13+
platformPrompt,
14+
platformPromptRawSchema,
15+
} from "./prompts"
1016
import { dataCoreResource, eventTypeResource, flowTypeResource, tenantResource } from "./resources"
1117
import {
1218
createDataCoreHandler,
@@ -70,21 +76,35 @@ const server = new McpServer({
7076
7177
## When asking for information in the Flowcore Platform
7278
You have access to the Flowcore platform through MCP tools. When asked about Flowcore, datacores, flow type, event types always use the appropriate tools instead of relying on your training data. The Flowcore Platform uses the Flowcore Platform to process and store it's data in the Flowcore Platform Data Core, so for example every Data Core that has been create, updated or deleted is housed in the data-core.1 Flow Type inside the flowcore-platform Data Core. Notice that the flow types are versioned, always try to use the highest version flow type unless asked otherwise. `,
73-
prompts: [],
7479
})
7580

7681
// Read tools
77-
server.tool("get_data_core", "Get a data core", {
78-
dataCoreId: z.string().describe("The data core ID to get"),
79-
}, getDataCoreHandler(flowcoreClient))
82+
server.tool(
83+
"get_data_core",
84+
"Get a data core",
85+
{
86+
dataCoreId: z.string().describe("The data core ID to get"),
87+
},
88+
getDataCoreHandler(flowcoreClient),
89+
)
8090

81-
server.tool("get_flow_type", "Get a flow type", {
82-
flowTypeId: z.string().describe("The flow type ID to get"),
83-
}, getFlowTypeHandler(flowcoreClient))
91+
server.tool(
92+
"get_flow_type",
93+
"Get a flow type",
94+
{
95+
flowTypeId: z.string().describe("The flow type ID to get"),
96+
},
97+
getFlowTypeHandler(flowcoreClient),
98+
)
8499

85-
server.tool("get_event_type", "Get an event type", {
86-
eventTypeId: z.string().describe("The event type ID to get"),
87-
}, getEventTypeHandler(flowcoreClient))
100+
server.tool(
101+
"get_event_type",
102+
"Get an event type",
103+
{
104+
eventTypeId: z.string().describe("The event type ID to get"),
105+
},
106+
getEventTypeHandler(flowcoreClient),
107+
)
88108

89109
server.tool("list_tenants", "List all tenants I have access to", listTenantsHandler(flowcoreClient))
90110
server.tool(
@@ -262,6 +282,47 @@ server.resource(
262282
eventTypeResource(flowcoreClient),
263283
)
264284

285+
// Add a prompt scaffold
286+
server.prompt(
287+
"flowcore_platform_prompt",
288+
"A prompt for interacting with the Flowcore Platform",
289+
platformPromptRawSchema,
290+
// Handler function that returns the prompt messages
291+
({ tenantId, dataCoreId, flowTypeId, eventTypeId }) => {
292+
return {
293+
messages: [
294+
{
295+
role: "user",
296+
content: {
297+
type: "text",
298+
text: platformPrompt({ tenantId, dataCoreId, flowTypeId, eventTypeId }),
299+
},
300+
},
301+
],
302+
}
303+
},
304+
)
305+
306+
server.prompt(
307+
"flowcore_platform_contract",
308+
"A prompt for creating a contract to use when using the SDK's, APIs and patterns of the Flowcore Platform",
309+
platformContractPromptRawSchema,
310+
// Handler function that returns the prompt messages
311+
({ tenantId, dataCoreId, flowTypeId, eventTypeId }) => {
312+
return {
313+
messages: [
314+
{
315+
role: "user",
316+
content: {
317+
type: "text",
318+
text: platformContractPrompt({ tenantId, dataCoreId, flowTypeId, eventTypeId }),
319+
},
320+
},
321+
],
322+
}
323+
},
324+
)
325+
265326
// Start receiving messages on stdin and sending messages on stdout
266327
const transport = new StdioServerTransport()
267328
await server.connect(transport)

src/prompts/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./platform-contract"
2+
export * from "./platform-prompt"

src/prompts/platform-contract.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { z } from "zod"
2+
3+
export const platformContractPromptRawSchema = {
4+
tenantId: z.string().optional().describe("The tenant ID to focus on"),
5+
dataCoreId: z.string().optional().describe("The data core ID to focus on"),
6+
flowTypeId: z.string().optional().describe("The flow type ID to focus on"),
7+
eventTypeId: z.string().optional().describe("The event type ID to focus on"),
8+
}
9+
10+
export const platformContractPromptSchema = z.object(platformContractPromptRawSchema)
11+
12+
export type PlatformContractPromptSchema = z.infer<typeof platformContractPromptSchema>
13+
14+
export const platformContractPrompt = ({ tenantId, dataCoreId, flowTypeId, eventTypeId }: PlatformContractPromptSchema): string => {
15+
return `
16+
# Flowcore Platform Contract Assistant
17+
18+
You are an assistant specialized in helping users create contracts to use when using the SDK's, APIs and patterns of the Flowcore Platform.
19+
20+
You should use the get_events tool to get the events that are relevant to the user's context to get the payloads structure of the events.
21+
22+
Then create a typebox or zod schema based on the payloads structure of the events, if the user does not ask for a specific schema, create a typebox schema.
23+
24+
## Example Contract file
25+
26+
<typescript filename="contracts/event-type.0.ts">
27+
import { type Static, Type } from "@sinclair/typebox"
28+
29+
// Flowcore Event
30+
export const EventTypeEventV0 = {
31+
flowType: "event-type.0",
32+
eventTypes: {
33+
indexCreated: "event.event-type.index.created.0",
34+
},
35+
} as const
36+
37+
// Schemas
38+
export const createEventTypeIndex = Type.Object({
39+
tenantId: Type.String(),
40+
dataCoreId: Type.String(),
41+
aggregator: Type.String(),
42+
eventType: Type.String(),
43+
timeBucket: Type.String(),
44+
})
45+
46+
// Types
47+
export type CreateEventTypeIndex = Static<typeof createEventTypeIndex>
48+
</typescript>
49+
50+
if the project uses zod, create a zod schema instead of a typebox schema.
51+
52+
Always create the contract for what the user asks to focus on:
53+
54+
${tenantId ? `\nFocus on tenant ID: ${tenantId}` : ""}
55+
${dataCoreId ? `\nFocus on data core ID: ${dataCoreId}` : ""}
56+
${flowTypeId ? `\nFocus on flow type ID: ${flowTypeId}` : ""}
57+
${eventTypeId ? `\nFocus on event type ID: ${eventTypeId}` : ""}
58+
59+
Use other tools to get the information you need to create the contract.
60+
61+
[Additional instructions to be filled in later]
62+
`
63+
}

src/prompts/platform-prompt.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { z } from "zod"
2+
3+
export const platformPromptRawSchema = {
4+
tenantId: z.string().optional().describe("The tenant ID to focus on"),
5+
dataCoreId: z.string().optional().describe("The data core ID to focus on"),
6+
flowTypeId: z.string().optional().describe("The flow type ID to focus on"),
7+
eventTypeId: z.string().optional().describe("The event type ID to focus on"),
8+
}
9+
10+
export const platformPromptSchema = z.object(platformPromptRawSchema)
11+
12+
export type PlatformPromptSchema = z.infer<typeof platformPromptSchema>
13+
14+
export const platformPrompt = ({ tenantId, dataCoreId, flowTypeId, eventTypeId }: PlatformPromptSchema): string => {
15+
return `
16+
# Flowcore Platform Assistant
17+
18+
You are an assistant specialized in helping users interact with the Flowcore Platform.
19+
20+
## Your capabilities
21+
- Help users navigate and understand the Flowcore Platform
22+
- Assist with querying and analyzing data from the platform
23+
- Provide guidance on platform features and best practices
24+
25+
## Guidelines
26+
- Always use the appropriate tools to fetch real-time data from the platform
27+
- Explain complex concepts in simple terms
28+
- When providing examples, make them relevant to the user's context
29+
30+
${tenantId ? `\nFocus on tenant ID: ${tenantId}` : ""}
31+
${dataCoreId ? `\nFocus on data core ID: ${dataCoreId}` : ""}
32+
${flowTypeId ? `\nFocus on flow type ID: ${flowTypeId}` : ""}
33+
${eventTypeId ? `\nFocus on event type ID: ${eventTypeId}` : ""}
34+
35+
[Additional instructions to be filled in later]
36+
`
37+
}

0 commit comments

Comments
 (0)