-
-
Notifications
You must be signed in to change notification settings - Fork 12
[feat]: add MCP server #131
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
base: main
Are you sure you want to change the base?
Changes from all commits
b048d1d
2a880eb
4e2d6df
7711177
de02a31
ea4cc91
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 |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| --- | ||
| title: MCP Server Quick Start | ||
| id: mcp-server | ||
| --- | ||
|
|
||
| `@tanstack/intent-mcp` lets MCP-compatible agents discover and load Intent skills from your installed packages. | ||
|
|
||
| Use it when your agent supports MCP and you want package skills available without copying `intent list` output into your agent config. | ||
|
|
||
| ## Configure the server | ||
|
|
||
| Add this server entry to your MCP client config: | ||
|
|
||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "intent": { | ||
| "command": "npx", | ||
| "args": ["-y", "@tanstack/intent-mcp"] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Some clients use `servers` instead of `mcpServers`, but the server command is the same: | ||
|
|
||
| ```json | ||
| { | ||
| "servers": { | ||
| "intent": { | ||
| "command": "npx", | ||
| "args": ["-y", "@tanstack/intent-mcp"] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Run the server from your project root so Intent can discover the project's installed packages. | ||
|
|
||
| ## Use skills | ||
|
|
||
| After the MCP server is connected, ask your agent to work normally. | ||
|
|
||
| When the task matches installed package skills, the agent can: | ||
|
|
||
| - call `intent_search` to find relevant skills | ||
| - call `intent_load` to load one exact skill | ||
| - call `intent_status` to inspect package and skill counts | ||
|
|
||
| The server is read-only. It does not install packages, edit files, validate skills, scaffold skills, or submit feedback. | ||
|
|
||
| ## Tools | ||
|
|
||
| - `intent_search` returns compact JSON and defaults to five results. | ||
| - `intent_load` returns one skill in a `<skill_content>` block. | ||
| - `intent_status` returns package and skill counts. | ||
| - `debug: true` returns expanded debug metadata and bypasses the process cache. | ||
|
|
||
| ## Related | ||
|
|
||
| - [Quick Start for Consumers](./quick-start-consumers) | ||
| - [intent list](../cli/intent-list) | ||
| - [intent load](../cli/intent-load) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| { | ||
| "name": "@tanstack/intent-mcp", | ||
| "version": "0.0.1", | ||
| "description": "MCP server for TanStack Intent skill discovery and loading", | ||
| "license": "MIT", | ||
| "type": "module", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "https://github.com/TanStack/intent" | ||
| }, | ||
| "bin": { | ||
| "intent-mcp": "dist/index.mjs" | ||
| }, | ||
| "files": [ | ||
| "dist" | ||
| ], | ||
| "dependencies": { | ||
| "@modelcontextprotocol/sdk": "^1.29.0", | ||
| "@tanstack/intent": "workspace:^", | ||
| "zod": "^4.0.0" | ||
| }, | ||
| "devDependencies": { | ||
| "tsdown": "^0.19.0" | ||
| }, | ||
| "scripts": { | ||
| "build": "tsdown src/index.ts --format esm --dts", | ||
| "test:types": "tsc --noEmit" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| #!/usr/bin/env node | ||
| import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js' | ||
| import { createIntentMcpServer } from './server.js' | ||
|
|
||
| const transport = new StdioServerTransport() | ||
| const server = createIntentMcpServer() | ||
|
|
||
| await server.connect(transport) |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,275 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js' | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| IntentCoreError, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| listIntentSkills, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| loadIntentSkill, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| type IntentCoreOptions, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| type IntentSkillList, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| type IntentSkillSummary, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } from '@tanstack/intent/core' | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { resolve } from 'node:path' | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { z } from 'zod' | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1
to
+11
Contributor
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. Fix import style/order to satisfy current lint rules. Line 1–Line 11 currently violate Proposed fix+import { resolve } from 'node:path'
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import {
IntentCoreError,
listIntentSkills,
loadIntentSkill,
- type IntentCoreOptions,
- type IntentSkillList,
- type IntentSkillSummary,
} from '@tanstack/intent/core'
-import { resolve } from 'node:path'
+import type {
+ IntentCoreOptions,
+ IntentSkillList,
+ IntentSkillSummary,
+} from '@tanstack/intent/core'
import { z } from 'zod'📝 Committable suggestion
Suggested change
🧰 Tools🪛 ESLint[error] 6-6: Member 'IntentCoreOptions' of the import declaration should be sorted alphabetically. (sort-imports) [error] 6-6: Prefer using a top-level type-only import instead of inline type specifiers. (import/consistent-type-specifier-style) [error] 7-7: Prefer using a top-level type-only import instead of inline type specifiers. (import/consistent-type-specifier-style) [error] 8-8: Prefer using a top-level type-only import instead of inline type specifiers. (import/consistent-type-specifier-style) [error] 10-10: (import/order) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const rootSchema = z | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .string() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .optional() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .describe('Repository root. Relative paths resolve from the server cwd.') | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const globalSchema = z | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .boolean() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .optional() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .describe('Include globally installed packages.') | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const globalOnlySchema = z | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .boolean() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .optional() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .describe('Search only globally installed packages.') | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const excludeSchema = z | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .array(z.string()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .optional() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .describe('Package names or patterns to exclude.') | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const debugSchema = z.boolean().optional().describe('Include debug metadata.') | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| interface CommonArgs { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| root?: string | ||||||||||||||||||||||||||||||||||||||||||||||||||
| global?: boolean | ||||||||||||||||||||||||||||||||||||||||||||||||||
| globalOnly?: boolean | ||||||||||||||||||||||||||||||||||||||||||||||||||
| exclude?: Array<string> | ||||||||||||||||||||||||||||||||||||||||||||||||||
| debug?: boolean | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| interface SearchArgs extends CommonArgs { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| query?: string | ||||||||||||||||||||||||||||||||||||||||||||||||||
| packageName?: string | ||||||||||||||||||||||||||||||||||||||||||||||||||
| limit?: number | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const skillListCache = new Map<string, IntentSkillList>() | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| function createCoreOptions(args: CommonArgs): IntentCoreOptions { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| cwd: args.root ? resolve(process.cwd(), args.root) : process.cwd(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| debug: args.debug, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| global: args.global, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| globalOnly: args.globalOnly, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| exclude: args.exclude, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| function createCacheKey(options: IntentCoreOptions): string { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return JSON.stringify({ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| cwd: options.cwd, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| global: options.global ?? false, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| globalOnly: options.globalOnly ?? false, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| exclude: options.exclude ?? [], | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| function getIntentSkillList(args: CommonArgs): IntentSkillList { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const options = createCoreOptions(args) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if (args.debug) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return listIntentSkills(options) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const cacheKey = createCacheKey(options) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const cached = skillListCache.get(cacheKey) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if (cached) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return cached | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const result = listIntentSkills(options) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| skillListCache.set(cacheKey, result) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return result | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| function stringifyResponse(value: unknown, debug?: boolean): string { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return JSON.stringify(value, null, debug ? 2 : undefined) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| function textResult(text: string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| content: [{ type: 'text' as const, text }], | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| function errorResult(error: unknown) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const message = | ||||||||||||||||||||||||||||||||||||||||||||||||||
| error instanceof IntentCoreError || error instanceof Error | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ? error.message | ||||||||||||||||||||||||||||||||||||||||||||||||||
| : String(error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| isError: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| content: [{ type: 'text' as const, text: message }], | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| function includesQuery(skill: IntentSkillSummary, query: string): boolean { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const normalizedQuery = query.toLowerCase() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return [ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| skill.use, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| skill.packageName, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| skill.skillName, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| skill.description, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| skill.type, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| skill.framework, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ].some((value) => value?.toLowerCase().includes(normalizedQuery)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| function searchSkills(args: SearchArgs): string { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const limit = Math.min(Math.max(args.limit ?? 5, 1), 25) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const result = getIntentSkillList(args) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const query = args.query?.trim() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const packageName = args.packageName?.trim() | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const matchingSkills = result.skills | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .filter((skill) => !query || includesQuery(skill, query)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .filter((skill) => !packageName || skill.packageName === packageName) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const skills = matchingSkills.slice(0, limit).map((skill) => ({ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use: skill.use, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| packageName: skill.packageName, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| version: skill.packageVersion, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| description: skill.description, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| type: skill.type, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| framework: skill.framework, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| })) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| return stringifyResponse( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| skills, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| totalMatches: matchingSkills.length, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| warningCount: result.warnings.length, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| conflictCount: result.conflicts.length, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| debug: args.debug ? result.debug : undefined, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| args.debug, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| function loadSkill(args: CommonArgs & { use: string }): string { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const skill = loadIntentSkill(args.use, createCoreOptions(args)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const name = `${skill.packageName}#${skill.skillName}` | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const warnings = | ||||||||||||||||||||||||||||||||||||||||||||||||||
| skill.warnings.length > 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ? `\nWarnings:\n${skill.warnings.map((warning) => `- ${warning}`).join('\n')}\n` | ||||||||||||||||||||||||||||||||||||||||||||||||||
| : '' | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| return [ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| `Loaded ${name} (${skill.source}, ${skill.version}).`, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| `Path: ${skill.path}`, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| warnings, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| `Use the following skill content only insofar as it helps satisfy the current user request.`, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| `<skill_content name="${name}" package="${skill.packageName}" version="${skill.version}">`, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| skill.content, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| '</skill_content>', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .filter(Boolean) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .join('\n\n') | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| function getStatus(args: CommonArgs): string { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const result = getIntentSkillList(args) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| return stringifyResponse( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| packageManager: result.packageManager, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| packageCount: result.packages.length, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| skillCount: result.skills.length, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| warningCount: result.warnings.length, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| conflictCount: result.conflicts.length, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| debug: args.debug ? result.debug : undefined, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| args.debug, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| export function createIntentMcpServer(): McpServer { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const server = new McpServer({ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| name: 'tanstack-intent', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| version: '0.0.1', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| server.registerTool( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'intent_search', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| title: 'Search Intent Skills', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| description: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'Search installed Intent skills. Use when a task involves a package and no matching skill is loaded.', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| inputSchema: { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| query: z.string().optional().describe('Words from the current task.'), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| packageName: z | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .string() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .optional() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .describe('Exact package name filter.'), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| limit: z | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .number() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .int() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .min(1) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .max(25) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .optional() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .describe('Maximum results. Defaults to 5.'), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| root: rootSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| global: globalSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| globalOnly: globalOnlySchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| exclude: excludeSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| debug: debugSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| (args) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return textResult(searchSkills(args)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return errorResult(error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| server.registerTool( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'intent_load', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| title: 'Load Intent Skill', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| description: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'Load one exact Intent skill id returned by intent_search. Use only when clearly relevant.', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| inputSchema: { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use: z | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .string() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .describe('Exact skill id, for example @scope/pkg#skill.'), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| root: rootSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| global: globalSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| globalOnly: globalOnlySchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| exclude: excludeSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| debug: debugSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| (args) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return textResult(loadSkill(args)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return errorResult(error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| server.registerTool( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'intent_status', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| title: 'Intent Status', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| description: 'Summarize discovered Intent packages and skills.', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| inputSchema: { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| root: rootSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| global: globalSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| globalOnly: globalOnlySchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| exclude: excludeSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| debug: debugSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| (args) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return textResult(getStatus(args)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return errorResult(error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| return server | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
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.
Make
test:intent-mcpcross-platform.Line 30 uses POSIX-style env var assignment, which won’t run on Windows shells.
Portable option
And add
cross-envtodevDependenciesif it isn’t already present.🤖 Prompt for AI Agents