Your AI Coding Assistant Shouldn't Be Your Company's Knowledge Layer
Summary
Why does every AI coding assistant rediscover how your company works? A platform-engineering build guide for financial services on Context as a Service — enterprise context plane, MCP gateway, and organizational truth plus local branch context for Cursor, Copilot, and Claude Code.
Short answer: If you run a wealth or asset management engineering org, do not let Cursor, Copilot, and Claude Code each rebuild their own picture of your portfolio platform. Build a company-owned context plane — a derived, permission-aware index of merged code, runbooks, ADRs, and engineering standards — and expose it through a context gateway (typically an MCP server) that every approved agent consumes. Combine that with local working context for unmerged branch changes.
That platform capability is what I call Context as a Service (CaaS): organizational truth maintained once, consumed by any approved agent — plus the developer's current branch at query time.
This is a design and build guide for platform engineers in financial services. For retrieval foundations, see Embeddings and Vector Databases. For exposing the gateway to agents, see Model Context Protocol Tools, Resources, and Prompts and Building Finance MCP Servers.
Why does every AI assistant rediscover how your company works?
Even if your firm standardizes on one IDE, the same tax shows up everywhere:
- Each repo gets indexed — often separately per tool
- Each developer rebuilds context in chat
- Each agent tries to infer architecture patterns, coding standards, service relationships, and business rules from scratch
Cursor indexes locally. Copilot indexes GitHub's view of `main`. Claude Code greps the workspace. None of them share a canonical, auditable view of organizational truth.
What if the company maintained that understanding once?
Code + Docs + Standards + Architecture
↓
Enterprise Context Plane
↓
MCP / Context Gateway
↓
AI Coding Assistant
+
Developer's local branch
=
Organizational truth + Current workThe tool can change. The developer can change. The repository can change. The company's context should not have to be rebuilt every time.
That is the problem this guide helps you design and build your way out of — as an internal platform capability, not a feature inside one vendor's index.
What to build: three components
Every implementation I have seen reduce to three deployable pieces:
| Component | Owns | Does not own |
|---|---|---|
| Ingestion platform | Parsing, chunking, symbol extraction, ACL propagation, embedding, incremental sync | Source code (Git remains SoR) |
| Context plane | Semantic, lexical, and symbol indexes; commit SHA tracking; domain metadata | Model inference |
| Context gateway | Auth, authorization, retrieval, reranking, audit, redaction; MCP or REST surface | Local uncommitted files |
GitHub / ADO (main) Confluence / Runbooks Eng Standards Repo
│ │ │
└────────────────────────┼─────────────────────────┘
▼
Ingestion Platform (K8s / Lambda)
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
Semantic Index Lexical Index Symbol Index
└───────────────────┼───────────────────┘
▼
Enterprise Context Plane
│
▼
Context Gateway (MCP over HTTP)
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
Cursor Claude Code Copilot
└───────────────────┼───────────────────┘
▼
+ Developer's local branch diffStep 1: Define your financial-services domain map
Before you index a single file, write down the domains your agents should route through. For a typical wealth platform:
Investment Domain
portfolio-api, portfolio-engine, holdings-service,
performance-service, risk-engine, market-data-service
Trading Domain
order-service, execution-gateway, fix-adapter, allocation-service
Identity Domain
auth-service, entitlements-api, customer-identity, secrets-vault
Compliance Domain
surveillance-engine, audit-log-service, reporting-apiStore this as configuration — not hard-coded in the gateway — so retrieval can filter by `domain=investment` before searching 400 repositories.
{
"domain": "investment",
"repositories": [
"portfolio-api",
"portfolio-engine",
"holdings-service",
"risk-engine",
"market-data-service"
],
"confluenceSpaces": ["PORT", "RISK"],
"standardsPaths": ["standards/http-retries.md", "standards/otel-finance.md"]
}Step 2: Build the repository registry
Create a single registry of approved branches to index. In regulated environments, that usually means `main` or a release branch — not every feature branch.
{
"repository": "portfolio-api",
"provider": "github",
"org": "wealth-platform",
"defaultBranch": "main",
"classification": "Internal",
"owningTeam": "portfolio",
"domain": "investment",
"aclSource": "github-team:portfolio-engineers",
"excludePaths": [".env*", "**/secrets/**", "**/*.pfx"]
}Build checklist
- Webhook on merge to `main` triggers incremental re-index
- Secret scanner runs before chunks enter any index
- Every indexed chunk records `commitSha`, `indexedAt`, and `repository`
- Repos outside the registry are never indexed — explicit allowlist, not discover-everything
Step 3: Design chunk metadata for .NET services
Raw text chunks are not enough for financial codebases. Each chunk should carry structured metadata agents and rerankers can filter on:
{
"repository": "portfolio-api",
"branch": "main",
"commit": "f31ab42",
"path": "src/Services/PortfolioService.cs",
"symbol": "PortfolioService.CalculateRisk",
"symbolKind": "method",
"language": "csharp",
"team": "portfolio",
"domain": "investment",
"classification": "Internal",
"lineStart": 84,
"lineEnd": 142
}How to build symbol extraction
- C# / Java: Roslyn or tree-sitter AST → methods, classes, interfaces, call edges
- Terraform: parse module blocks and output references for infra context
- OpenAPI / FIX specs: index by operation ID and message type, not just raw YAML
When an agent asks "where is portfolio risk calculated?", semantic search finds conceptually related code. When it asks "who calls `CalculateRisk()`?", the symbol index wins. Build both.
Step 4: Implement the ingestion pipeline
Treat ingestion as event-driven micro-batch jobs, not a nightly cron over everything.
Initial index (per repository)
Registry lookup → Clone main at commit SHA
→ Secret scan / path exclusions
→ Language detect → AST parse
→ Symbol + dependency graph
→ Semantic chunks (function-level for C#, section-level for docs)
→ Attach metadata + ACL from GitHub team membership
→ Embed → Write to all three indexes
→ Record: repo, branch, commitSha, indexedAtIncremental index (on PR merge)
Merge webhook → Diff changed files
→ Re-parse only changed paths
→ Delete obsolete chunks for those paths
→ Recalculate symbol references touched by the diff
→ Update cross-repo edges if public API contracts changed
→ Re-embed changed chunks only
→ Bump commitSha recordA change to `IPortfolioClient` in a shared contracts repo should trigger dependency recalculation in `order-service` and `holdings-service`, not just the repo where the edit landed.
Documentation pipeline (separate trigger)
Confluence and runbook updates should not share the Git merge trigger:
Confluence page updated → Validate caller permissions against source ACL
→ Fetch new version → Chunk by heading
→ Invalidate prior version chunks
→ Re-embed → Update context planeIf an engineer cannot read a Confluence page in the browser, the gateway must not return it. Propagate Confluence space permissions into index ACL fields at ingest time.
Step 5: Build the context gateway
Do not give agents direct access to OpenSearch or Pinecone. Build a gateway that owns the contract.
Core retrieval operations
Design these as explicit API or MCP tool surfaces:
search_code(query, domain?, repository?, topK?)
find_symbol(name, repository?)
find_references(symbol, repository?)
search_documentation(query, domain?, space?)
get_engineering_standard(topic) // e.g. "http-retries", "fix-session-recovery"
get_similar_implementation(description, domain)
get_api_contract(serviceName)C# gateway service sketch
Separate retrieval from authorization. Every call carries the developer identity from your IdP (Okta, Entra ID):
public sealed record ContextQuery(
string DeveloperId,
string AgentId,
string QueryType,
string Domain,
IReadOnlyList<string> RepositoryFilter);
public interface IContextGateway
{
Task<IReadOnlyList<CodeChunkResult>> SearchCodeAsync(
ContextQuery context,
string query,
int topK,
CancellationToken ct);
Task<EngineeringStandard?> GetStandardAsync(
ContextQuery context,
string topic,
CancellationToken ct);
}
public sealed class ContextGatewayService(
ISemanticIndex semantic,
ILexicalIndex lexical,
ISymbolIndex symbols,
IAclEvaluator acl,
IAuditLogger audit) : IContextGateway
{
public async Task<IReadOnlyList<CodeChunkResult>> SearchCodeAsync(
ContextQuery context, string query, int topK, CancellationToken ct)
{
var semanticHits = await semantic.SearchAsync(query, context.RepositoryFilter, topK * 2, ct);
var lexicalHits = await lexical.SearchAsync(query, context.RepositoryFilter, topK, ct);
var symbolHits = await symbols.SearchAsync(query, context.RepositoryFilter, topK, ct);
var merged = Reranker.Merge(semanticHits, lexicalHits, symbolHits);
var authorized = await acl.FilterAsync(context.DeveloperId, merged, ct);
await audit.LogAsync(context with { QueryType = "search_code" }, authorized.Count, ct);
return authorized.Take(topK).ToList();
}
}The gateway fails closed: if ACL evaluation errors, return nothing — not an unfiltered result set.
Step 6: Expose the gateway as an MCP server
MCP lets Cursor, Claude Code, and Copilot consume the same gateway without custom per-vendor integrations. For finance, keep context tools read-only; state-changing operations stay in separate, approval-gated MCP tools.
[McpServerToolType]
public sealed class PortfolioContextTools(IContextGateway gateway, IDeveloperContext dev)
{
[McpServerTool, Description(
"Search approved portfolio-domain code on main. Returns chunks with commit SHA and path.")]
public async Task<string> SearchPortfolioCodeAsync(
[Description("Natural language query, e.g. 'HTTP retry for outbound market data calls'.")]
string query,
CancellationToken ct)
{
var results = await gateway.SearchCodeAsync(
dev.CurrentContext("search_code", "investment", ["portfolio-api", "risk-engine"]),
query,
topK: 8,
ct);
return JsonSerializer.Serialize(results, JsonOptions.Indented);
}
[McpServerTool, Description(
"Retrieve an engineering standard by topic, e.g. http-retries or fix-session-recovery.")]
public async Task<string> GetEngineeringStandardAsync(string topic, CancellationToken ct)
{
var standard = await gateway.GetStandardAsync(
dev.CurrentContext("get_standard", "investment", []),
topic,
ct);
return standard?.Content ?? $"No standard found for topic '{topic}'.";
}
}Deploy this MCP server on HTTP behind your internal load balancer — same pattern as Running MCP Servers on Kubernetes. Register it in Copilot's enterprise MCP allowlist and Cursor's MCP config.
Step 7: Combine organization context with local working context
The gateway knows `main`. The developer is on `feature/portfolio-retry` with uncommitted edits to `PortfolioService.cs`.
At agent runtime, assemble context in layers:
1. Developer prompt
2. Local: git diff + open files on current branch
3. Organization (via gateway):
- Authoritative PortfolioService on main (for comparison)
- HTTP retry standard
- OrderService retry reference impl
- Relevant ADR on idempotent outbound calls
4. Task instruction: implement using org standards, preserve local changesExample assembled prompt the agent actually sees:
USER: Add retry handling to PortfolioService.
LOCAL (branch feature/portfolio-retry):
PortfolioService.cs — uncommitted changes to CalculateRisk and new
CallMarketDataAsync method.
ORG STANDARD (http-retries):
Max 3 attempts, exponential backoff, no retry on 4xx,
emit retry.number and correlation.id.
REFERENCE (order-service/main @ a9f2c11):
OrderService.cs lines 210-248 — Polly retry around IExecutionGateway.
TASK: Implement retry on CallMarketDataAsync. Match OrderService pattern.
Do not overwrite the developer's in-progress CalculateRisk changes.Build a thin developer context adapter in each IDE integration that reads local git state and prepends it before gateway results reach the model.
Step 8: Index the knowledge layers that matter in finance
Code intelligence
Index merged code from approved repos. Prioritize services that define business flows:
Portfolio API → Validation → Risk Engine → Order Service → Execution → LedgerThat flow rarely lives in one doc. It lives across controllers, message handlers, DB schemas, and FIX adapters. Cross-repo symbol and dependency indexing is what makes "where does a trade get validated?" answerable.
Engineering standards (highest ROI)
Explicitly index and version these — do not rely on semantic search to discover them inside random Confluence pages:
Authentication (JWT, mTLS between services)
Authorization (entitlements model)
API versioning and breaking-change policy
OpenTelemetry conventions (service.name, operation.name)
HTTP retry and circuit breaker defaults
FIX session recovery and sequence number handling
Secrets retrieval (never index the secrets themselves)
PCI / PII logging redaction rules
Database migration and rollback standards
Terraform module approval listStore standards in a dedicated Git repo (`engineering-standards`) with markdown files. Index that repo first — it is small, high-value, and easy to keep current.
Documentation and operational context
Index ADRs, incident runbooks, and on-call playbooks — with source ACLs. A runbook for "FIX session drop during market open" is exactly the kind of context an agent needs when a developer asks about reconnection logic.
Do not index client PII, production credentials, or raw trade blotters.
Step 9: Security controls to build in from day one
| Control | What to build |
|---|---|
| Identity | Every gateway call carries developer IdP subject; no anonymous retrieval |
| ACL propagation | GitHub team → repo ACL; Confluence space → doc ACL; re-sync on permission change |
| Secret exclusion | Block `.env`, `*.pfx`, `appsettings.Production.json` at ingest; run Gitleaks or equivalent |
| Read-only context | Context MCP tools never deploy, trade, or rotate credentials |
| Audit log | Log developer, agent, queryType, domain, repos searched, result count, timestamp |
| Classification | Tag chunks `Internal`, `Confidential`; filter at query time by developer clearance |
Context access and action access are different privileges. Your portfolio MCP server can expose `search_code` broadly while `place_order` requires a separate approval gate — same pattern as Deploying MCP Servers.
Step 10: Roll out on one domain first
Do not index the entire enterprise. Start with the Investment / Portfolio domain.
Phase 1 — Code (weeks 1–4)
Index `portfolio-api`, `portfolio-engine`, `holdings-service`, `risk-engine`, `market-data-service`. Ship semantic + lexical + symbol search. Enforce GitHub team ACLs. Record commit SHA on every chunk.
Phase 2 — Standards (weeks 5–6)
Index `engineering-standards` repo. Wire `get_engineering_standard` in the gateway. Measure whether retry and logging suggestions match firm conventions.
Phase 3 — Docs (weeks 7–8)
Connect Confluence spaces `PORT` and `RISK`. Index ADRs from `architecture-decisions` repo. Validate ACL propagation with a developer who lacks space access.
Phase 4 — Gateway + MCP (weeks 9–10)
Deploy context gateway on HTTP. Connect Cursor and one other approved agent. Run eval queries: "where is pre-trade risk checked?", "what is our FIX reconnect pattern?"
Phase 5 — Event-driven sync (weeks 11–12)
Merge webhook → incremental code index. Confluence webhook → doc index. Alert on stale index (indexed commit more than N hours behind `main`).
Phase 6 — Developer memory (later)
Only after organizational truth is reliable: layer per-developer working memory (recent repos, open incidents) — clearly separated from company truth.
What to measure
Infrastructure metrics (vector count, chunk count) tell you the pipeline ran. Outcome metrics tell you it worked:
- Time for a new engineer to trace a trade from API to ledger
- Retrieval accuracy on a fixed eval set ("where is buying-power checked?")
- Rate of AI suggestions that violate HTTP retry or logging standards
- Duplicate implementations of the same cross-cutting concern
- Stale-context incidents (agent cited code from commit behind `main`)
- Acceptance rate of AI-generated PRs in the portfolio domain
Build vs. buy
Cloud providers offer pieces of this pipeline — managed chunking, embedding, vector stores. That can accelerate ingestion plumbing.
What they do not replace is your domain map, your ACL model, your standards corpus, and your gateway contract. Even on Bedrock Knowledge Bases or Azure AI Search, you still need:
- A repository registry with approved branches
- Finance-specific metadata (domain, team, classification, commit SHA)
- Symbol and dependency indexes for .NET service graphs
- A gateway that enforces entitlements before any chunk reaches an agent
Treat managed services as infrastructure inside your context plane, not as the context plane itself.
Context as a Service (CaaS)
Chunking as a service is too small a concept — chunking is an implementation detail. What enterprises actually need is Context as a Service: a platform that takes authoritative inputs and returns retrievable, permission-aware organizational context on demand.
INPUT OUTPUT
───── ──────
Code Accurate
Documentation Permission-aware
Architecture (ADRs) Current
Engineering standards Retrievable
Runbooks / API specs Machine-readable
Infrastructure metadata organizational contextConceptually, the service contract looks like this:
POST /context/retrieve
identity: developer-123
agent: cursor
domain: investment
query: "HTTP retry for outbound market data"
repositories: [portfolio-api, market-data-service]
→ ranked chunks + standards + commit SHAs + audit recordYou can build CaaS internally (the 10-step guide above), buy pieces from cloud providers (embedding, vector store, managed ingestion), or run a hybrid — but the organizational contract should stay yours:
| Layer | Build internally | Buy from cloud |
|---|---|---|
| Repository registry & domain map | Yes | No |
| ACL / entitlements model | Yes | Partial (varies by vendor) |
| Symbol & dependency index | Yes | Rarely |
| Context gateway + MCP surface | Yes | No |
| Embedding & vector storage | Optional | Often |
| Raw document chunking | Optional | Often |
Would I build this as an internal platform capability? Yes — for any financial services org with more than one AI coding tool, more than one domain team, or regulated access requirements. The Efficiency Team (or AI platform squad) owns CaaS the same way it owns CI/CD, secrets, and observability: shared infrastructure that every squad consumes, not something each domain rebuilds on every laptop.
The IDE vendor can change. The model can change. CaaS is what stops you from paying the rediscovery tax every time either one does.
The architectural bet
Models will change. IDEs will change. Agents will change.
Your portfolio APIs, FIX adapters, risk engines, compliance runbooks, and engineering standards belong to your firm. The machine-readable layer that connects them should too.
Build it as platform infrastructure — owned by your Efficiency Team or AI platform squad, consumed by every coding agent through one gateway — and you stop paying the tax of rediscovering your own organization on every developer laptop.
Related reading
Frequently asked questions
- What is Context as a Service (CaaS)?
- Context as a Service is a platform capability that ingests authoritative code, docs, standards, and architecture once, stores them in a permission-aware enterprise context plane, and exposes retrieval through a context gateway (often MCP). Agents consume organizational truth on demand instead of each tool rebuilding its own index. Combine CaaS with local branch context at query time.
- What should a financial services firm build first?
- Start with one domain — typically Investment/Portfolio. Index five core repos (portfolio-api, holdings-service, risk-engine, etc.), ship semantic plus symbol search with GitHub team ACLs, then add an engineering-standards repo and a context gateway exposed as an MCP server before expanding to Confluence and other domains.
- What are the three components of an enterprise context plane?
- An ingestion platform (parse, chunk, embed, sync on merge), a context plane (semantic, lexical, and symbol indexes with commit SHA tracking), and a context gateway (auth, ACL filtering, retrieval, audit) exposed to agents via MCP or REST. Git and Confluence remain systems of record.
- How do you combine organizational context with local branch changes?
- The gateway serves authoritative main-branch code and standards. A developer-context adapter in each IDE prepends git diff and open files from the current branch. The agent prompt merges both layers so suggestions match firm conventions without overwriting uncommitted work.
- Why expose the context plane through MCP?
- MCP gives Cursor, Claude Code, and Copilot a shared read-only tool surface without per-vendor integration. Finance teams keep context tools separate from state-changing tools like order placement, which stay behind approval gates in a different MCP server.
Related reading
Embeddings and Vector Databases: The Search Layer Behind Real AI Applications
Embeddings convert meaning into vectors; vector databases make those vectors searchable. Together they form the retrieval foundation behind RAG, semantic search, and enterprise AI assistants.
Building Finance MCP Servers
Finance-specific MCP patterns — equity search, portfolio resources, order tools with approval gates, and audit-friendly error handling for regulated workloads.
Deploying MCP Servers: Stdio, HTTP, and Approval Gates
Platform engineering guide to MCP transport choice — stdio for Cursor, HTTP for production containers — plus human-in-the-loop approval before state-changing tools.