Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion .mise-tasks/seed.mts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { projectsRead } from "@gram/client/funcs/projectsRead.js";
import { toolsList } from "@gram/client/funcs/toolsList.js";
import { toolsetsCreate } from "@gram/client/funcs/toolsetsCreate.js";
import { toolsetsUpdateBySlug } from "@gram/client/funcs/toolsetsUpdateBySlug.js";
import { mcpMetadataSet } from "@gram/client/funcs/mcpMetadataSet.js";
import { ServiceError } from "@gram/client/models/errors";
import { $ } from "zx";

Expand All @@ -27,6 +28,8 @@ type Asset = {
slug: string;
filename: string;
storybookDefault?: boolean;
docsUrl?: string;
docsBtnText?: string;
};

const SEED_PROJECTS: {
Expand All @@ -47,6 +50,8 @@ const SEED_PROJECTS: {
slug: "kitchen-sink",
filename: path.join("local", "openapi", "kitchen-sink.json"),
storybookDefault: true,
docsUrl: "https://docs.getgram.ai",
docsBtnText: "Gram Docs",
},
{
type: "openapi",
Expand Down Expand Up @@ -149,6 +154,8 @@ async function seed() {
projectSlug,
assetSlug: asset.slug,
mcpPublic,
docsUrl: asset.docsUrl,
docsBtnText: asset.docsBtnText,
});
verb = toolset.created ? "Created" : "Updated";
log.info(
Expand Down Expand Up @@ -339,8 +346,10 @@ async function upsertToolset(init: {
projectSlug: string;
assetSlug: string;
mcpPublic: boolean;
docsUrl?: string;
docsBtnText?: string;
}): Promise<Toolset> {
const { gram, serverURL, sessionId, projectSlug, assetSlug, mcpPublic } =
const { gram, serverURL, sessionId, projectSlug, assetSlug, mcpPublic, docsUrl, docsBtnText } =
init;
const toolRes = await toolsList(
gram,
Expand Down Expand Up @@ -469,6 +478,29 @@ async function upsertToolset(init: {

log.info(`${toolset.mcpURL} visibility was changed to public`);

// Set MCP metadata if docs URL is provided
if (docsUrl) {
const metadataRes = await mcpMetadataSet(
gram,
{
setMcpMetadataRequestBody: {
toolsetSlug: toolset.slug,
externalDocumentationUrl: docsUrl,
externalDocumentationText: docsBtnText,
},
},
{
sessionHeaderGramSession: sessionId,
projectSlugHeaderGramProject: projectSlug,
},
);
if (!metadataRes.ok) {
log.warn(`Failed to set MCP metadata for toolset '${toolset.slug}': ${metadataRes.error}`);
} else {
log.info(`Set MCP metadata for toolset '${toolset.slug}' (docs: ${docsUrl})`);
}
}

return toolset;
}

Expand Down
6 changes: 6 additions & 0 deletions .speakeasy/out.openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13678,6 +13678,9 @@ components:
type: string
description: When the metadata entry was created
format: date-time
external_documentation_text:
type: string
description: Custom text for the external documentation link button
external_documentation_url:
type: string
description: A link to external documentation for the MCP install page
Expand Down Expand Up @@ -14826,6 +14829,9 @@ components:
SetMcpMetadataRequestBody:
type: object
properties:
external_documentation_text:
type: string
description: Custom text for the external documentation link button
external_documentation_url:
type: string
description: A link to external documentation for the MCP install page
Expand Down
20 changes: 10 additions & 10 deletions client/sdk/.speakeasy/gen.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/sdk/.speakeasy/gen.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/sdk/docs/models/components/mcpmetadata.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/sdk/jsr.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/sdk/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions client/sdk/src/lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
export const SDK_METADATA = {
language: "typescript",
openapiDocVersion: "0.0.1",
sdkVersion: "0.26.4",
sdkVersion: "0.26.5",
genVersion: "2.801.0",
userAgent: "speakeasy-sdk/typescript 0.26.4 2.801.0 0.0.1 @gram/client",
userAgent: "speakeasy-sdk/typescript 0.26.5 2.801.0 0.0.1 @gram/client",
} as const;
6 changes: 6 additions & 0 deletions client/sdk/src/models/components/mcpmetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ export type McpMetadata = {
* When the metadata entry was created
*/
createdAt: Date;
/**
* Custom text for the external documentation link button
*/
externalDocumentationText?: string | undefined;
/**
* A link to external documentation for the MCP install page
*/
Expand Down Expand Up @@ -53,6 +57,7 @@ export const McpMetadata$inboundSchema: z.ZodType<
unknown
> = z.object({
created_at: z.string().datetime({ offset: true }).transform(v => new Date(v)),
external_documentation_text: z.string().optional(),
external_documentation_url: z.string().optional(),
header_display_names: z.record(z.string()).optional(),
id: z.string(),
Expand All @@ -63,6 +68,7 @@ export const McpMetadata$inboundSchema: z.ZodType<
}).transform((v) => {
return remap$(v, {
"created_at": "createdAt",
"external_documentation_text": "externalDocumentationText",
"external_documentation_url": "externalDocumentationUrl",
"header_display_names": "headerDisplayNames",
"logo_asset_id": "logoAssetId",
Expand Down
7 changes: 7 additions & 0 deletions client/sdk/src/models/components/setmcpmetadatarequestbody.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import * as z from "zod/v3";
import { remap as remap$ } from "../../lib/primitives.js";

export type SetMcpMetadataRequestBody = {
/**
* Custom text for the external documentation link button
*/
externalDocumentationText?: string | undefined;
/**
* A link to external documentation for the MCP install page
*/
Expand All @@ -26,6 +30,7 @@ export type SetMcpMetadataRequestBody = {

/** @internal */
export type SetMcpMetadataRequestBody$Outbound = {
external_documentation_text?: string | undefined;
external_documentation_url?: string | undefined;
instructions?: string | undefined;
logo_asset_id?: string | undefined;
Expand All @@ -38,12 +43,14 @@ export const SetMcpMetadataRequestBody$outboundSchema: z.ZodType<
z.ZodTypeDef,
SetMcpMetadataRequestBody
> = z.object({
externalDocumentationText: z.string().optional(),
externalDocumentationUrl: z.string().optional(),
instructions: z.string().optional(),
logoAssetId: z.string().optional(),
toolsetSlug: z.string(),
}).transform((v) => {
return remap$(v, {
externalDocumentationText: "external_documentation_text",
externalDocumentationUrl: "external_documentation_url",
logoAssetId: "logo_asset_id",
toolsetSlug: "toolset_slug",
Expand Down
1 change: 1 addition & 0 deletions server/database/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,7 @@ CREATE TABLE IF NOT EXISTS mcp_metadata (
toolset_id UUID NOT NULL,
project_id UUID NOT NULL,
external_documentation_url TEXT,
external_documentation_text TEXT,
logo_id UUID,
instructions TEXT,
header_display_names JSONB NOT NULL DEFAULT '{}'::JSONB, -- DEPRECATED: use mcp_environment_configs table instead
Expand Down
2 changes: 2 additions & 0 deletions server/design/mcpmetadata/design.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var McpMetadata = Type("McpMetadata", func() {
Attribute("external_documentation_url", String, "A link to external documentation for the MCP install page", func() {
Format(FormatURI)
})
Attribute("external_documentation_text", String, "Custom text for the external documentation link button")
Attribute("instructions", String, "Server instructions returned in the MCP initialize response")
Attribute("header_display_names", MapOf(String, String), "Maps security scheme keys to user-friendly display names")
Attribute("created_at", String, "When the metadata entry was created", func() {
Expand Down Expand Up @@ -75,6 +76,7 @@ var _ = Service("mcpMetadata", func() {
Attribute("toolset_slug", shared.Slug, "The slug of the toolset associated with this install page metadata")
Attribute("logo_asset_id", String, "The asset ID for the MCP install page logo")
Attribute("external_documentation_url", String, "A link to external documentation for the MCP install page")
Attribute("external_documentation_text", String, "Custom text for the external documentation link button")
Attribute("instructions", String, "Server instructions returned in the MCP initialize response")

Required("toolset_slug")
Expand Down
Loading
Loading