@youdotcom-oss/mcp 1.3.3 → 1.3.4

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 CHANGED
@@ -13,6 +13,7 @@ A Model Context Protocol (MCP) server that provides web search, AI agent, and co
13
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
14
 
15
15
  **This guide (AGENTS.md) is for developers, contributors, and AI coding agents** who want to:
16
+
16
17
  - Set up a local development environment
17
18
  - Understand the codebase architecture
18
19
  - Contribute code or bug fixes
@@ -24,7 +25,7 @@ A Model Context Protocol (MCP) server that provides web search, AI agent, and co
24
25
  ## Tech Stack
25
26
 
26
27
  - **Runtime**: Bun >= 1.2.21 (not Node.js)
27
- - **Framework**: Model Context Protocol SDK v1.22.0
28
+ - **Framework**: Model Context Protocol SDK v1.24.0
28
29
  - **HTTP Server**: Hono v4.10.6 with @hono/mcp for HTTP transport (SSE protocol support)
29
30
  - **Validation**: Zod 3.25.76 for schema validation
30
31
  - **Testing**: Bun test (built-in test runner)
@@ -61,6 +62,7 @@ This project uses [Biome](https://biomejs.dev/) for automated code formatting an
61
62
  ### Manual Adherence Required
62
63
 
63
64
  **Arrow Functions**: Always use arrow functions for declarations (not enforced by Biome)
65
+
64
66
  ```ts
65
67
  // ✅ Preferred
66
68
  export const fetchData = async (params: Params) => { ... };
@@ -70,6 +72,7 @@ export async function fetchData(params: Params) { ... }
70
72
  ```
71
73
 
72
74
  **No Unused Exports**: All exports must be actively used (Biome detects unused variables/imports, but NOT unused exports)
75
+
73
76
  ```bash
74
77
  # Before adding exports, verify usage:
75
78
  grep -r "ExportName" src/
@@ -78,38 +81,45 @@ grep -r "ExportName" src/
78
81
  ### MCP-Specific Patterns
79
82
 
80
83
  **Schema Design**: Always use Zod for input/output validation
84
+
81
85
  ```ts
82
86
  export const MyToolInputSchema = z.object({
83
- query: z.string().min(1).describe('Search query'),
84
- limit: z.number().optional().describe('Max results'),
87
+ query: z.string().min(1).describe("Search query"),
88
+ limit: z.number().optional().describe("Max results"),
85
89
  });
86
90
  ```
87
91
 
88
92
  **Error Handling**: Always use try/catch with typed error handling
93
+
89
94
  ```ts
90
95
  try {
91
96
  const response = await apiCall();
92
97
  return formatResponse(response);
93
98
  } catch (err: unknown) {
94
99
  const errorMessage = err instanceof Error ? err.message : String(err);
95
- await logger({ level: 'error', data: `API call failed: ${errorMessage}` });
96
- return { content: [{ type: 'text', text: `Error: ${errorMessage}` }], isError: true };
100
+ await logger({ level: "error", data: `API call failed: ${errorMessage}` });
101
+ return {
102
+ content: [{ type: "text", text: `Error: ${errorMessage}` }],
103
+ isError: true,
104
+ };
97
105
  }
98
106
  ```
99
107
 
100
108
  **Logging**: Use `getLogger(mcp)` helper, never console.log
109
+
101
110
  ```ts
102
- import { getLogger } from '../shared/get-logger.ts';
111
+ import { getLogger } from "../shared/get-logger.ts";
103
112
 
104
113
  const logger = getLogger(mcp);
105
- await logger({ level: 'info', data: `Operation successful: ${result}` });
106
- await logger({ level: 'error', data: `Operation failed: ${errorMessage}` });
114
+ await logger({ level: "info", data: `Operation successful: ${result}` });
115
+ await logger({ level: "error", data: `Operation failed: ${errorMessage}` });
107
116
  ```
108
117
 
109
118
  **Response Format**: Return both `content` and `structuredContent`
119
+
110
120
  ```ts
111
121
  return {
112
- content: [{ type: 'text', text: formattedText }],
122
+ content: [{ type: "text", text: formattedText }],
113
123
  structuredContent: responseData,
114
124
  };
115
125
  ```
@@ -157,6 +167,7 @@ bun run format:package # Format package.json only
157
167
  ## Contributing
158
168
 
159
169
  For detailed contribution guidelines, including:
170
+
160
171
  - Bug reporting
161
172
  - Feature requests
162
173
  - Pull request workflow
@@ -170,6 +181,7 @@ See [CONTRIBUTING.md](./CONTRIBUTING.md)
170
181
  ### Tool Registration
171
182
 
172
183
  Use Zod schemas for tool parameter validation. See examples:
184
+
173
185
  - Search tool: `src/search/register-search-tool.ts:7-86`
174
186
  - Express tool: `src/express/register-express-tool.ts:7-66`
175
187
  - Contents tool: `src/contents/register-contents-tool.ts:7-89`
@@ -186,7 +198,6 @@ Use `getLogger(mcp)` helper, never console.log. See `src/shared/get-logger.ts:8-
186
198
 
187
199
  Include mailto links in error logs using `generateErrorReportLink()` helper (`src/shared/generate-error-report-link.ts:6-37`). This creates one-click error reporting with full diagnostic context.
188
200
 
189
-
190
201
  ## Testing
191
202
 
192
203
  ### Test Organization
@@ -196,6 +207,7 @@ Include mailto links in error logs using `generateErrorReportLink()` helper (`sr
196
207
  - **Coverage Target**: >80% for core utilities
197
208
 
198
209
  For test patterns, see:
210
+
199
211
  - Unit tests: `src/search/tests/search.utils.spec.ts`
200
212
  - Integration tests: `src/tests/tool.spec.ts`
201
213
 
@@ -204,22 +216,25 @@ For test patterns, see:
204
216
  **IMPORTANT: Avoid patterns that silently skip assertions** - they hide failures.
205
217
 
206
218
  ❌ **Early Returns** - Silently exits test, skips remaining assertions
219
+
207
220
  ```ts
208
221
  if (!item) return; // Bad: test passes even if item is undefined
209
222
  ```
210
223
 
211
224
  ❌ **Redundant Conditionals** - Asserts defined, then conditionally checks type
225
+
212
226
  ```ts
213
227
  expect(item?.markdown).toBeDefined();
214
228
  if (item?.markdown) {
215
- expect(typeof item.markdown).toBe('string'); // Redundant!
229
+ expect(typeof item.markdown).toBe("string"); // Redundant!
216
230
  }
217
231
  ```
218
232
 
219
233
  ✅ **Let tests fail naturally** - Use optional chaining and direct assertions:
234
+
220
235
  ```ts
221
236
  expect(item).toBeDefined();
222
- expect(item).toHaveProperty('url'); // Fails with clear error if undefined
237
+ expect(item).toHaveProperty("url"); // Fails with clear error if undefined
223
238
  ```
224
239
 
225
240
  ### Running Tests
@@ -243,6 +258,7 @@ Requires `YDC_API_KEY` environment variable for API tests.
243
258
  **Symptom**: Error message "YDC_API_KEY environment variable is required"
244
259
 
245
260
  **Solution**:
261
+
246
262
  ```bash
247
263
  # Set up .env file
248
264
  echo "export YDC_API_KEY=your-actual-api-key-here" > .env
@@ -260,6 +276,7 @@ echo $YDC_API_KEY
260
276
  **Symptom**: `bun run build` fails with TypeScript errors
261
277
 
262
278
  **Solution**:
279
+
263
280
  ```bash
264
281
  # Check TypeScript errors
265
282
  bun run check:types
@@ -277,6 +294,7 @@ bun run build
277
294
  **Symptom**: Tests fail with 429 (Too Many Requests) errors
278
295
 
279
296
  **Solution**:
297
+
280
298
  - Wait a few minutes before re-running tests
281
299
  - Run specific test suites instead of all tests at once
282
300
  - Use `bun test --bail` to stop after first failure
@@ -287,6 +305,7 @@ bun run build
287
305
  **Symptom**: Docker build fails with permission errors
288
306
 
289
307
  **Solution**:
308
+
290
309
  ```bash
291
310
  # Ensure Docker daemon is running
292
311
  docker info
@@ -303,6 +322,7 @@ groups $USER
303
322
  **Symptom**: Pre-commit hook fails or `bun run check` shows errors
304
323
 
305
324
  **Solution**:
325
+
306
326
  ```bash
307
327
  # Auto-fix most issues
308
328
  bun run check:write
@@ -324,6 +344,7 @@ bun run lint:fix
324
344
  **Symptom**: "Cannot find module" errors in TypeScript
325
345
 
326
346
  **Solution**:
347
+
327
348
  - Always use `.js` extensions in imports (even for `.ts` files)
328
349
  - Check that the file exists at the specified path
329
350
  - Use relative paths correctly (`./` for same directory, `../` for parent)
@@ -334,11 +355,13 @@ bun run lint:fix
334
355
  **Symptom**: MCP client can't connect to server
335
356
 
336
357
  **Solution for Stdio mode**:
358
+
337
359
  - Verify the path to `stdio.ts` or `stdio.js` is correct and absolute
338
360
  - Check that Bun is installed and in PATH
339
361
  - Test manually: `bun src/stdio.ts`
340
362
 
341
363
  **Solution for HTTP mode**:
364
+
342
365
  - Verify server is running: `curl http://localhost:4000/mcp-health`
343
366
  - Check port isn't in use: `lsof -i :4000` (macOS/Linux)
344
367
  - Verify Bearer token matches your API key
@@ -369,13 +392,13 @@ const validatedResponse = ResponseSchema.parse(jsonResponse);
369
392
 
370
393
  // Handle specific status codes
371
394
  if (response.status === 401) {
372
- throw new Error('Invalid or expired API key');
395
+ throw new Error("Invalid or expired API key");
373
396
  }
374
397
  if (response.status === 403) {
375
- throw new Error('API key lacks permissions for this endpoint');
398
+ throw new Error("API key lacks permissions for this endpoint");
376
399
  }
377
400
  if (response.status === 429) {
378
- throw new Error('Rate limit exceeded');
401
+ throw new Error("Rate limit exceeded");
379
402
  }
380
403
  ```
381
404
 
@@ -418,7 +441,7 @@ Content extraction from web pages
418
441
  graph TD
419
442
  Clients["MCP Clients
420
443
  (Claude Desktop, Claude Code, Custom Clients)"]
421
-
444
+
422
445
  Clients -->|"Stdio (Local)"| Stdio["src/stdio.ts
423
446
  - Process I/O
424
447
  - JSON-RPC"]
@@ -426,14 +449,14 @@ graph TD
426
449
  - /mcp
427
450
  - /mcp-health
428
451
  - Bearer Auth"]
429
-
452
+
430
453
  Stdio --> Server["src/get-mcp-server.ts
431
454
  MCP Server Factory
432
455
  - registerTool()
433
456
  - Tool Handlers
434
457
  - Logging"]
435
458
  HTTP --> Server
436
-
459
+
437
460
  Server --> Search["you-search
438
461
  - Validation
439
462
  - Query Build
@@ -446,7 +469,7 @@ graph TD
446
469
  - Validation
447
470
  - Multi-URL
448
471
  - Formatting"]
449
-
472
+
450
473
  Search -->|X-API-Key| APIs["You.com APIs
451
474
  - Search API (ydc-index.io)
452
475
  - Agent API (api.you.com)
@@ -458,6 +481,7 @@ graph TD
458
481
  ### Request Flow
459
482
 
460
483
  **Stdio Transport (Local Development)**:
484
+
461
485
  1. MCP Client sends JSON-RPC request via stdin
462
486
  2. `stdio.ts` receives and parses request
463
487
  3. Calls MCP Server with tool name + parameters
@@ -467,6 +491,7 @@ graph TD
467
491
  7. JSON-RPC response sent via stdout
468
492
 
469
493
  **HTTP Transport (Remote Deployment)**:
494
+
470
495
  1. MCP Client connects via SSE to `/mcp`
471
496
  2. Client sends tool request over SSE connection
472
497
  3. `http.ts` authenticates Bearer token
@@ -558,6 +583,7 @@ This section covers local development setup, self-hosting options, and productio
558
583
  ### Local development setup
559
584
 
560
585
  **Prerequisites:**
586
+
561
587
  - Bun >= 1.2.21 installed
562
588
  - You.com API key from [you.com/platform/api-keys](https://you.com/platform/api-keys)
563
589
 
@@ -583,6 +609,7 @@ bun start
583
609
  ```
584
610
 
585
611
  **Verify setup:**
612
+
586
613
  ```bash
587
614
  # Test STDIO mode
588
615
  echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | bun src/stdio.ts
@@ -613,7 +640,7 @@ curl http://localhost:4000/mcp-health
613
640
  **Docker Compose:**
614
641
 
615
642
  ```yaml
616
- version: '3.8'
643
+ version: "3.8"
617
644
  services:
618
645
  youdotcom-mcp:
619
646
  build: .
@@ -626,13 +653,13 @@ services:
626
653
 
627
654
  ### Deployment modes
628
655
 
629
- | Mode | Use Case | Transport | Command |
630
- |------|----------|-----------|---------|
631
- | **STDIO Dev** | Local development and testing | STDIO | `bun run dev` |
632
- | **STDIO Prod** | MCP client integration (local) | STDIO | `./bin/stdio.js` |
633
- | **HTTP Dev** | Local HTTP server testing | HTTP/SSE | `bun start` |
634
- | **HTTP Prod** | Remote clients, web apps, production | HTTP/SSE | `bun run build && bun bin/http` |
635
- | **Docker** | Containerized deployment | HTTP/SSE | `docker run ...` |
656
+ | Mode | Use Case | Transport | Command |
657
+ | -------------- | ------------------------------------ | --------- | ------------------------------- |
658
+ | **STDIO Dev** | Local development and testing | STDIO | `bun run dev` |
659
+ | **STDIO Prod** | MCP client integration (local) | STDIO | `./bin/stdio.js` |
660
+ | **HTTP Dev** | Local HTTP server testing | HTTP/SSE | `bun start` |
661
+ | **HTTP Prod** | Remote clients, web apps, production | HTTP/SSE | `bun run build && bun bin/http` |
662
+ | **Docker** | Containerized deployment | HTTP/SSE | `docker run ...` |
636
663
 
637
664
  ### Production deployment
638
665
 
@@ -662,10 +689,10 @@ PORT=4000 bun bin/http
662
689
 
663
690
  **Environment variables:**
664
691
 
665
- | Variable | Required | Default | Description |
666
- |----------|----------|---------|-------------|
667
- | `YDC_API_KEY` | Yes | - | You.com API key |
668
- | `PORT` | No | 4000 | HTTP server port (HTTP mode only) |
692
+ | Variable | Required | Default | Description |
693
+ | ------------- | -------- | ------- | --------------------------------- |
694
+ | `YDC_API_KEY` | Yes | - | You.com API key |
695
+ | `PORT` | No | 4000 | HTTP server port (HTTP mode only) |
669
696
 
670
697
  **Production considerations:**
671
698
 
@@ -693,6 +720,7 @@ bun test # Built-in test runner
693
720
  ```
694
721
 
695
722
  **Import Extensions** (enforced by Biome):
723
+
696
724
  - Local files: `.ts` extension
697
725
  - NPM packages: `.js` extension
698
726
  - JSON files: `.json` with import assertion