Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions .changeset/sixty-regions-tickle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@sei-js/mcp-server": patch
---

Added main docs search tool
17 changes: 14 additions & 3 deletions docs/mcp-server/context.mdx
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
---
title: "Documentation Context"
description: "How the MCP server reads @sei-js documentation to provide intelligent assistance"
description: "How the MCP server provides intelligent assistance through comprehensive documentation search"
icon: "book-open"
---

The Sei MCP Server includes intelligent documentation search that reads the entire @sei-js ecosystem documentation to provide context-aware responses and code generation.
The Sei MCP Server includes intelligent documentation search that provides access to both the main Sei documentation and the entire @sei-js ecosystem documentation for context-aware responses and code generation.

## Documentation Access

The MCP server can search and reference documentation for all @sei-js packages:
The MCP server provides two search tools:

### Main Sei Documentation (`search_docs`)
Search the official Sei documentation for:
- General chain information and network details
- Ecosystem providers and integrations
- User onboarding guides and tutorials
- Bridging and cross-chain operations
- DeFi protocols and marketplace information

### Sei-JS Package Documentation (`search_sei_js_docs`)
Search and reference documentation for all @sei-js packages:

- **@sei-js/precompiles** - Precompile contract reference and integration examples
- **@sei-js/sei-global-wallet** - EIP-6963 wallet standard implementation
Expand Down
5 changes: 3 additions & 2 deletions docs/mcp-server/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ The Model Context Protocol is an open standard that connects AI systems with cus
- **Real-time blockchain data access** - Get current balances, transaction history, and network status directly from Sei
- **Secure by default** - Runs in read-only mode until you explicitly enable wallet tools
- **Full execution and write operations** - Deploy contracts, execute transactions, and interact with smart contracts (with wallet configured)
- **Up-to-date documentation access** - Search and understand the latest Sei documentation and guides
- **Up-to-date documentation access** - Search both main Sei docs and Sei-JS package documentation for comprehensive guidance
- **Specialized blockchain capabilities** - Access Sei-specific features like precompiles and native token operations

The Sei MCP Server leverages this protocol to bring comprehensive blockchain functionality directly to your AI assistant, enabling natural language interactions with the Sei network.
Expand All @@ -91,13 +91,14 @@ The Sei MCP Server leverages this protocol to bring comprehensive blockchain fun
</Accordion>

<Accordion title="Comprehensive Toolkit" icon="toolbox">
Access 16+ blockchain tools covering token management, NFT operations, smart contract interactions, and network monitoring.
Access 29 blockchain tools covering token management, NFT operations, smart contract interactions, network monitoring, and documentation search.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would now make this 20+ until you add one more

</Accordion>
</AccordionGroup>

## Example Queries

```text
"How do I bridge tokens to Sei from Ethereum?"
"How do I query staking my delegations using Viem?"
"Generate a wallet connection component using Sei Global Wallet"
"Help me set up a new Sei project with the latest patterns"
Expand Down
5 changes: 3 additions & 2 deletions docs/mcp-server/tools.mdx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
title: "Available Tools"
description: "Complete reference of 28 MCP tools for blockchain operations"
description: "Complete reference of 29 MCP tools for blockchain operations"
icon: "wrench"
---

The Sei MCP Server provides 28 tools for blockchain operations. **By default, wallet tools are disabled** and only read-only tools are available. [Enable wallet tools](/mcp-server/setup#wallet-connection) to unlock transaction capabilities.
The Sei MCP Server provides 29 tools for blockchain operations. **By default, wallet tools are disabled** and only read-only tools are available. [Enable wallet tools](/mcp-server/setup#wallet-connection) to unlock transaction capabilities.

<Note>
**Wallet Tools Disabled by Default**
Expand Down Expand Up @@ -113,6 +113,7 @@ These tools require [wallet configuration](/mcp-server/setup#wallet-connection)

| Tool | Purpose | Example Usage |
|------|---------|---------------|
| `search_docs` | Search the main Sei docs for general chain information, ecosystem providers, and user onboarding guides | "How do I bridge tokens to Sei?" |
| `search_sei_js_docs` | Search Sei-JS documentation | "How do I use precompiles with Viem?" |

## Enabling Wallet Tools
Expand Down
1 change: 1 addition & 0 deletions packages/mcp-server/src/docs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { createDocsSearchTool } from './server.js';
67 changes: 67 additions & 0 deletions packages/mcp-server/src/docs/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import type { SeiSearchResponse } from '../mintlify/types';

const DOCS_SEARCH_URL = 'https://docs.sei-apis.io/search';

export const createDocsSearchTool = async (server: McpServer) => {
server.tool(
'search_docs',
'Search the main Sei docs for general chain information, ecosystem providers, and user onboarding guides. Useful for all queries for up-to-date information about Sei.',
{
query: z.string()
},
async ({ query }) => {
try {
const results = await searchDocs(query);
const content = results.map((result) => {
const { title, content, link } = result;
const text = `Title: ${title}\nContent: ${content}\nLink: ${link}`;
return {
type: 'text' as const,
text
};
});
return {
content
};
} catch (error) {
return {
content: [
{
type: 'text',
text: `Error searching docs: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
);
};

const searchDocs = async (query: string): Promise<SeiSearchResponse[]> => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't necessarily a search - would call this fetchDocs or something else

const url = `${DOCS_SEARCH_URL}?q=${encodeURIComponent(query)}`;

try {
const response = await fetch(url);

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const data = await response.json() as SeiSearchResponse[];

if (!data || data.length === 0) {
throw new Error('No results found');
}

return data;
} catch (error) {
if (error instanceof Error) {
throw new Error(`Search failed: ${error.message}`);
}

throw error;
}
};
6 changes: 3 additions & 3 deletions packages/mcp-server/src/mintlify/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { TrieveSDK } from 'trieve-ts-sdk';
import { z } from 'zod';

import { DEFAULT_BASE_URL, SERVER_URL, SUBDOMAIN } from './config.js';
import type { MintlifySearchConfig, SeiJSSearchResult, TrieveResponse, TrieveSearchResult } from './types.js';
import type { MintlifySearchConfig, SeiSearchResponse, TrieveResponse, TrieveSearchResult } from './types.js';
import { formatErr, throwOnAxiosError } from './utils.js';

/**
Expand All @@ -28,7 +28,7 @@ const fetchMintlifyConfig = async (subdomain: string): Promise<MintlifySearchCon
/**
* Search Sei-JS documentation using Mintlify/Trieve API
*/
const searchSeiJSDocs = async (query: string, config: MintlifySearchConfig): Promise<SeiJSSearchResult[]> => {
const searchSeiJSDocs = async (query: string, config: MintlifySearchConfig): Promise<SeiSearchResponse[]> => {
const trieve = new TrieveSDK({
apiKey: config.trieveApiKey,
datasetId: config.trieveDatasetId,
Expand Down Expand Up @@ -65,7 +65,7 @@ export const createSeiJSDocsSearchTool = async (server: McpServer): Promise<void

server.tool(
'search_sei_js_docs',
'Search all @sei-js libraries documentation for blockchain development, EVM/Ethereum integration, global wallet connections, React next.js and vite boilerplates, ledger integration, and the Sei chain registry',
'Search all @sei-js libraries documentation for blockchain development, EVM/Ethereum integration, global wallet connections, React Next.js and Vite boilerplates, ledger integration, and the Sei chain registry. Useful for NodeJS based integrations with Sei.',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NodeJS-based

{
query: z.string()
},
Expand Down
2 changes: 1 addition & 1 deletion packages/mcp-server/src/mintlify/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export interface MintlifySearchConfig {
base_url?: string;
}

export interface SeiJSSearchResult {
export interface SeiSearchResponse {
title: string;
content: string;
link: string;
Expand Down
5 changes: 3 additions & 2 deletions packages/mcp-server/src/server/server.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { getSupportedNetworks } from '../core/chains.js';
import { registerEVMPrompts } from '../core/prompts.js';
import { registerEVMResources } from '../core/resources.js';
import { registerEVMTools } from '../core/tools.js';
import { createSeiJSDocsSearchTool } from '../mintlify/index.js';
import { createDocsSearchTool } from '../docs/index.js';

// Create and start the MCP server
async function startServer() {
Expand All @@ -20,7 +20,8 @@ async function startServer() {
registerEVMTools(server);
registerEVMPrompts(server);

// Register documentation search tool
// Register documentation search tools
await createDocsSearchTool(server);
await createSeiJSDocsSearchTool(server);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now, whats the diff between Docs and SeiJSDocs ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs come from a different source since the main docs don't use mintlify


// Log server information
Expand Down
25 changes: 25 additions & 0 deletions packages/mcp-server/src/tests/core/services/balance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,31 @@ describe('Balance Service', () => {
// Restore console.error
console.error = originalConsoleError;
});

test('should return false if there is a non-Error object thrown', async () => {
// Import mocked modules
const { readContract } = await import('../../../core/services/contracts.js');
const { utils } = await import('../../../core/services/utils.js');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we do anything about the relative imports?


// Configure mocks for this test
(readContract as jest.Mock).mockImplementation(() => {
throw 'String error message'; // Non-Error object
});
(utils.validateAddress as jest.Mock).mockImplementation((address) => address as `0x${string}`);

// Mock console.error to avoid cluttering test output
const originalConsoleError = console.error;
console.error = () => {};

// Call the function
const result = await isNFTOwner(VALID_TOKEN_ADDRESS, VALID_OWNER_ADDRESS, 1n);

// Verify results
expect(result).toBe(false);

// Restore console.error
console.error = originalConsoleError;
});
});

describe('getERC721Balance', () => {
Expand Down
Loading