Skip to main content
Glama

@pulumi/mcp-server

Official
by pulumi
resource-search.test.ts6.56 kB
import { expect } from 'chai'; import { testClaudeCodeInvocation, ClaudeCodeTest } from './helpers.js'; import { resourceSearchCommands, setResourceSearchHandler } from '../src/insights/resource-search.js'; import { TestResourceSearchHandler } from './mocks/resource-search-handler.js'; describe('Resource Search Tool', function () { // Set up test handler before running tests before(() => { setResourceSearchHandler(new TestResourceSearchHandler()); }); describe('Direct Tool Tests (Unit Tests)', () => { const commands = resourceSearchCommands; describe('Untagged S3 buckets query', () => { it('should return acme-bucket for untagged S3 bucket query', async () => { const args = { query: 'type:aws:s3:Bucket AND -properties.tags:*', org: 'mock-org' }; const result = await commands['resource-search'].handler(args); const response = JSON.parse(result.content[0].text); // Test that we get the expected resource expect(response.results.resources).to.have.lengthOf(1); expect(response.results.resources[0].name).to.equal('acme-bucket'); }); }); describe('Default query handling', () => { it('should return default resource for non-S3 queries', async () => { const args = { query: 'package:aws type:lambda:Function', org: 'mock-org' }; const result = await commands['resource-search'].handler(args); const response = JSON.parse(result.content[0].text); // Test that we get the default resource expect(response.results.resources).to.have.lengthOf(1); expect(response.results.resources[0].name).to.equal('example-resource'); }); }); describe('Properties parameter handling', () => { it('should pass properties parameter to the search request', async () => { const args = { query: 'type:aws:s3:Bucket -properties.tags:*', properties: true, org: 'mock-org' }; const result = await commands['resource-search'].handler(args); const response = JSON.parse(result.content[0].text); // Test that we get a resource with properties expect(response.results.resources).to.have.lengthOf(1); expect(response.results.resources[0]).to.have.property('properties'); expect(response.results.resources[0].properties).to.be.an('object'); expect(response.results.resources[0].properties['region']).to.equal('us-west-2'); }); it('should handle properties parameter set to false', async () => { const args = { query: 'type:aws:s3:Bucket -properties.tags:*', properties: false, org: 'mock-org' }; const result = await commands['resource-search'].handler(args); const response = JSON.parse(result.content[0].text); // Test that we still get a resource (properties behavior is handled by API) expect(response.results.resources).to.have.lengthOf(1); expect(response.results.resources[0]).to.have.property('properties'); expect(JSON.stringify(response.results.resources[0].properties)).to.equal('{}'); }); it('should work without properties parameter (defaults to false)', async () => { const args = { query: 'type:aws:s3:Bucket -properties.tags:*', org: 'mock-org' }; const result = await commands['resource-search'].handler(args); const response = JSON.parse(result.content[0].text); // Test that we get a resource without explicitly setting properties expect(response.results.resources).to.have.lengthOf(1); expect(response.results.resources[0]).to.have.property('properties'); expect(JSON.stringify(response.results.resources[0].properties)).to.equal('{}'); }); }); }); describe('Claude Code SDK Integration Tests', function () { before(function () { if (!process.env.ANTHROPIC_API_KEY) { console.log('Skipping Claude Code SDK tests - no API key'); this.skip(); } }); describe('Natural Language to Resource Search Tool Selection', () => { const resourceSearchTestCases: ClaudeCodeTest[] = [ { query: 'Do I have any untagged S3 buckets?', expectedTool: 'pulumi-resource-search', description: 'Untagged S3 buckets query', contextType: 'pulumi' }, { query: 'List all deployed Lambda functions in my AWS infrastructure', expectedTool: 'pulumi-resource-search', description: 'Lambda functions query', contextType: 'pulumi' }, { query: 'Search for all EC2 instances in my production stack', expectedTool: 'pulumi-resource-search', description: 'Stack-based resource search query', contextType: 'pulumi' }, { query: 'Find all my RDS database instances across all stacks', expectedTool: 'pulumi-resource-search', description: 'Resource type search query', contextType: 'pulumi' } ]; resourceSearchTestCases.forEach((testCase) => { it(`should invoke resource-search tool for: "${testCase.description}"`, async function () { const toolsInvoked = await testClaudeCodeInvocation(testCase); // Verify that one of the invoked tools contains 'resource-search' const searchTool = toolsInvoked.find(tool => tool.includes('resource-search')); expect(searchTool, `Expected Claude Code to invoke a tool containing 'resource-search', but got: ${toolsInvoked.join(', ')}`).to.not.be.undefined; }); }); // Test that it should NOT invoke resource search for non-resource queries it('should NOT invoke resource-search for deployment queries', async function () { const testCase: ClaudeCodeTest = { query: 'Deploy this code to AWS', expectedTool: 'should-not-invoke-resource-search', description: 'AWS deployment request', contextType: 'pulumi' }; const toolsInvoked = await testClaudeCodeInvocation(testCase); // Should NOT invoke any tool containing 'resource-search' const searchTool = toolsInvoked.find(tool => tool.includes('resource-search')); expect(searchTool, `Claude incorrectly invoked a resource-search tool for deployment query. Got: ${searchTool}`).to.be.undefined; }); }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pulumi/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server