-
Notifications
You must be signed in to change notification settings - Fork 1
ENG-2597: Promote stlc-generated node SDK + MCP server (Stainless cutover) #96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1 @@ | ||
| configured_endpoints: 31 | ||
| openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell/hyperspell-e57add0181eb2a057f8416eaf4020dd5b3042431342a51e3d4dc39af4a41aced.yml | ||
| openapi_spec_hash: d0d66b814ebe56ac7c0135f9f3aab616 | ||
| config_hash: 11e84d884a86d2db0411c35fae6e9121 |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -41,22 +41,22 @@ For clients with a configuration JSON, it might look something like this: | |||||
| If you use Cursor, you can install the MCP server by using the button below. You will need to set your environment variables | ||||||
| in Cursor's `mcp.json`, which can be found in Cursor Settings > Tools & MCP > New MCP Server. | ||||||
|
|
||||||
| [](https://cursor.com/en-US/install-mcp?name=%40hyperspell%2Fhyperspell-mcp&config=eyJuYW1lIjoiQGh5cGVyc3BlbGwvaHlwZXJzcGVsbC1tY3AiLCJ0cmFuc3BvcnQiOiJodHRwIiwidXJsIjoiaHR0cHM6Ly9oeXBlcnNwZWxsLnN0bG1jcC5jb20iLCJoZWFkZXJzIjp7IngtaHlwZXJzcGVsbC1hcGkta2V5IjoiTXkgQVBJIEtleSIsIlgtQXMtVXNlciI6Ik15IFVzZXIgSUQifX0) | ||||||
| [](https://cursor.com/en-US/install-mcp?name=%40hyperspell%2Fhyperspell-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBoeXBlcnNwZWxsL2h5cGVyc3BlbGwtbWNwIl0sImVudiI6eyJIWVBFUlNQRUxMX0FQSV9LRVkiOiJNeSBBUEkgS2V5IiwiSFlQRVJTUEVMTF9VU0VSX0lEIjoiTXkgVXNlciBJRCJ9fQ) | ||||||
|
|
||||||
| ### VS Code | ||||||
|
|
||||||
| If you use MCP, you can install the MCP server by clicking the link below. You will need to set your environment variables | ||||||
| in VS Code's `mcp.json`, which can be found via Command Palette > MCP: Open User Configuration. | ||||||
|
|
||||||
| [Open VS Code](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22%40hyperspell%2Fhyperspell-mcp%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fhyperspell.stlmcp.com%22%2C%22headers%22%3A%7B%22x-hyperspell-api-key%22%3A%22My%20API%20Key%22%2C%22X-As-User%22%3A%22My%20User%20ID%22%7D%7D) | ||||||
| [Open VS Code](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22%40hyperspell%2Fhyperspell-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40hyperspell%2Fhyperspell-mcp%22%5D%2C%22env%22%3A%7B%22HYPERSPELL_API_KEY%22%3A%22My%20API%20Key%22%2C%22HYPERSPELL_USER_ID%22%3A%22My%20User%20ID%22%7D%7D) | ||||||
|
|
||||||
| ### Claude Code | ||||||
|
|
||||||
| If you use Claude Code, you can install the MCP server by running the command below in your terminal. You will need to set your | ||||||
| environment variables in Claude Code's `.claude.json`, which can be found in your home directory. | ||||||
|
|
||||||
| ``` | ||||||
| claude mcp add hyperspell_hyperspell_mcp_api --header "x-hyperspell-api-key: My API Key" --header "X-As-User: My User ID" --transport http https://hyperspell.stlmcp.com | ||||||
| claude mcp add hyperspell_hyperspell_mcp_api --env HYPERSPELL_API_KEY="My API Key" HYPERSPELL_USER_ID="My User ID" -- npx -y @hyperspell/hyperspell-mcp | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Prompt to fix with AI
|
||||||
| ``` | ||||||
|
|
||||||
| ## Code Mode | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,7 +2,7 @@ | |||||||||||
|
|
||||||||||||
| import { Tool } from '@modelcontextprotocol/sdk/types.js'; | ||||||||||||
| import { Metadata, McpRequestContext, asTextContentResult } from './types'; | ||||||||||||
| import { getLogger } from './logger'; | ||||||||||||
|
|
||||||||||||
| import type { LocalDocsSearch } from './local-docs-search'; | ||||||||||||
|
|
||||||||||||
| export const metadata: Metadata = { | ||||||||||||
|
|
@@ -41,9 +41,6 @@ export const tool: Tool = { | |||||||||||
| }, | ||||||||||||
| }; | ||||||||||||
|
|
||||||||||||
| const docsSearchURL = | ||||||||||||
| process.env['DOCS_SEARCH_URL'] || 'https://api.stainless.com/api/projects/hyperspell/docs/search'; | ||||||||||||
|
|
||||||||||||
| let _localSearch: LocalDocsSearch | undefined; | ||||||||||||
|
|
||||||||||||
| export function setLocalSearch(search: LocalDocsSearch): void { | ||||||||||||
|
|
@@ -67,58 +64,6 @@ async function searchLocal(args: Record<string, unknown>): Promise<unknown> { | |||||||||||
| }).results; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| async function searchRemote(args: Record<string, unknown>, reqContext: McpRequestContext): Promise<unknown> { | ||||||||||||
| const body = args as any; | ||||||||||||
| const query = new URLSearchParams(body).toString(); | ||||||||||||
|
|
||||||||||||
| const startTime = Date.now(); | ||||||||||||
| const result = await fetch(`${docsSearchURL}?${query}`, { | ||||||||||||
| headers: { | ||||||||||||
| ...(reqContext.stainlessApiKey && { Authorization: reqContext.stainlessApiKey }), | ||||||||||||
| ...(reqContext.mcpSessionId && { 'x-stainless-mcp-session-id': reqContext.mcpSessionId }), | ||||||||||||
| ...(reqContext.mcpClientInfo && { | ||||||||||||
| 'x-stainless-mcp-client-info': JSON.stringify(reqContext.mcpClientInfo), | ||||||||||||
| }), | ||||||||||||
| }, | ||||||||||||
| }); | ||||||||||||
|
|
||||||||||||
| const logger = getLogger(); | ||||||||||||
|
|
||||||||||||
| if (!result.ok) { | ||||||||||||
| const errorText = await result.text(); | ||||||||||||
| logger.warn( | ||||||||||||
| { | ||||||||||||
| durationMs: Date.now() - startTime, | ||||||||||||
| query: body.query, | ||||||||||||
| status: result.status, | ||||||||||||
| statusText: result.statusText, | ||||||||||||
| errorText, | ||||||||||||
| }, | ||||||||||||
| 'Got error response from docs search tool', | ||||||||||||
| ); | ||||||||||||
|
|
||||||||||||
| if (result.status === 404 && !reqContext.stainlessApiKey) { | ||||||||||||
| throw new Error( | ||||||||||||
| 'Could not find docs for this project. You may need to provide a Stainless API key via the STAINLESS_API_KEY environment variable, the --stainless-api-key flag, or the x-stainless-api-key HTTP header.', | ||||||||||||
| ); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| throw new Error( | ||||||||||||
| `${result.status}: ${result.statusText} when using doc search tool. Details: ${errorText}`, | ||||||||||||
| ); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| const resultBody = await result.json(); | ||||||||||||
| logger.info( | ||||||||||||
| { | ||||||||||||
| durationMs: Date.now() - startTime, | ||||||||||||
| query: body.query, | ||||||||||||
| }, | ||||||||||||
| 'Got docs search result', | ||||||||||||
| ); | ||||||||||||
| return resultBody; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| export const handler = async ({ | ||||||||||||
| reqContext, | ||||||||||||
| args, | ||||||||||||
|
|
@@ -128,11 +73,7 @@ export const handler = async ({ | |||||||||||
| }) => { | ||||||||||||
| const body = args ?? {}; | ||||||||||||
|
|
||||||||||||
| if (_localSearch) { | ||||||||||||
| return asTextContentResult(await searchLocal(body)); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| return asTextContentResult(await searchRemote(body, reqContext)); | ||||||||||||
| return asTextContentResult(await searchLocal(body)); | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Prompt to fix with AI
|
||||||||||||
| }; | ||||||||||||
|
|
||||||||||||
| export default { metadata, tool, handler }; | ||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GitHub Actions secrets are not exposed as env vars automatically;
.github/workflows/release-doctor.ymlruns this script with noenv:block, soRELEASE_PLEASE_TOKENis always empty and the check always errors, blocking every release-please PR.Prompt to fix with AI