Skip to content

Implement MCP server for GIQL documentation and operator reference#56

Merged
conradbzura merged 6 commits intomainfrom
55-mcp-server
Mar 3, 2026
Merged

Implement MCP server for GIQL documentation and operator reference#56
conradbzura merged 6 commits intomainfrom
55-mcp-server

Conversation

@conradbzura
Copy link
Copy Markdown
Collaborator

@conradbzura conradbzura commented Feb 25, 2026

Summary

Add a Model Context Protocol (MCP) server that exposes GIQL's operator reference, syntax guide, and full documentation as structured tools and resources. Any MCP-compatible client (Claude Desktop, Cursor, VS Code agents) can discover GIQL operators, look up syntax, and search docs on demand — eliminating hallucinated queries from LLMs unfamiliar with the dialect.

Closes #55

Proposed changes

New subpackage src/giql/mcp/

Add __init__.py and server.py implementing a FastMCP server with:

  • Resource giql://docs/{path} — serve cleaned RST documentation by path
  • Tool list_operators — return all GIQL operators with category, description, and syntax
  • Tool explain_operator — return full documentation for a named operator
  • Tool get_syntax_reference — return the complete syntax quick reference
  • Tool search_docs — full-text search across all documentation files

Operator metadata (signatures, parameters, examples, doc-file mappings) is embedded in the server module. RST content is read from the docs/ tree at runtime and cleaned for LLM consumption (directives stripped, cross-references simplified, code blocks converted to fenced markdown).

Doc path constants align with the actual repository layout (dialect/, transpilation/, recipes/).

Packaging changes in pyproject.toml

  • Add fastmcp as an optional dependency under an mcp extra
  • Add fastmcp to the dev dependency group
  • Add a giql-mcp console entry point

RST cleaning utility

clean_rst() converts Sphinx RST to plain text suitable for LLM context windows: remove toctree/contents directives, convert code-block to fenced blocks, simplify cross-references, and collapse excess blank lines.

MCP server README

Add src/giql/mcp/README.md documenting installation, running the server, MCP client configuration, interactive testing with FastMCP Inspector, and available tools and resources.

Test cases

Test Suite Test ID Given When Then Coverage Target
TestCleanRst CR-001 RST with .. toctree:: directive clean_rst() is called Directive is removed, body text preserved Directive stripping
TestCleanRst CR-002 RST with .. code-block:: sql directive clean_rst() is called Converts to fenced ```sql block Code block conversion
TestCleanRst CR-003 RST with :ref: and :doc: cross-references clean_rst() is called Cross-references replaced with plain text labels Cross-ref cleaning
TestFindDocsRoot FD-001 GIQL_DOCS env var set to existing directory find_docs_root() is called Returns that directory Env var strategy
TestFindDocsRoot FD-002 GIQL_DOCS set to nonexistent path find_docs_root() is called Does not return that path Invalid env var fallthrough
TestDocPaths DP-001 The DOC_PATHS dict All values are inspected Every value ends with .rst Path format validation
TestDocPaths DP-002 The DOC_PATHS dict Directory prefixes are inspected Only dialect, transpilation, recipes subdirectories used Directory prefix validation
TestDocPaths DP-003 The OPERATORS dict All doc_file values are inspected Every value starts with dialect/ Operator doc_file alignment
TestListOperators LO-001 Server with operator metadata list_operators() is called Returns list with all 9 operators Complete listing
TestListOperators LO-002 Server with operator metadata list_operators() is called Each entry has name, category, description, syntax keys Schema correctness
TestExplainOperator EO-001 Docs root with spatial-operators.rst containing INTERSECTS section explain_operator("INTERSECTS") is called full_documentation is populated with section content Doc extraction
TestExplainOperator EO-002 Valid operator name in lowercase explain_operator("distance") is called Resolves to DISTANCE without error Case-insensitive lookup
TestExplainOperator EO-003 Invalid operator name "BOGUS" explain_operator() is called Returns error dict with available operators list Unknown operator
TestExplainOperator EO-004 DOCS_ROOT is None explain_operator("MERGE") is called full_documentation is None No docs fallback
TestGetSyntaxReference SR-001 Server with embedded reference get_syntax_reference() is called Returns string containing all operator categories Embedded reference
TestGetDocumentation GD-001 Docs root with synthetic RST files get_documentation("quickstart") is called Returns cleaned content containing "Quickstart" Happy path
TestGetDocumentation GD-002 Docs root present get_documentation("nonexistent/page") is called Returns error listing available paths Unknown path
TestGetDocumentation GD-003 DOCS_ROOT is None get_documentation("quickstart") is called Returns "not accessible" message Missing docs
TestSearchDocs SD-001 Docs root with synthetic RST files search_docs("Quickstart") is called Returns results with path, title, and excerpt Keyword match
TestSearchDocs SD-002 Docs root with synthetic RST files search_docs("xyzzy_nonexistent_term_12345") is called Returns no-results message No match
TestSearchDocs SD-003 DOCS_ROOT is None search_docs("anything") is called Returns error about inaccessible docs Missing docs

Implementation plan

    • Add fastmcp optional dependency and giql-mcp entry point to pyproject.toml
    • Create src/giql/mcp/__init__.py
    • Implement src/giql/mcp/server.py with operator metadata, RST utilities, doc path constants aligned to docs/ layout, resource, tools, and entry point
    • Write tests in tests/test_mcp_server.py covering CR-001 through SD-003 (21 tests, 87% server module coverage)
    • Add src/giql/mcp/README.md with installation, configuration, testing, and API reference

@conradbzura conradbzura self-assigned this Feb 25, 2026
Add fastmcp as an optional "mcp" dependency and to the dev group.
Register giql-mcp console script entry point for the MCP server.
Expose GIQL operator reference, syntax guide, and documentation
through the Model Context Protocol so AI assistants can query
structured information instead of hallucinating GIQL syntax.

Tools: list_operators, explain_operator, get_syntax_reference,
search_docs. Resource: giql://docs/{path} for full doc pages.

Closes #55
Cover clean_rst, find_docs_root, DOC_PATHS validation, list_operators,
explain_operator, get_syntax_reference, get_documentation, and
search_docs across 7 test classes and 21 test methods.
The MCP server tests require fastmcp, which is only installed via the
optional mcp extra. Update pip install to use ".[mcp]" so CI picks up
the dependency.
@conradbzura conradbzura marked this pull request as ready for review February 26, 2026 14:40
Covers installation, running the server, client configuration,
interactive testing with FastMCP Inspector, and a summary of
available tools and resources.
@conradbzura conradbzura merged commit 8718df1 into main Mar 3, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement an MCP server for GIQL documentation and operator reference

1 participant