@youdotcom-oss/mcp 1.2.3 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md ADDED
@@ -0,0 +1,594 @@
1
+ ---
2
+ description: Development guidelines for You.com MCP Server using Bun runtime.
3
+ globs: "*.ts, *.tsx, *.js, *.jsx, package.json"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # You.com MCP Server Development Guide
8
+
9
+ A Model Context Protocol (MCP) server that provides web search, AI agent, and content extraction capabilities through You.com's APIs.
10
+
11
+ ---
12
+
13
+ > **Note for end users**: If you want to use this MCP server (not develop or contribute), see [README.md](./README.md) for setup instructions, getting started guides, and usage examples.
14
+
15
+ **This guide (AGENTS.md) is for developers, contributors, and AI coding agents** who want to:
16
+ - Set up a local development environment
17
+ - Understand the codebase architecture
18
+ - Contribute code or bug fixes
19
+ - Run tests and quality checks
20
+ - Review pull requests
21
+
22
+ ---
23
+
24
+ ## Tech Stack
25
+
26
+ - **Runtime**: Bun >= 1.2.21 (not Node.js)
27
+ - **Framework**: Model Context Protocol SDK v1.22.0
28
+ - **HTTP Server**: Hono v4.10.6 with @hono/mcp for HTTP transport (SSE protocol support)
29
+ - **Validation**: Zod 3.25.76 for schema validation
30
+ - **Testing**: Bun test (built-in test runner)
31
+ - **Code Quality**: Biome 2.3.6 (linter + formatter)
32
+ - **Type Checking**: TypeScript 5.9.3
33
+ - **Git Hooks**: lint-staged 16.2.7
34
+
35
+ ## Quick Start
36
+
37
+ ### Setup Environment
38
+
39
+ ```bash
40
+ echo "export YDC_API_KEY=your-actual-api-key-here" > .env
41
+ source .env
42
+ ```
43
+
44
+ ### Development Commands
45
+
46
+ ```bash
47
+ bun install # Install dependencies
48
+ bun run dev # Start stdio server
49
+ bun start # Start HTTP server on port 4000
50
+ bun test # Run tests
51
+ bun run check # Run all checks (biome + types + package format)
52
+ bun run check:write # Auto-fix all issues
53
+ ```
54
+
55
+ ## Code Style
56
+
57
+ This project uses [Biome](https://biomejs.dev/) for automated code formatting and linting. Most style rules are enforced automatically via git hooks (see `biome.json:55`).
58
+
59
+ ### Manual Adherence Required
60
+
61
+ **Arrow Functions**: Always use arrow functions for declarations (not enforced by Biome)
62
+ ```ts
63
+ // ✅ Preferred
64
+ export const fetchData = async (params: Params) => { ... };
65
+
66
+ // ❌ Avoid
67
+ export async function fetchData(params: Params) { ... }
68
+ ```
69
+
70
+ **No Unused Exports**: All exports must be actively used (Biome detects unused variables/imports, but NOT unused exports)
71
+ ```bash
72
+ # Before adding exports, verify usage:
73
+ grep -r "ExportName" src/
74
+ ```
75
+
76
+ ### MCP-Specific Patterns
77
+
78
+ **Schema Design**: Always use Zod for input/output validation
79
+ ```ts
80
+ export const MyToolInputSchema = z.object({
81
+ query: z.string().min(1).describe('Search query'),
82
+ limit: z.number().optional().describe('Max results'),
83
+ });
84
+ ```
85
+
86
+ **Error Handling**: Always use try/catch with typed error handling
87
+ ```ts
88
+ try {
89
+ const response = await apiCall();
90
+ return formatResponse(response);
91
+ } catch (err: unknown) {
92
+ const errorMessage = err instanceof Error ? err.message : String(err);
93
+ await logger({ level: 'error', data: `API call failed: ${errorMessage}` });
94
+ return { content: [{ type: 'text', text: `Error: ${errorMessage}` }], isError: true };
95
+ }
96
+ ```
97
+
98
+ **Logging**: Use `getLogger(mcp)` helper, never console.log
99
+ ```ts
100
+ const logger = getLogger(mcp);
101
+ await logger({ level: 'info', data: `Operation successful: ${result}` });
102
+ await logger({ level: 'error', data: `Operation failed: ${errorMessage}` });
103
+ ```
104
+
105
+ **Response Format**: Return both `content` and `structuredContent`
106
+ ```ts
107
+ return {
108
+ content: [{ type: 'text', text: formattedText }],
109
+ structuredContent: responseData,
110
+ };
111
+ ```
112
+
113
+ ## Development Workflow
114
+
115
+ ### Git Hooks
116
+
117
+ Git hooks are automatically configured after `bun install`:
118
+
119
+ - **Pre-commit**: Runs Biome check and format-package on staged files
120
+ - **Setup**: `bun run prepare` (runs automatically with install)
121
+ - Git hooks enforce code quality standards and should never be bypassed
122
+
123
+ ### MCP Inspector
124
+
125
+ Test and debug MCP tools interactively:
126
+
127
+ ```bash
128
+ bun run inspect # Automatically loads .env variables
129
+ ```
130
+
131
+ - Opens interactive UI to test MCP tools
132
+ - Requires `YDC_API_KEY` in `.env` file
133
+ - See [MCP Inspector docs](https://modelcontextprotocol.io/docs/tools/inspector)
134
+
135
+ ### Code Quality Commands
136
+
137
+ ```bash
138
+ # Check everything (CI command)
139
+ bun run check # Runs biome + types + package format
140
+
141
+ # Individual checks
142
+ bun run check:biome # Lint and format check
143
+ bun run check:types # TypeScript type check
144
+ bun run check:package # package.json format check
145
+
146
+ # Auto-fix
147
+ bun run check:write # Fix all auto-fixable issues
148
+ bun run lint:fix # Fix lint issues only
149
+ bun run format # Format code only
150
+ bun run format:package # Format package.json only
151
+ ```
152
+
153
+ ## Contributing
154
+
155
+ For detailed contribution guidelines, including:
156
+ - Bug reporting
157
+ - Feature requests
158
+ - Pull request workflow
159
+ - Commit message conventions (Conventional Commits)
160
+ - Code review process
161
+
162
+ See [CONTRIBUTING.md](./CONTRIBUTING.md)
163
+
164
+ ## MCP Server Patterns
165
+
166
+ ### Tool Registration
167
+
168
+ Use Zod schemas for tool parameter validation. See examples:
169
+ - Search tool: `src/search/register-search-tool.ts:7-47`
170
+ - Express tool: `src/express/register-express-tool.ts:7-35`
171
+ - Contents tool: `src/contents/register-contents-tool.ts:7-45`
172
+
173
+ ### Error Handling
174
+
175
+ Always use try/catch with typed error handling (`err: unknown`). See `src/search/search.utils.ts:90-105` for standard pattern.
176
+
177
+ ### Logging
178
+
179
+ Use `getLogger(mcp)` helper, never console.log. See `src/shared/shared.utils.ts:35-40` for implementation.
180
+
181
+ ### Error Reporting
182
+
183
+ Include mailto links in error logs using `generateErrorReportLink()` helper (`src/shared/shared.utils.ts:75-100`). This creates one-click error reporting with full diagnostic context.
184
+
185
+
186
+ ## Testing
187
+
188
+ ### Test Organization
189
+
190
+ - **Unit Tests**: `src/*/tests/*.spec.ts` - Test individual utilities
191
+ - **Integration Tests**: `src/tests/*.spec.ts` - Test MCP tools end-to-end
192
+ - **Coverage Target**: >80% for core utilities
193
+
194
+ For test patterns, see:
195
+ - Unit tests: `src/search/tests/search.utils.spec.ts`
196
+ - Integration tests: `src/tests/tool.spec.ts`
197
+
198
+ ### Test Assertion Anti-Patterns
199
+
200
+ **IMPORTANT: Avoid patterns that silently skip assertions** - they hide failures.
201
+
202
+ ❌ **Early Returns** - Silently exits test, skips remaining assertions
203
+ ```ts
204
+ if (!item) return; // Bad: test passes even if item is undefined
205
+ ```
206
+
207
+ ❌ **Redundant Conditionals** - Asserts defined, then conditionally checks type
208
+ ```ts
209
+ expect(item?.markdown).toBeDefined();
210
+ if (item?.markdown) {
211
+ expect(typeof item.markdown).toBe('string'); // Redundant!
212
+ }
213
+ ```
214
+
215
+ ✅ **Let tests fail naturally** - Use optional chaining and direct assertions:
216
+ ```ts
217
+ expect(item).toBeDefined();
218
+ expect(item).toHaveProperty('url'); // Fails with clear error if undefined
219
+ ```
220
+
221
+ ### Running Tests
222
+
223
+ ```bash
224
+ bun test # All tests
225
+ bun test --coverage # With coverage report
226
+ bun test src/search/tests/ # Specific directory
227
+ ```
228
+
229
+ Requires `YDC_API_KEY` environment variable for API tests.
230
+
231
+ ## Troubleshooting
232
+
233
+ ### Common Issues
234
+
235
+ #### YDC_API_KEY not found
236
+
237
+ **Symptom**: Error message "YDC_API_KEY environment variable is required"
238
+
239
+ **Solution**:
240
+ ```bash
241
+ # Set up .env file
242
+ echo "export YDC_API_KEY=your-actual-api-key-here" > .env
243
+ source .env
244
+
245
+ # Or export directly
246
+ export YDC_API_KEY="your-actual-api-key-here"
247
+
248
+ # Verify it's set
249
+ echo $YDC_API_KEY
250
+ ```
251
+
252
+ #### Build Failures
253
+
254
+ **Symptom**: `bun run build` fails with TypeScript errors
255
+
256
+ **Solution**:
257
+ ```bash
258
+ # Check TypeScript errors
259
+ bun run check:types
260
+
261
+ # Fix code quality issues
262
+ bun run check:write
263
+
264
+ # Clean and rebuild
265
+ rm -rf bin/
266
+ bun run build
267
+ ```
268
+
269
+ #### Test Failures with API Rate Limits
270
+
271
+ **Symptom**: Tests fail with 429 (Too Many Requests) errors
272
+
273
+ **Solution**:
274
+ - Wait a few minutes before re-running tests
275
+ - Run specific test suites instead of all tests at once
276
+ - Use `bun test --bail` to stop after first failure
277
+ - Check your API key rate limits at [api.you.com](https://api.you.com)
278
+
279
+ #### Docker Permission Issues
280
+
281
+ **Symptom**: Docker build fails with permission errors
282
+
283
+ **Solution**:
284
+ ```bash
285
+ # Ensure Docker daemon is running
286
+ docker info
287
+
288
+ # Build with sudo if needed (Linux)
289
+ sudo docker build -t youdotcom-mcp-server .
290
+
291
+ # Check Docker group membership (Linux)
292
+ groups $USER
293
+ ```
294
+
295
+ #### Biome/TypeScript Errors
296
+
297
+ **Symptom**: Pre-commit hook fails or `bun run check` shows errors
298
+
299
+ **Solution**:
300
+ ```bash
301
+ # Auto-fix most issues
302
+ bun run check:write
303
+
304
+ # Check specific issues
305
+ bun run check:biome # Linting and formatting
306
+ bun run check:types # TypeScript type errors
307
+ bun run check:package # package.json formatting
308
+
309
+ # Format code manually
310
+ bun run format
311
+
312
+ # Fix lint issues manually
313
+ bun run lint:fix
314
+ ```
315
+
316
+ #### Import Resolution Errors
317
+
318
+ **Symptom**: "Cannot find module" errors in TypeScript
319
+
320
+ **Solution**:
321
+ - Always use `.js` extensions in imports (even for `.ts` files)
322
+ - Check that the file exists at the specified path
323
+ - Use relative paths correctly (`./` for same directory, `../` for parent)
324
+ - Example: `import { foo } from './utils.js'` (not `./utils`)
325
+
326
+ #### MCP Client Connection Issues
327
+
328
+ **Symptom**: MCP client can't connect to server
329
+
330
+ **Solution for Stdio mode**:
331
+ - Verify the path to `stdio.ts` or `stdio.js` is correct and absolute
332
+ - Check that Bun is installed and in PATH
333
+ - Test manually: `bun src/stdio.ts`
334
+
335
+ **Solution for HTTP mode**:
336
+ - Verify server is running: `curl http://localhost:4000/mcp-health`
337
+ - Check port isn't in use: `lsof -i :4000` (macOS/Linux)
338
+ - Verify Bearer token matches your API key
339
+ - Check firewall settings
340
+
341
+ ## API Integration
342
+
343
+ ### You.com API Key
344
+
345
+ This server uses a single `YDC_API_KEY` for all APIs, but they use different authentication methods:
346
+
347
+ - **Search API** (`you-search`): Uses `X-API-Key` header
348
+ - **Contents API** (`you-contents`): Uses `X-API-Key` header
349
+ - **Agent API** (`you-express`): Uses `Authorization: Bearer` header
350
+
351
+ **Important**: If you receive 401 Unauthorized errors when using the `you-express` tool, ensure your API key has permissions for agent endpoints.
352
+
353
+ ### API Response Validation
354
+
355
+ Always validate API responses and handle errors:
356
+
357
+ ```ts
358
+ // Check for error field even with 200 status
359
+ checkResponseForErrors(jsonResponse);
360
+
361
+ // Validate with Zod
362
+ const validatedResponse = ResponseSchema.parse(jsonResponse);
363
+
364
+ // Handle specific status codes
365
+ if (response.status === 401) {
366
+ throw new Error('Invalid or expired API key');
367
+ }
368
+ if (response.status === 403) {
369
+ throw new Error('API key lacks permissions for this endpoint');
370
+ }
371
+ if (response.status === 429) {
372
+ throw new Error('Rate limit exceeded');
373
+ }
374
+ ```
375
+
376
+ ## Available MCP Tools
377
+
378
+ ### 1. `you-search`
379
+
380
+ Web and news search using You.com Search API
381
+
382
+ - Returns web results with snippets and news articles
383
+ - Supports filters: freshness, country, safesearch, file types
384
+ - Authentication: `X-API-Key` header
385
+
386
+ ### 2. `you-express`
387
+
388
+ Fast AI responses with optional web search
389
+
390
+ - Best for straightforward queries
391
+ - Fast responses with real-time web information
392
+ - Returns AI-synthesized answer + optional web search results
393
+ - Uses non-streaming JSON responses (`stream: false`)
394
+ - Authentication: `Authorization: Bearer` header
395
+
396
+ ### 3. `you-contents`
397
+
398
+ Content extraction from web pages
399
+
400
+ - Extracts full page content in markdown or HTML format
401
+ - Processes multiple URLs in a single API request
402
+ - Returns both text and structured content formats
403
+ - Markdown recommended for text extraction
404
+ - HTML recommended for layout preservation
405
+ - Authentication: `X-API-Key` header
406
+
407
+ ## Architecture
408
+
409
+ ### System Overview
410
+
411
+ ```
412
+ ┌─────────────────────────────────────────────────────────────────┐
413
+ │ MCP Clients │
414
+ │ (Claude Desktop, Claude Code, Custom Clients) │
415
+ └────────────────┬──────────────────────┬─────────────────────────┘
416
+ │ │
417
+ │ Stdio │ HTTP/SSE
418
+ │ (Local) │ (Remote)
419
+ ▼ ▼
420
+ ┌────────────────┐ ┌─────────────────┐
421
+ │ src/stdio.ts │ │ src/http.ts │
422
+ │ │ │ (Hono + SSE) │
423
+ │ - Process I/O │ │ - /mcp │
424
+ │ - JSON-RPC │ │ - /mcp-health │
425
+ └────────┬───────┘ │ - Bearer Auth │
426
+ │ └────────┬─────────┘
427
+ │ │
428
+ └──────────┬──────────┘
429
+
430
+ ┌────────────────────────┐
431
+ │ src/get-mcp-server.ts │
432
+ │ MCP Server Factory │
433
+ │ │
434
+ │ - registerTool() │
435
+ │ - Tool Handlers │
436
+ │ - Logging │
437
+ └────────┬───────────────┘
438
+
439
+ ┌────────────────┼────────────────┐
440
+ │ │ │
441
+ ▼ ▼ ▼
442
+ ┌───────────────┐ ┌──────────────┐ ┌──────────────┐
443
+ │ you-search │ │ you-express │ │ you-contents │
444
+ │ │ │ │ │ │
445
+ │ - Validation │ │ - Validation │ │ - Validation │
446
+ │ - Query Build │ │ - Transform │ │ - Multi-URL │
447
+ │ - Formatting │ │ - Formatting │ │ - Formatting │
448
+ └──────┬────────┘ └──────┬───────┘ └──────┬───────┘
449
+ │ │ │
450
+ │ X-API-Key │ Bearer │ X-API-Key
451
+ ▼ ▼ ▼
452
+ ┌────────────────────────────────────────────────────┐
453
+ │ You.com APIs │
454
+ │ │
455
+ │ - Search API - Agent API - Contents API │
456
+ │ (ydc-index.io) (api.you.com) (ydc-index.io) │
457
+ └────────────────────────────────────────────────────┘
458
+ ```
459
+
460
+ ### Request Flow
461
+
462
+ **Stdio Transport (Local Development)**:
463
+ 1. MCP Client sends JSON-RPC request via stdin
464
+ 2. `stdio.ts` receives and parses request
465
+ 3. Calls MCP Server with tool name + parameters
466
+ 4. MCP Server validates input with Zod schemas
467
+ 5. Tool handler calls You.com API
468
+ 6. Response formatted for MCP
469
+ 7. JSON-RPC response sent via stdout
470
+
471
+ **HTTP Transport (Remote Deployment)**:
472
+ 1. MCP Client connects via SSE to `/mcp`
473
+ 2. Client sends tool request over SSE connection
474
+ 3. `http.ts` authenticates Bearer token
475
+ 4. Calls MCP Server with tool name + parameters
476
+ 5. MCP Server validates input with Zod schemas
477
+ 6. Tool handler calls You.com API
478
+ 7. Response formatted for MCP
479
+ 8. SSE event sent back to client
480
+
481
+ ### Core Server Files
482
+
483
+ - `src/stdio.ts` - Stdio transport entry point (used by `bun run dev`)
484
+ - `src/http.ts` - HTTP transport with Bearer token auth (Hono app)
485
+ - `/mcp` - Main MCP endpoint (SSE streaming)
486
+ - `/mcp-health` - Health check endpoint
487
+ - Bearer token authentication via `Authorization` header
488
+ - `Content-Encoding: identity` header handling for compatibility
489
+ - `src/get-mcp-server.ts` - MCP server factory function
490
+
491
+ ### Search Tool (`you-search`)
492
+
493
+ - `src/search/register-search-tool.ts` - Tool registration with validation
494
+ - `src/search/search.schemas.ts` - Zod schemas for validation
495
+ - `src/search/search.utils.ts` - API calls, query building, formatting
496
+ - `src/search/tests/search.utils.spec.ts` - Unit tests
497
+
498
+ ### Express Agent Tool (`you-express`)
499
+
500
+ - `src/express/register-express-tool.ts` - Tool registration and request handling
501
+ - `src/express/express.schemas.ts` - Dual schema architecture
502
+ - API response validation (ExpressAgentApiResponseSchema)
503
+ - Token-efficient MCP output (ExpressAgentMcpResponseSchema)
504
+ - API validates full You.com response
505
+ - MCP output returns only essential fields
506
+ - `src/express/express.utils.ts` - API calls and response transformation
507
+ - `callExpressAgent()` - Calls You.com Express API (`stream: false`)
508
+ - Transforms API response to MCP format
509
+ - `formatExpressAgentResponse()` - Formats MCP response
510
+ - `agentThrowOnFailedStatus()` - Handles API errors
511
+ - `src/express/tests/express.utils.spec.ts` - Unit tests
512
+
513
+ ### Contents Tool (`you-contents`)
514
+
515
+ - `src/contents/register-contents-tool.ts` - Tool registration
516
+ - Calls `fetchContents()` with all URLs in single request
517
+ - Formats response for text and structured output
518
+ - Comprehensive error handling (401, 403, 429, 5xx)
519
+ - `src/contents/contents.schemas.ts` - Zod schemas
520
+ - `ContentsQuerySchema` - Input validation
521
+ - `ContentsApiResponseSchema` - API response validation
522
+ - `ContentsStructuredContentSchema` - MCP output format
523
+ - `src/contents/contents.utils.ts` - API calls and formatting
524
+ - `fetchContents()` - Single API call with all URLs
525
+ - Uses `X-API-Key` header
526
+ - Validates response schema
527
+ - `formatContentsResponse()` - Formats for MCP output
528
+ - `src/contents/tests/contents.utils.spec.ts` - Unit tests
529
+
530
+ ### Shared Utilities
531
+
532
+ - `src/shared/shared.utils.ts` - Cross-tool utilities
533
+ - `useGetClientVersion(mcp)` - Returns a `getUserAgent` function that creates User-Agent strings with MCP client version info
534
+ - `getLogger(mcp)` - Returns a logging function for MCP server notifications
535
+ - `checkResponseForErrors()` - Validates API responses for error fields
536
+ - `generateErrorReportLink()` - Creates mailto links for error reporting
537
+
538
+ ### Integration Tests
539
+
540
+ - `src/tests/http.spec.ts` - HTTP server endpoint tests
541
+ - `src/tests/tool.spec.ts` - End-to-end MCP tool tests
542
+
543
+ ## Deployment
544
+
545
+ ### Quick Start
546
+
547
+ ```bash
548
+ # Local development
549
+ git clone <repository-url>
550
+ cd you-mcp-server
551
+ bun install
552
+ echo "export YDC_API_KEY=your-key" > .env
553
+ source .env
554
+ bun run dev # Stdio mode
555
+
556
+ # HTTP server
557
+ bun start # Port 4000
558
+
559
+ # Docker
560
+ docker build -t youdotcom-mcp-server .
561
+ docker run -d -p 4000:4000 youdotcom-mcp-server
562
+ ```
563
+
564
+ ### Deployment Modes
565
+
566
+ | Mode | Use Case | Command |
567
+ |------|----------|---------|
568
+ | **Stdio Dev** | Local development | `bun run dev` |
569
+ | **Stdio Prod** | MCP client integration | `./bin/stdio.js` |
570
+ | **HTTP** | Web apps, remote clients | `bun start` |
571
+ | **Docker** | Containerized deployment | `docker run ...` |
572
+
573
+ For detailed deployment instructions, Docker configuration, and MCP client setup, see README.md.
574
+
575
+ For complete API reference documentation including parameters, response formats, and examples, see [API.md](./docs/API.md).
576
+
577
+ ## Bun Runtime
578
+
579
+ This project uses Bun (>= 1.2.21) instead of Node.js:
580
+
581
+ ```bash
582
+ bun <file> # Run TypeScript directly
583
+ bun install # Install dependencies
584
+ bun test # Built-in test runner
585
+ ```
586
+
587
+ **Import Extensions** (enforced by Biome):
588
+ - Local files: `.ts` extension
589
+ - NPM packages: `.js` extension
590
+ - JSON files: `.json` with import assertion
591
+
592
+ See `src/contents/register-contents-tool.ts:1-5` for import examples.
593
+
594
+ **Build**: See `scripts/build.ts` for Bun.build configuration.