cd /news/developer-tools/one-mcp-server-two-ai-clients-wiring… · home topics developer-tools article
[ARTICLE · art-115153] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

One MCP Server, Two AI Clients: Wiring Actian VectorAI DB Into Claude and Cursor

A developer built a single MCP server in about 230 lines of Python to connect Actian VectorAI DB to both Claude and Cursor, demonstrating the protocol's promise of one server for any AI client. The server exposes six tools, handles embeddings locally, and was verified at the protocol layer, with the build published on GitHub.

read4 min views1 publishedAug 29, 2026

MCP promises one server, any AI client. I put that to the test by wiring Actian VectorAI DB up to Claude and Cursor with a single ~230-line Python file, and verified every claim about it at the protocol layer rather than taking anything on faith. Build's public on GitHub.

Every vector database has its own SDK. Every AI assistant has its own plugin format. Want Claude and Cursor to search your vector DB? That's normally two separate integrations, and a third tool next month makes three.

MCP removes that last part. It's an open protocol (originally from Anthropic) that lets any MCP-aware client (Claude Desktop, Claude Code, Cursor, whatever comes next) talk to the same server over a standard interface. Write the server once, every client gets it for free.

I built a small MCP server for Actian VectorAI DB, a portable, local-first vector database, to see if that promise holds up.

Six tools, ~230 lines of Python, one file:

Tool What it does
create_collection
Idempotently creates a 384-dim collection with a chosen distance metric
ingest_documents
Embeds text and upserts it, payload included
search
Embeds a query, returns top-k ranked hits
list_collections
Lists what's in the instance
get_collection_info
Point count, status, vector config
delete_collection
Deletes it, no confirmation step

The one design decision I'd defend to the death: the LLM never sees a vector. Every tool's input and output is plain strings, lists, and JSON dicts. The embedding happens inside the server process (sentence-transformers

running all-MiniLM-L6-v2

locally on CPU), so Claude or Cursor only ever reasons about text and decides when to call search

. LLMs are bad at generating 384 floating point numbers that mean something; they're good at calling a function with a query: str

argument.

Claude / Cursor  <--stdio JSON-RPC-->  server.py (FastMCP)  <--gRPC-->  Actian VectorAI DB
                                              │
                                     sentence-transformers
                                     (local, 384-dim embeddings)

It's a reference implementation, sized for a stage: a single global DB, running locally, built around a demo-sized dataset (six sentences, for this build).

Before locking in get_collection_info

, I checked what the response looked like against the installed actian-vectorai-client==1.0.2

, rather than coding purely off memory. Point count and status come back directly from that call, but not vector config (size/distance), so get_collection_info

pulls those two things from two places: gRPC for point count and status, and the REST API (port 6573) for vector config.

First, examples/demo.py

running straight against the live DB, plain Python calling the SDK directly: created a collection, ingested 6 FAQ sentences, searched, and got the right result back.

Then fastmcp.Client

, to drive server.py

over stdio JSON-RPC, the same path Claude and Cursor use. This is what confirmed get_collection_info

was pulling the right data from both the gRPC and REST calls, something that only became visible once data flowed through the full protocol path.

I also pointed the server at a dead port on purpose, just to confirm every tool failed with a plain-English message instead of a stack trace.

At the OS process level, I confirmed Cursor itself had spawned the MCP server subprocess after re, proof the config was picked up and working.

And finally, calling search

through that MCP connection and getting back {"text": "Submissions close Sunday at 9am."}

for "submission deadline for the hackathon," score 0.4227

.

Create a collection called notes

.

Collection 'notes' is ready (distance=cosine, dim=384).

Add these three facts to notes

: submissions close Sunday at 9am, first prize is $2,000, teams can have 2-5 members.

Inserted 3 document(s) into collection 'notes'.

What's the submission deadline?

[{"score": 0.4777, "payload": {"text": "Submissions close Sunday at 9am."}}]

, which the assistant turns into "the deadline is Sunday at 9am."

Then the point of the whole exercise: ask the same question in Cursor, switch windows, ask it again in Claude Desktop. Only the client-specific config block differs between the two.

I picked Actian VectorAI DB for being local-first, no cloud dependency, which mattered for a live demo on conference wifi. The Community Edition is free and was enough for this entire build. If you want to spin it up yourself, the Docker setup instructions cover both a plain docker run

and a docker-compose.yml

.

The bigger point, though: one small MCP server, any MCP client, natural language in, semantic search out, no vectors ever exposed to the model. If you've got an SDK and a thing worth calling from an LLM, this is basically the whole recipe. You can find the repo here.

── more in #developer-tools 4 stories · sorted by recency
── more on @actian vectorai db 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/one-mcp-server-two-a…] indexed:0 read:4min 2026-08-29 ·