This repository was archived by the owner on Jan 19, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 27
feat: tools refactor #54
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| import { z } from "zod"; | ||
| import type { Context, Tool } from "../types"; | ||
| import { AddInsightToDashboardSchema } from "../../schema/dashboards"; | ||
| import { getProjectBaseUrl } from "../../lib/utils/api"; | ||
|
|
||
| const schema = z.object({ | ||
| data: AddInsightToDashboardSchema, | ||
| }); | ||
|
|
||
| type Params = z.infer<typeof schema>; | ||
|
|
||
| export const addInsightHandler = async (context: Context, params: Params) => { | ||
| const { data } = params; | ||
| const projectId = await context.getProjectId(); | ||
|
|
||
| const insightResult = await context.api | ||
| .insights({ projectId }) | ||
| .get({ insightId: data.insight_id }); | ||
|
|
||
| if (!insightResult.success) { | ||
| throw new Error(`Failed to get insight: ${insightResult.error.message}`); | ||
| } | ||
|
|
||
| const result = await context.api.dashboards({ projectId }).addInsight({ data }); | ||
|
|
||
| if (!result.success) { | ||
| throw new Error(`Failed to add insight to dashboard: ${result.error.message}`); | ||
| } | ||
|
|
||
| const resultWithUrls = { | ||
| ...result.data, | ||
| dashboard_url: `${getProjectBaseUrl(projectId)}/dashboard/${data.dashboard_id}`, | ||
| insight_url: `${getProjectBaseUrl(projectId)}/insights/${insightResult.data.short_id}`, | ||
| }; | ||
|
|
||
| return { content: [{ type: "text", text: JSON.stringify(resultWithUrls) }] }; | ||
| }; | ||
|
|
||
| const tool = (): Tool<typeof schema> => ({ | ||
| name: "add-insight-to-dashboard", | ||
| description: ` | ||
| - Add an existing insight to a dashboard. | ||
| - Requires insight ID and dashboard ID. | ||
| - Optionally supports layout and color customization. | ||
| `, | ||
| schema, | ||
| handler: addInsightHandler, | ||
| }); | ||
|
|
||
| export default tool; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import { z } from "zod"; | ||
| import type { Context, Tool } from "../types"; | ||
| import { CreateDashboardInputSchema } from "../../schema/dashboards"; | ||
| import { getProjectBaseUrl } from "../../lib/utils/api"; | ||
|
|
||
| const schema = z.object({ | ||
| data: CreateDashboardInputSchema, | ||
| }); | ||
|
|
||
| type Params = z.infer<typeof schema>; | ||
|
|
||
| export const createHandler = async (context: Context, params: Params) => { | ||
| const { data } = params; | ||
| const projectId = await context.getProjectId(); | ||
| const dashboardResult = await context.api.dashboards({ projectId }).create({ data }); | ||
|
|
||
| if (!dashboardResult.success) { | ||
| throw new Error(`Failed to create dashboard: ${dashboardResult.error.message}`); | ||
| } | ||
|
|
||
| const dashboardWithUrl = { | ||
| ...dashboardResult.data, | ||
| url: `${getProjectBaseUrl(projectId)}/dashboard/${dashboardResult.data.id}`, | ||
| }; | ||
|
|
||
| return { content: [{ type: "text", text: JSON.stringify(dashboardWithUrl) }] }; | ||
| }; | ||
|
|
||
| const tool = (): Tool<typeof schema> => ({ | ||
| name: "dashboard-create", | ||
| description: ` | ||
| - Create a new dashboard in the project. | ||
| - Requires name and optional description, tags, and other properties. | ||
| `, | ||
| schema, | ||
| handler: createHandler, | ||
| }); | ||
|
|
||
| export default tool; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import { z } from "zod"; | ||
| import type { Context, Tool } from "../types"; | ||
|
|
||
| const schema = z.object({ | ||
| dashboardId: z.number(), | ||
| }); | ||
|
|
||
| type Params = z.infer<typeof schema>; | ||
|
|
||
| export const deleteHandler = async (context: Context, params: Params) => { | ||
| const { dashboardId } = params; | ||
| const projectId = await context.getProjectId(); | ||
| const result = await context.api.dashboards({ projectId }).delete({ dashboardId }); | ||
|
|
||
| if (!result.success) { | ||
| throw new Error(`Failed to delete dashboard: ${result.error.message}`); | ||
| } | ||
|
|
||
| return { content: [{ type: "text", text: JSON.stringify(result.data) }] }; | ||
| }; | ||
|
|
||
| const tool = (): Tool<typeof schema> => ({ | ||
| name: "dashboard-delete", | ||
| description: ` | ||
| - Delete a dashboard by ID (soft delete - marks as deleted). | ||
| `, | ||
| schema, | ||
| handler: deleteHandler, | ||
| }); | ||
|
|
||
| export default tool; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import { z } from "zod"; | ||
| import type { Context, Tool } from "../types"; | ||
|
|
||
| const schema = z.object({ | ||
| dashboardId: z.number(), | ||
| }); | ||
|
|
||
| type Params = z.infer<typeof schema>; | ||
|
|
||
| export const getHandler = async (context: Context, params: Params) => { | ||
| const { dashboardId } = params; | ||
| const projectId = await context.getProjectId(); | ||
| const dashboardResult = await context.api.dashboards({ projectId }).get({ dashboardId }); | ||
|
|
||
| if (!dashboardResult.success) { | ||
| throw new Error(`Failed to get dashboard: ${dashboardResult.error.message}`); | ||
| } | ||
|
|
||
| return { content: [{ type: "text", text: JSON.stringify(dashboardResult.data) }] }; | ||
| }; | ||
|
|
||
| const tool = (): Tool<typeof schema> => ({ | ||
| name: "dashboard-get", | ||
| description: ` | ||
| - Get a specific dashboard by ID. | ||
| `, | ||
| schema, | ||
| handler: getHandler, | ||
| }); | ||
|
|
||
| export default tool; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| import { z } from "zod"; | ||
| import type { Context, Tool } from "../types"; | ||
| import { ListDashboardsSchema } from "../../schema/dashboards"; | ||
|
|
||
| const schema = z.object({ | ||
| data: ListDashboardsSchema.optional(), | ||
| }); | ||
|
|
||
| type Params = z.infer<typeof schema>; | ||
|
|
||
| export const getAllHandler = async (context: Context, params: Params) => { | ||
| const { data } = params; | ||
| const projectId = await context.getProjectId(); | ||
| const dashboardsResult = await context.api.dashboards({ projectId }).list({ params: data }); | ||
|
|
||
| if (!dashboardsResult.success) { | ||
| throw new Error(`Failed to get dashboards: ${dashboardsResult.error.message}`); | ||
| } | ||
|
|
||
| return { content: [{ type: "text", text: JSON.stringify(dashboardsResult.data) }] }; | ||
| }; | ||
|
|
||
| const tool = (): Tool<typeof schema> => ({ | ||
| name: "dashboards-get-all", | ||
| description: ` | ||
| - Get all dashboards in the project with optional filtering. | ||
| - Can filter by pinned status, search term, or pagination. | ||
| `, | ||
| schema, | ||
| handler: getAllHandler, | ||
| }); | ||
|
|
||
| export default tool; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| import { z } from "zod"; | ||
| import type { Context, Tool } from "../types"; | ||
| import { UpdateDashboardInputSchema } from "../../schema/dashboards"; | ||
| import { getProjectBaseUrl } from "../../lib/utils/api"; | ||
|
|
||
| const schema = z.object({ | ||
| dashboardId: z.number(), | ||
| data: UpdateDashboardInputSchema, | ||
| }); | ||
|
|
||
| type Params = z.infer<typeof schema>; | ||
|
|
||
| export const updateHandler = async (context: Context, params: Params) => { | ||
| const { dashboardId, data } = params; | ||
| const projectId = await context.getProjectId(); | ||
| const dashboardResult = await context.api | ||
| .dashboards({ projectId }) | ||
| .update({ dashboardId, data }); | ||
|
|
||
| if (!dashboardResult.success) { | ||
| throw new Error(`Failed to update dashboard: ${dashboardResult.error.message}`); | ||
| } | ||
|
|
||
| const dashboardWithUrl = { | ||
| ...dashboardResult.data, | ||
| url: `${getProjectBaseUrl(projectId)}/dashboard/${dashboardResult.data.id}`, | ||
| }; | ||
|
|
||
| return { content: [{ type: "text", text: JSON.stringify(dashboardWithUrl) }] }; | ||
| }; | ||
|
|
||
| const tool = (): Tool<typeof schema> => ({ | ||
| name: "dashboard-update", | ||
| description: ` | ||
| - Update an existing dashboard by ID. | ||
| - Can update name, description, pinned status or tags. | ||
| `, | ||
| schema, | ||
| handler: updateHandler, | ||
| }); | ||
|
|
||
| export default tool; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import { z } from "zod"; | ||
| import type { Context, Tool } from "../types"; | ||
| import { docsSearch } from "../../inkeepApi"; | ||
|
|
||
| const schema = z.object({ | ||
| query: z.string(), | ||
| }); | ||
|
|
||
| type Params = z.infer<typeof schema>; | ||
|
|
||
| export const searchDocsHandler = async (context: Context, params: Params) => { | ||
| const { query } = params; | ||
| const inkeepApiKey = context.env.INKEEP_API_KEY; | ||
|
|
||
| if (!inkeepApiKey) { | ||
| return { | ||
| content: [ | ||
| { | ||
| type: "text", | ||
| text: "Error: INKEEP_API_KEY is not configured.", | ||
| }, | ||
| ], | ||
| }; | ||
| } | ||
| const resultText = await docsSearch(inkeepApiKey, query); | ||
| return { content: [{ type: "text", text: resultText }] }; | ||
| }; | ||
|
|
||
| const tool = (): Tool<typeof schema> => ({ | ||
| name: "docs-search", | ||
| description: ` | ||
| - Use this tool to search the PostHog documentation for information that can help the user with their request. | ||
| - Use it as a fallback when you cannot answer the user's request using other tools in this MCP. | ||
| `, | ||
| schema, | ||
| handler: searchDocsHandler, | ||
| }); | ||
|
|
||
| export default tool; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| import { z } from "zod"; | ||
| import type { Context, Tool } from "../types"; | ||
| import { ErrorDetailsSchema } from "../../schema/errors"; | ||
|
|
||
| const schema = z.object({ | ||
| data: ErrorDetailsSchema, | ||
| }); | ||
|
|
||
| type Params = z.infer<typeof schema>; | ||
|
|
||
| export const errorDetailsHandler = async (context: Context, params: Params) => { | ||
| const { data } = params; | ||
| const projectId = await context.getProjectId(); | ||
|
|
||
| const errorQuery = { | ||
| kind: "ErrorTrackingQuery", | ||
| dateRange: { | ||
| date_from: | ||
| data.dateFrom?.toISOString() || | ||
| new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(), | ||
| date_to: data.dateTo?.toISOString() || new Date().toISOString(), | ||
| }, | ||
| volumeResolution: 0, | ||
| issueId: data.issueId, | ||
| }; | ||
|
|
||
| const errorsResult = await context.api.query({ projectId }).execute({ queryBody: errorQuery }); | ||
| if (!errorsResult.success) { | ||
| throw new Error(`Failed to get error details: ${errorsResult.error.message}`); | ||
| } | ||
|
|
||
| return { | ||
| content: [{ type: "text", text: JSON.stringify(errorsResult.data.results) }], | ||
| }; | ||
| }; | ||
|
|
||
| const tool = (): Tool<typeof schema> => ({ | ||
| name: "error-details", | ||
| description: ` | ||
| - Use this tool to get the details of an error in the project. | ||
| `, | ||
| schema, | ||
| handler: errorDetailsHandler, | ||
| }); | ||
|
|
||
| export default tool; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| import { z } from "zod"; | ||
| import type { Context, Tool } from "../types"; | ||
| import { ListErrorsSchema } from "../../schema/errors"; | ||
|
|
||
| const schema = z.object({ | ||
| data: ListErrorsSchema, | ||
| }); | ||
|
|
||
| type Params = z.infer<typeof schema>; | ||
|
|
||
| export const listErrorsHandler = async (context: Context, params: Params) => { | ||
| const { data } = params; | ||
| const projectId = await context.getProjectId(); | ||
|
|
||
| const errorQuery = { | ||
| kind: "ErrorTrackingQuery", | ||
| orderBy: data.orderBy || "occurrences", | ||
| dateRange: { | ||
| date_from: | ||
| data.dateFrom?.toISOString() || | ||
| new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(), | ||
| date_to: data.dateTo?.toISOString() || new Date().toISOString(), | ||
| }, | ||
| volumeResolution: 1, | ||
| orderDirection: data.orderDirection || "DESC", | ||
| filterTestAccounts: data.filterTestAccounts ?? true, | ||
| status: data.status || "active", | ||
| }; | ||
|
|
||
| const errorsResult = await context.api.query({ projectId }).execute({ queryBody: errorQuery }); | ||
| if (!errorsResult.success) { | ||
| throw new Error(`Failed to list errors: ${errorsResult.error.message}`); | ||
| } | ||
|
|
||
| return { | ||
| content: [{ type: "text", text: JSON.stringify(errorsResult.data.results) }], | ||
| }; | ||
| }; | ||
|
|
||
| const tool = (): Tool<typeof schema> => ({ | ||
| name: "list-errors", | ||
| description: ` | ||
| - Use this tool to list errors in the project. | ||
| `, | ||
| schema, | ||
| handler: listErrorsHandler, | ||
| }); | ||
|
|
||
| export default tool; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.