Skip to main content
Glama

m9k_context

Read-onlyIdempotent

Retrieve a document chunk with neighboring chunks from the same session. Use after searching to understand the conversation flow.

Instructions

Get a chunk with surrounding context (adjacent chunks in the same session). Use after m9k_search to understand the conversation flow.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
chunkIdYesThe chunk ID to get context for
windowNoNumber of chunks before/after to include

Implementation Reference

  • Registration and handler for the m9k_context tool. Accepts chunkId and optional window parameter. Queries the conv_chunks table for the target chunk, then retrieves adjacent chunks in the same session to provide surrounding conversation context.
    server.registerTool(
      'm9k_context',
      {
        description:
          'Get a chunk with surrounding context (adjacent chunks in the same session). Use after m9k_search to understand the conversation flow.',
        inputSchema: {
          chunkId: z.string().describe('The chunk ID to get context for'),
          window: z
            .number()
            .int()
            .min(1)
            .max(10)
            .default(3)
            .describe('Number of chunks before/after to include'),
        },
        annotations: {
          readOnlyHint: true,
          destructiveHint: false,
          idempotentHint: true,
          openWorldHint: false,
        },
      },
      async ({ chunkId, window }) => {
        const target = ctx.db
          .prepare('SELECT session_id, idx FROM conv_chunks WHERE id = ? AND deleted_at IS NULL')
          .get(chunkId) as { session_id: string; idx: number } | undefined;
    
        if (!target) {
          return {
            content: [
              {
                type: 'text' as const,
                text: JSON.stringify({ error: 'Chunk not found', chunkId }),
              },
            ],
            isError: true,
          };
        }
    
        const minIdx = Math.max(0, target.idx - window);
        const maxIdx = target.idx + window;
    
        const rows = ctx.db
          .prepare(
            `SELECT id, session_id, idx, kind, user_content, assistant_content, hash, timestamp, token_count, tags, metadata_json
             FROM conv_chunks WHERE session_id = ? AND idx BETWEEN ? AND ? AND deleted_at IS NULL ORDER BY idx`,
          )
          .all(target.session_id, minIdx, maxIdx);
    
        return {
          content: [
            {
              type: 'text' as const,
              text: JSON.stringify({ target: chunkId, chunks: rows }),
            },
          ],
        };
      },
    );
  • Input schema for m9k_context: chunkId (string, required) and window (number, 1-10, default 3) defining how many chunks before/after to include.
    server.registerTool(
      'm9k_context',
      {
        description:
          'Get a chunk with surrounding context (adjacent chunks in the same session). Use after m9k_search to understand the conversation flow.',
        inputSchema: {
          chunkId: z.string().describe('The chunk ID to get context for'),
          window: z
            .number()
            .int()
            .min(1)
            .max(10)
            .default(3)
            .describe('Number of chunks before/after to include'),
        },
        annotations: {
          readOnlyHint: true,
          destructiveHint: false,
          idempotentHint: true,
          openWorldHint: false,
        },
  • Tool registration via server.registerTool('m9k_context', ...) with schema, annotations (readOnly, idempotent), and async handler. Exported by registerSearchTools function.
    server.registerTool(
      'm9k_context',
      {
        description:
          'Get a chunk with surrounding context (adjacent chunks in the same session). Use after m9k_search to understand the conversation flow.',
        inputSchema: {
          chunkId: z.string().describe('The chunk ID to get context for'),
          window: z
            .number()
            .int()
            .min(1)
            .max(10)
            .default(3)
            .describe('Number of chunks before/after to include'),
        },
        annotations: {
          readOnlyHint: true,
          destructiveHint: false,
          idempotentHint: true,
          openWorldHint: false,
        },
      },
      async ({ chunkId, window }) => {
        const target = ctx.db
          .prepare('SELECT session_id, idx FROM conv_chunks WHERE id = ? AND deleted_at IS NULL')
          .get(chunkId) as { session_id: string; idx: number } | undefined;
    
        if (!target) {
          return {
            content: [
              {
                type: 'text' as const,
                text: JSON.stringify({ error: 'Chunk not found', chunkId }),
              },
            ],
            isError: true,
          };
        }
    
        const minIdx = Math.max(0, target.idx - window);
        const maxIdx = target.idx + window;
    
        const rows = ctx.db
          .prepare(
            `SELECT id, session_id, idx, kind, user_content, assistant_content, hash, timestamp, token_count, tags, metadata_json
             FROM conv_chunks WHERE session_id = ? AND idx BETWEEN ? AND ? AND deleted_at IS NULL ORDER BY idx`,
          )
          .all(target.session_id, minIdx, maxIdx);
    
        return {
          content: [
            {
              type: 'text' as const,
              text: JSON.stringify({ target: chunkId, chunks: rows }),
            },
          ],
        };
      },
    );
  • Imports and setup for the search module: zod for schema validation, McpServer type, getStat for DB stats, search function, and ToolContext interface.
    /**
     * Progressive retrieval tools: m9k_search, m9k_context, m9k_full.
     */
    
    import { z } from 'zod';
    import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
    import { getStat } from '../db.js';
    import { search } from '../search.js';
    import type { ToolContext } from './context.js';
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, non-destructive, and idempotent behavior. Description adds useful context about returning adjacent chunks in the same session, which clarifies the tool's scope beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste: first sentence states purpose, second gives usage context. Every word is necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read tool with two parameters and explicit annotations, the description adequately defines purpose and usage. Minor gap: doesn't describe return structure, but acceptable given no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% (both chunkId and window have descriptions). The description does not add extra parameter details beyond the schema, meeting the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the verb 'Get' and the resource 'a chunk with surrounding context (adjacent chunks in the same session)', distinguishing it from sibling tools like m9k_search and m9k_full.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly suggests using after m9k_search to understand conversation flow, providing clear context but no explicit when-not-to-use or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

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/louis49/melchizedek'

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