Skip to content

Conversation

@bashandbone
Copy link
Contributor

Comprehensive Server Refactor

This branch refactors services within the server architecture to improve separation and maintability/testability, and enable use of mcp stdio transport protocol.

Background

CodeWeaver's FastMCP server was previously tightly coupled to core CodeWeaver services -- like indexing/chunking/embedding generation, and file change watching. This made it very difficult to run any core services without running all services. Additionally, CodeWeaver exposed several endpoints through the FastMCP server (using its FastMCP.custom_route() method), which further required the mcp server to always run when taking any action.

The bigger problem was this practically prevented use of the mcp stdio transport, because the stdio transport has several characteristics that make it unique: 1) clients create stdio servers and control their lifetimes, 2) All stdio sessions are fully isolated -- there's no shared state. The tight coupling of codeweaver, combined with the lack of shared state, meant potentially destructive and minimally resource intensive overlapping chunking/indexing and embedding operations per stdio session.

At the same time, today's MCP clients largely assume local clients will communicate using stdio, creating a barrier to adoption.

Key Changes

  • All FastMCP server construction was moved from the server package to a new package, codeweaver.mcp. It was further broken up into multiple modules there for clarity.
  • The previous codeweaver.middleware package was moved into the new mcp package as a subpackage. Corresponding with this change, the FastMCP Middleware type/class was aliased across the codebase as McpMiddleware. This helps clarify a continual source of confusion where Mcp middleware, which only applies to Mcp transports, is conflated with HTTP (i.e. Starlette) middleware.
  • The move to the mcp package and reduced role of the FastMCP server enabled a significant reduction in initialization complexity.
  • The server package was further refactored. I added management.py to define a new administrative Starlette app that directly exposes the previously proxied-through-fastmcp endpoints. This administrative server will be on port 9329 by default, whereas mcp defaults to the previous 9328.
  • Background indexing initialization was moved to server.background_services.py, a new modules, and logging setup was moved to server.logging.py.
  • There are now three distinct servers that CodeWeaver can run together and independently -- 1) a background services server for use as a continual running daemon, 2) The administrative/management server that exposes health and status endpoints, 3) The fastmcp http server for communicating with mcp clients. Each server has its own lifespan definition and management, brought together with asyncio.gather()
  • For clarity, the three health_ prefixed modules in codeweaver.server we moved to a new health subpackage in server and two lost their health prefixes -- becoming models.py, endpoint.py, and the other remaining health_service.py. I also refactored several overly large functions in this package.
  • The new mcp mechanism for stdio in codeweaver.mcp.server.py still requires an mcp http server. We wrap stdio servers in a tcp bridge before returning them to the requesting client.
  • main.py was substantially simplified to account for these new changes and because of the relative simplicity of creating three more focused servers vice one do-everything server.
  • A start and stop CLI command was added to support the new daemon functionality, and CLI commands were updated to match the new entrypoints
  • Tests were updated accordingly and are passing.

Backwards Compatibility

  • The only concern here was that there would be no change to how the average user connects to an mcp session -- if they were already accustomed to directly connecting to the http server for mcp; that doesn't change. The mcp http server stilld defaults to port 9328.
  • From an API perspective, CodeWeaver is still in early alpha and we've been abundantly clear in communications that we will change the API surface without notice while still in Alpha in order to provide a superior product.

bashandbone and others added 27 commits November 28, 2025 12:31
… stdio

- Added privacy utilities for telemetry to redact identifiable information for people who opt-in to additional telemetry.
…ddleware package to a subpackage within mcp package from root-level. Separated CodeWeaver management services from fastmcp initialization and instance creation. Not done with this refactor -- goal is separating business logic from the mcp transports, which will allow use of stdio transport (which needs to spawn multiple instances).
- Renamed AppState to CodeWeaverState throughout the codebase for clarity and consistency.
- Updated ToolRegistrationDict to enforce required fields and allow optional fields.
- Removed app_bindings.py as it was no longer needed; integrated functionality directly into management.py.
- Adjusted health endpoint and lifespan management to utilize the new CodeWeaverState.
- Updated tests to reflect changes in state management and tool registration.
- Enhanced documentation to clarify the purpose and constraints of CodeWeaverState.
- Increased cache duration for favicon to 72 hours.
Fix MCP server refactor: add ServerSetup, app_bindings, fix broken imports
…er.py into multiple modules and move health related modules to their own package in 'server.health'. Completed 'mcp' package and http server creation logic.
…issues from the refactors. 1. Created Two Separate Lifespan Functions (src/codeweaver/server/lifespan.py):

  - background_services_lifespan() - For daemon mode (no MCP server dependency)
  - http_lifespan() - For HTTP MCP server mode (composes background lifespan)
  - combined_lifespan - Backward compatibility alias

  2. Fixed Circular Import (src/codeweaver/server/management.py):
  - Moved CodeWeaverState import to TYPE_CHECKING block
  - Used quoted type annotation in __init__ method

  3. Fixed Dataclass PrivateAttr Syntax (src/codeweaver/server/server.py):
  - Updated telemetry, _mcp_http_server, and _tasks fields to use Annotated properly
…nagers; fixed incorrect signal handling in main.py
…s; clean up imports and logging configuration
…rage

Fix IndexingStats computed_field usage and CodeWeaverState fixture initialization
…dling in CodeWeaverSettings

- Updated AWSProviderSettings docstring to clarify the need for region-specific credentials for Bedrock models.
- Removed redundant phrases in AWS access key, secret access key, and session token descriptions.
- Added a new class method 'python_json_schema' to CodeWeaverSettings for better JSON validation schema retrieval.
- Modified 'json_schema' method to utilize the new 'python_json_schema' method and adjusted the schema path handling in 'save_schema'.
Copilot AI review requested due to automatic review settings December 1, 2025 15:03
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Sorry @bashandbone, your pull request is larger than the review limit of 150000 diff characters

@github-actions
Copy link
Contributor

github-actions bot commented Dec 1, 2025

👋 Hey @bashandbone,

Thanks for your contribution to codeweaver! 🧵

You need to agree to the CLA first... 🖊️

Before we can accept your contribution, you need to agree to our Contributor License Agreement (CLA).

To agree to the CLA, please comment:

I read the contributors license agreement and I agree to it.

Those exact words are important1, so please don't change them. 😉

You can read the full CLA here: Contributor License Agreement


@bashandbone has signed the CLA.


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

Footnotes

  1. Our bot needs those exact words to recognize that you agree to the CLA.

bashandbone and others added 20 commits December 1, 2025 15:45
Fixed bug where `_extracted_from__prepare_vectors_34()` (a refactoring artifact)
was called instead of the correct method `_prepare_sparse_vector_data()`.

This was causing sparse-only vector searches to fail with 0 results because
the method didn't exist, leading to errors during vector preparation.

Fixes #115

Co-authored-by: Adam Poulemanos <[email protected]>
- Change Qdrant health check endpoint from /health (404) to /healthz
- Update docker-compose.yml healthcheck to use correct /healthz endpoint
- Replace timeout-based waits with retry loops with max attempts
- Add better error messages and logging for debugging
- Keep continue-on-error for CodeWeaver (may fail without valid API keys)

Co-authored-by: bashandbone <[email protected]>
…env vars

- Use raw bash TCP/HTTP check in docker-compose since curl not in Qdrant image
- Extract health check URLs to environment variables for maintainability
- Check /healthz endpoint for proper HTTP 200 status

Co-authored-by: bashandbone <[email protected]>
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
…once'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Signed-off-by: Adam Poulemanos <[email protected]>
Copilot AI review requested due to automatic review settings December 1, 2025 20:55
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 115 out of 128 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Copilot AI review requested due to automatic review settings December 1, 2025 20:58
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@bashandbone
Copy link
Contributor Author

All tests pass. CLA check is faulty (expecting bot signatures). Everything looks solid. Time to merge!

@bashandbone bashandbone merged commit 5f9087a into main Dec 1, 2025
12 of 13 checks passed
@bashandbone bashandbone deleted the feat-background-services branch December 1, 2025 21:48
@github-actions github-actions bot locked and limited conversation to collaborators Dec 1, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants