@pantheon.ai/mcp 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="TypeScriptCompiler">
4
+ <option name="useServicePoweredTypesEnabledManually" value="true" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/pantheon-mcp.iml" filepath="$PROJECT_DIR$/.idea/pantheon-mcp.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="WEB_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$" />
5
+ <orderEntry type="inheritedJdk" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ </component>
8
+ </module>
package/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@pantheon.ai/mcp",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "description": "",
6
+ "bin": "src/index.ts",
7
+ "scripts": {
8
+ "postinstall": "patch-package"
9
+ },
10
+ "devDependencies": {
11
+ "@modelcontextprotocol/inspector": "^0.19.0",
12
+ "@types/express": "^5.0.6",
13
+ "@types/node": "^24.10.10",
14
+ "ai": "6.0.45",
15
+ "patch-package": "^8.0.1",
16
+ "typescript": "^5.5.3"
17
+ },
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "workspaces": [
22
+ "packages/sdk"
23
+ ],
24
+ "dependencies": {
25
+ "@modelcontextprotocol/sdk": "^1.26.0",
26
+ "express": "^5.2.1",
27
+ "zod": "^4.3.6"
28
+ }
29
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@pantheon/sdk",
3
+ "version": "0.0.0",
4
+ "type": "module",
5
+ "dependencies": {
6
+ "url-template": "^3.1.1",
7
+ "zod": "^4.1.9"
8
+ },
9
+ "devDependencies": {
10
+ "typescript": "^5.9.2"
11
+ },
12
+ "exports": {
13
+ ".": "./src/index.ts",
14
+ "./*": "./src/*.ts"
15
+ }
16
+ }
@@ -0,0 +1,22 @@
1
+ import { defineApi, get, post, typeOf } from "@pantheon/sdk/lib/api"
2
+ import { z } from "zod"
3
+
4
+ export const login = defineApi(
5
+ post`/api/v1/auth/login`,
6
+ typeOf<FormData>(),
7
+ "raw"
8
+ )
9
+
10
+ export const logout = defineApi(post`/api/v1/auth/logout`, null, "raw")
11
+
12
+ export const getMe = defineApi(
13
+ get`/api/v1/users/me`,
14
+ null,
15
+ z.object({
16
+ id: z.string(),
17
+ email: z.string(),
18
+ is_active: z.boolean(),
19
+ is_superuser: z.boolean(),
20
+ is_verified: z.boolean(),
21
+ })
22
+ )
@@ -0,0 +1,27 @@
1
+ import { defineApi, get } from "@pantheon/sdk/lib/api"
2
+ import { paged } from "@pantheon/sdk/schemas/common"
3
+
4
+ import { z } from "zod"
5
+
6
+ export const getGithubUser = defineApi(
7
+ get`/api/v1/connectors/github/user`,
8
+ null,
9
+ z
10
+ .object({
11
+ github_username: z.string(),
12
+ })
13
+ .nullable()
14
+ )
15
+
16
+ export const listGithubRepositories = defineApi(
17
+ get`/api/v1/user/github/repositories?page=${"page"}&size=${"size"}`,
18
+ null,
19
+ paged(
20
+ z.object({
21
+ repo_id: z.number(),
22
+ repo_name: z.string(),
23
+ public: z.boolean(),
24
+ installation_id: z.number(),
25
+ })
26
+ )
27
+ )
@@ -0,0 +1,53 @@
1
+ import { defineApi, del, get, post, put, typeOf } from "@pantheon/sdk/lib/api"
2
+ import { paged } from "@pantheon/sdk/schemas/common"
3
+ import {
4
+ environmentDeleteSchema,
5
+ environmentSchema,
6
+ } from "@pantheon/sdk/schemas/environments"
7
+
8
+ export const listEnvironments = defineApi(
9
+ get`/api/v1/admin/environments?page=${"page"}&size=${"size"}&id=${"id?"}&name=${"name?"}&display_name=${"display_name?"}&repo_name=${"repo_name?"}&repo_id=${"repo_id?"}&query=${"query?"}`,
10
+ null,
11
+ paged(environmentSchema)
12
+ )
13
+
14
+ export const getEnvironment = defineApi(
15
+ get`/api/v1/admin/environments/${"environmentId"}`,
16
+ null,
17
+ environmentSchema
18
+ )
19
+
20
+ export const createEnvironment = defineApi(
21
+ post`/api/v1/admin/environments`,
22
+ typeOf<{
23
+ name: string
24
+ display_name?: string
25
+ description?: string
26
+ base_image_ref?: string
27
+ seed_snap_id?: string
28
+ repo_name?: string
29
+ repo_id?: number
30
+ source_branch_id?: string
31
+ }>(),
32
+ environmentSchema
33
+ )
34
+
35
+ export const updateEnvironment = defineApi(
36
+ put`/api/v1/admin/environments/${"environmentId"}`,
37
+ typeOf<{
38
+ name?: string
39
+ display_name?: string
40
+ description?: string
41
+ base_image_ref?: string
42
+ seed_snap_id?: string
43
+ repo_name?: string
44
+ repo_id?: number | null
45
+ }>(),
46
+ environmentSchema
47
+ )
48
+
49
+ export const deleteEnvironment = defineApi(
50
+ del`/api/v1/admin/environments/${"environmentId"}`,
51
+ null,
52
+ environmentDeleteSchema
53
+ )
@@ -0,0 +1,143 @@
1
+ import { defineApi, del, get, post, typeOf } from "@pantheon/sdk/lib/api"
2
+ import { branchSchema, branchSnapsSchema } from "@pantheon/sdk/schemas/branch"
3
+ import { paged } from "@pantheon/sdk/schemas/common"
4
+ import {
5
+ explorationResultSchema,
6
+ explorationSchema,
7
+ } from "@pantheon/sdk/schemas/exploration"
8
+
9
+ import { FSResponseValidator } from "@pantheon/sdk/schemas/fs"
10
+ import {
11
+ projectBackgroundTaskSchema,
12
+ projectMessageSchema,
13
+ projectSchema,
14
+ } from "@pantheon/sdk/schemas/project"
15
+ import { z } from "zod"
16
+
17
+ export const listProjects = defineApi(
18
+ get`/api/v1/projects?page=${"page"}&size=${"size"}&user_id=${"user_id?"}&category=${"category?"}`,
19
+ null,
20
+ paged(projectSchema)
21
+ )
22
+
23
+ export const getProject = defineApi(
24
+ get`/api/v1/projects/${"projectId"}`,
25
+ null,
26
+ projectSchema
27
+ )
28
+
29
+ export const createProject = defineApi(
30
+ post`/api/v1/projects`,
31
+ typeOf<{
32
+ first_prompt: string
33
+ project_type: "general" | "github"
34
+ github_repo_id?: number
35
+ github_installation_id?: number
36
+ env_id?: string
37
+ }>(),
38
+ projectSchema
39
+ )
40
+
41
+ export const listProjectMessages = defineApi(
42
+ get`/api/v1/projects/${"projectId"}/messages`,
43
+ null,
44
+ z.object({
45
+ messages: projectMessageSchema.array(),
46
+ ongoing_stream_id: z.string().nullable(),
47
+ })
48
+ )
49
+
50
+ export const deleteProjectMessage = defineApi(
51
+ del`/api/v1/projects/${"projectId"}/messages/${"messageId"}`,
52
+ null,
53
+ "raw" as const
54
+ )
55
+
56
+ export const postProjectMessage = defineApi(
57
+ post`/api/v1/projects/${"projectId"}`,
58
+ typeOf<{
59
+ prompt: string
60
+ selected_branches?: string[]
61
+ }>(),
62
+ z.object({
63
+ messages: projectMessageSchema.array(),
64
+ ongoing_stream_id: z.string().nullable(),
65
+ })
66
+ )
67
+
68
+ export const continueProject = defineApi(
69
+ post`/api/v1/projects/${"projectId"}/continue`,
70
+ typeOf<{}>(),
71
+ "raw" as const
72
+ )
73
+
74
+ export const stopProject = defineApi(
75
+ post`/api/v1/projects/${"projectId"}/stop`,
76
+ typeOf<{}>(),
77
+ "raw" as const
78
+ )
79
+
80
+ export const getProjectBranch = defineApi(
81
+ get`/api/v1/projects/${"projectId"}/branches/${"branchId"}`,
82
+ null,
83
+ branchSchema
84
+ )
85
+
86
+ export const getProjectBranchOutput = defineApi(
87
+ get`/api/v1/projects/${"projectId"}/branches/${"branchId"}/output?full_output=${"fullOutput?"}`,
88
+ null,
89
+ z.string()
90
+ )
91
+
92
+ export const listProjectBranches = defineApi(
93
+ get`/api/v1/projects/${"projectId"}/branches?page=${"page"}&size=${"size"}`,
94
+ null,
95
+ paged(branchSchema)
96
+ )
97
+
98
+ export const listProjectBranchSnaps = defineApi(
99
+ get`/api/v1/projects/${"projectId"}/branches/${"branchId"}/snaps`,
100
+ null,
101
+ branchSnapsSchema
102
+ )
103
+
104
+ export const listProjectBackgroundTasks = defineApi(
105
+ get`/api/v1/projects/${"projectId"}/background_tasks?statuses=${"statuses?"}`,
106
+ null,
107
+ z.array(projectBackgroundTaskSchema)
108
+ )
109
+
110
+ export const createProjectExploration = defineApi(
111
+ post`/api/v1/projects/${"projectId"}/explorations`,
112
+ typeOf<{
113
+ parent_branch_id: string
114
+ shared_prompt_sequence: string[] // 1 - 4
115
+ num_branches?: number // default 3, 1 - 50
116
+ agent?: string
117
+ }>(),
118
+ explorationSchema
119
+ )
120
+
121
+ export const listProjectExplorations = defineApi(
122
+ get`/api/v1/projects/${"projectId"}/explorations`,
123
+ null,
124
+ explorationSchema.array()
125
+ )
126
+
127
+ export const getProjectExplorationResult = defineApi(
128
+ get`/api/v1/projects/${"projectId"}/explorations/${"explorationId"}/result`,
129
+ null,
130
+ explorationResultSchema
131
+ )
132
+
133
+ export const getProjectBranchFs = defineApi(
134
+ get`/api/v1/projects/${"projectId"}/branches/${"branchId"}/fs/${"path*"}`,
135
+ null,
136
+ FSResponseValidator
137
+ )
138
+
139
+ export const getProjectBranchFsPreview = defineApi(
140
+ get`/api/v1/projects/${"projectId"}/branches/${"branchId"}/preview/${"path*"}`,
141
+ null,
142
+ FSResponseValidator
143
+ )
@@ -0,0 +1,17 @@
1
+ import { defineApi, get } from "@pantheon/sdk/lib/api"
2
+ import {
3
+ projectMessageStreamParser,
4
+ projectRawMessageStreamParser,
5
+ } from "@pantheon/sdk/schemas/project"
6
+
7
+ export const readMessageStream = defineApi(
8
+ get`/ai_stream_proxy/v2/streams/${"streamId"}/stream?format=vercel-ai-ui-message-stream-v1&skip=${"skip?"}`,
9
+ null,
10
+ projectMessageStreamParser
11
+ )
12
+
13
+ export const readRawMessageStream = defineApi(
14
+ get`/ai_stream_proxy/v2/streams/${"streamId"}/stream?format=opaque-stream-json`,
15
+ null,
16
+ projectRawMessageStreamParser
17
+ )
@@ -0,0 +1,16 @@
1
+ export type { PrimitiveValue } from "url-template"
2
+ export type { Api } from "@pantheon/sdk/lib/api"
3
+
4
+ export * from "@pantheon/sdk/api/projects"
5
+ export * from "@pantheon/sdk/api/connectors"
6
+ export * from "@pantheon/sdk/api/stream-proxy"
7
+ export * from "@pantheon/sdk/lib/vercel-ai-hack"
8
+
9
+ export type {
10
+ MessageMetadata,
11
+ Tools,
12
+ DataTypes,
13
+ MasterAgentMessage,
14
+ MasterAgentMessageChunk,
15
+ MasterAgentMessagePart,
16
+ } from "@pantheon/sdk/schemas/ai"
@@ -0,0 +1,169 @@
1
+ import type {
2
+ Api,
3
+ ApiParams,
4
+ ApiRequestBody,
5
+ ApiResponseBody,
6
+ } from "@pantheon/sdk/lib/api"
7
+ import { type PrimitiveValue } from "url-template"
8
+
9
+ export interface ApiExecutor {
10
+ execute<API extends Api<any, any, any, any>>(
11
+ api: API,
12
+ params: ApiParams<API>,
13
+ body: ApiRequestBody<API> extends void ? null : ApiRequestBody<API>,
14
+ requestInit?: Omit<RequestInit, "method" | "body">
15
+ ): Promise<ApiResponseBody<API>>
16
+
17
+ onError(
18
+ callback: (error: unknown, context: ApiExecutorContext) => void
19
+ ): () => void
20
+ }
21
+
22
+ export interface ApiExecutorContext {
23
+ readonly api: Api<any, any, any, any>
24
+ readonly params: any
25
+ readonly requestBody: any
26
+ readonly url: string
27
+ readonly request: Request
28
+ }
29
+
30
+ export class ApiError extends Error {
31
+ public readonly response: Response
32
+ public readonly context: ApiExecutorContext
33
+ public readonly responseBody: any
34
+
35
+ constructor(
36
+ response: Response,
37
+ context: ApiExecutorContext,
38
+ responseBody: any
39
+ ) {
40
+ super(
41
+ `${context.request.method} ${context.url}: ${response.status} ${response.statusText} ${getServerErrorMessage(responseBody)}`
42
+ )
43
+ this.response = response
44
+ this.context = context
45
+ this.responseBody = responseBody
46
+ }
47
+ }
48
+
49
+ export interface ApiExecutorOptions {
50
+ baseUrl?: string
51
+ headers?: HeadersInit
52
+ validateResponse: (
53
+ response: Response,
54
+ context: ApiExecutorContext
55
+ ) => void | Promise<void>
56
+ }
57
+
58
+ export function createApiExecutor({
59
+ baseUrl,
60
+ headers,
61
+ validateResponse,
62
+ }: ApiExecutorOptions): Readonly<ApiExecutor> {
63
+ const errorCallbacks: ((
64
+ error: unknown,
65
+ context: ApiExecutorContext
66
+ ) => void)[] = []
67
+
68
+ function onError(
69
+ callback: (error: unknown, context: ApiExecutorContext) => void
70
+ ): () => void {
71
+ errorCallbacks.push(callback)
72
+
73
+ return () => {
74
+ const index = errorCallbacks.indexOf(callback)
75
+ if (index !== -1) {
76
+ errorCallbacks.splice(index, 1)
77
+ }
78
+ }
79
+ }
80
+
81
+ async function execute<
82
+ Params extends Record<string, PrimitiveValue> | null,
83
+ RequestBody,
84
+ ResponseBody,
85
+ >(
86
+ api: Api<any, Params, RequestBody, ResponseBody>,
87
+ params: Params,
88
+ requestBody: RequestBody,
89
+ requestInit?: Omit<RequestInit, "method" | "body" | "headers">
90
+ ): Promise<ResponseBody> {
91
+ const url = baseUrl
92
+ ? new URL(api.url(params as any), baseUrl).toString()
93
+ : api.url(params as any)
94
+ const { headers: initHeaders, ...init } = api.requestInit(requestBody)
95
+
96
+ const executorHeaders = new Headers(headers)
97
+ if (initHeaders) {
98
+ new Headers(initHeaders).forEach((value, key) => {
99
+ executorHeaders.set(key, value)
100
+ })
101
+ }
102
+ const request = new Request(url, {
103
+ ...requestInit,
104
+ ...init,
105
+ headers: executorHeaders,
106
+ credentials: "include",
107
+ })
108
+
109
+ const context = Object.freeze({ api, params, requestBody, url, request })
110
+ try {
111
+ const response = await fetch(request)
112
+ await validateResponse(response, context)
113
+ return await api.handleResponse(response, context)
114
+ } catch (error) {
115
+ for (const callback of errorCallbacks) {
116
+ callback(error, context)
117
+ }
118
+ return Promise.reject(error)
119
+ }
120
+ }
121
+
122
+ return Object.freeze({
123
+ execute,
124
+ onError,
125
+ })
126
+ }
127
+
128
+ export async function validateResponse(
129
+ response: Response,
130
+ context: ApiExecutorContext
131
+ ) {
132
+ if (!response.ok) {
133
+ const responseBody = await response
134
+ .clone()
135
+ .json()
136
+ .catch(() => response.clone().text())
137
+ .catch(() => undefined)
138
+
139
+ throw new ApiError(response, context, responseBody)
140
+ }
141
+ }
142
+
143
+ function getServerErrorMessage(error: any): string {
144
+ if (error == null) {
145
+ return "No error message."
146
+ }
147
+
148
+ if (typeof error === "string") {
149
+ return error
150
+ }
151
+
152
+ if (typeof error === "object") {
153
+ for (const key of [
154
+ "message",
155
+ "error",
156
+ "errMsg",
157
+ "errorMsg",
158
+ "detail",
159
+ "details",
160
+ ]) {
161
+ if (key in error) {
162
+ return String(error[key])
163
+ }
164
+ }
165
+ return JSON.stringify(error, undefined, 2)
166
+ }
167
+
168
+ return String(error)
169
+ }