← Back to Writing
Article· 9 min read

Your AI Coding Assistant Shouldn't Be Your Company's Knowledge Layer

Enterprise AIAI EngineeringRAG ArchitectureMCP ServerCode IntelligenceDeveloper ProductivityAI Platform Engineering
Architecture diagram of an enterprise context plane for wealth management: ingestion from Git and runbooks through search indexes to a context gateway consumed by AI coding agents

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 work

The 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:

ComponentOwnsDoes not own
Ingestion platformParsing, chunking, symbol extraction, ACL propagation, embedding, incremental syncSource code (Git remains SoR)
Context planeSemantic, lexical, and symbol indexes; commit SHA tracking; domain metadataModel inference
Context gatewayAuth, authorization, retrieval, reranking, audit, redaction; MCP or REST surfaceLocal 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 diff

Step 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-api

Store 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, indexedAt

Incremental 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 record

A 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 plane

If 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 changes

Example 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 → Ledger

That 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 list

Store 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

ControlWhat to build
IdentityEvery gateway call carries developer IdP subject; no anonymous retrieval
ACL propagationGitHub team → repo ACL; Confluence space → doc ACL; re-sync on permission change
Secret exclusionBlock `.env`, `*.pfx`, `appsettings.Production.json` at ingest; run Gitleaks or equivalent
Read-only contextContext MCP tools never deploy, trade, or rotate credentials
Audit logLog developer, agent, queryType, domain, repos searched, result count, timestamp
ClassificationTag 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 context

Conceptually, 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 record

You 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:

LayerBuild internallyBuy from cloud
Repository registry & domain mapYesNo
ACL / entitlements modelYesPartial (varies by vendor)
Symbol & dependency indexYesRarely
Context gateway + MCP surfaceYesNo
Embedding & vector storageOptionalOften
Raw document chunkingOptionalOften

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.

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