You asked LangChain for a SharePoint loader, pointed it at a site, and it read the PDFs in a document library. The list your team works in every day, with its status, severity and project columns, never arrived. LlamaIndex does the same. CrewAI, AutoGen and n8n can reach list items, but only by calling SharePoint live for each question, which turns slow and page-bound the first time someone asks how many open defects each project has.
This guide takes the six frameworks in turn. For each one it says what the framework’s own SharePoint integration reads, in the versions we read on 23 October 2026, and gives the short code that points the framework at a SQL copy of your lists. Every Python snippet below ran against a Postgres replica that SPSync built from our construction demo data, logged in as a read-only role. What we tested was the tool layer and the database boundary. No language model was called, so we did not test how well any model writes the SQL, and the n8n steps come from n8n’s documentation and were not run in n8n.
Why the framework loaders stop at documents
Most framework connectors for SharePoint were written for retrieval over files: fetch a document, split it into chunks, embed the chunks. List items are rows, and the questions people ask about rows are counts, filters and joins.
| Framework, version read | Its own SharePoint route | Route to the replica |
|---|---|---|
| LangChain 1.4.7, langchain-community 0.4.2 | SharePointLoader: files in one document library | A database MCP server through MCPAdapter |
| LlamaIndex core 0.14.25, SharePoint reader 0.10.0 | SharePointReader: drive files or site pages | SQLDatabase and NLSQLTableQueryEngine |
| Semantic Kernel 1.45.0 (Python) | No SharePoint connector in the package | MCPStdioPlugin |
| CrewAI 1.15.28 | Microsoft SharePoint integration on CrewAI AMP, live | NL2SQLTool |
| AutoGen 0.7.5, archived | None of its own; Composio’s toolkit runs on AG2 | mcp_server_tools |
| n8n 2.44.6 | Microsoft SharePoint node, list items live | Postgres node as an AI tool |
A live call works for “show me item 42”. It struggles with “which live projects have the most open defects”, because the agent has to page through the whole list, join it to the Projects list in its own memory, and do it again for the next question. A list past the 5,000-item list view threshold also limits what a view or a query across all its items can do. Each live route needs its own consent to read SharePoint, which means one more security review per agent.
One replica behind every framework
SPSync reads the lists you choose and replicates them one way into Postgres or SQL Server,
one table per list, and keeps the tables current on a schedule. A lookup column arrives as
{col}_id and {col}_value, and a deleted item stays as a row with sp_deleted_at set.
SharePoint stays the system of record.
Our test replica holds two lists from the construction demo: Projects, and Snagging and Defects, which looks each defect up to its project. The agent role reads both tables, cannot write, and sees defects only on projects that are still on site. This is the pattern from the Postgres starter kit, applied to these tables:
create role agent_live login password 'change-me';alter role agent_live set default_transaction_read_only = on;alter role agent_live set statement_timeout = '15s';grant usage on schema spsync to agent_live;grant select on spsync.ab_snagging_and_defects, spsync.ab_projects to agent_live;
alter table spsync.ab_snagging_and_defects enable row level security;create policy live_projects_only on spsync.ab_snagging_and_defects for select to agent_live using (project_id in (select sp_item_id from spsync.ab_projects where status in ('Active', 'Snagging')));The role gets no grant on sp_users, so names and email addresses stay out of reach. The
sync writes as the table owner and owners skip these policies, so leave
force row level security off. A few things the replica does not do: it holds list
fields and library metadata, not the text inside files; it does not carry SharePoint item
permissions, so this role is the boundary; and SPSync ships no agent of its
own.
Three of the frameworks below load tools from an MCP server, so we used one server for all
three. DBHub 1.5.0, from Bytebase, reads its settings from dbhub.toml, refuses anything
but reads when readonly is set, and caps each result:
[[sources]]id = "replica"dsn = "postgres://agent_live:${REPLICA_PASSWORD}@db.internal:5432/replica?sslmode=require"
[[tools]]name = "execute_sql"source = "replica"readonly = truemax_rows = 200The MCP post compares DBHub with other Postgres and SQL Server servers, and shows the same replica in Claude and Cursor.
Is there a LangChain SharePoint loader for lists?
There is a loader, and it reads files. SharePointLoader in langchain-community 0.4.2
takes a document_library_id, signs in through the O365 package, and parses the files in
that library into documents. It has no option for list items. LangChain’s current
integration pages no longer list it, and they no longer list SQLDatabaseToolkit either,
although both classes still ship in the 0.4.2 package.
LangChain’s own SQL agent tutorial now builds its database tools as @tool functions and
warns that the database connection should be scoped as narrowly as possible. The shorter
route is MCP. LangChain 1.4 added MCPAdapter, in the langchain[mcp] extra and still
marked beta, which starts a server from a config dict and hands its tools to
create_agent:
import osfrom langchain.agents import create_agentfrom langchain.mcp import MCPAdapter
CONFIG = { "mcpServers": { "replica": { "command": "npx", "env": {"REPLICA_PASSWORD": os.environ["REPLICA_PASSWORD"]}, } }}
async def snagging_agent(model): async with MCPAdapter(CONFIG) as adapter: tools = await adapter.list_tools() return create_agent(model, tools)In our run the adapter listed one tool, execute_sql. The join across both tables
returned the three live projects and their open defect counts, and an update came back
as a read-only violation. For retrieval by meaning, langchain-postgres 0.0.19’s
PGVectorStore can open an existing table by naming its id, content and embedding
columns, so it is the class to try against the sp_embedding column SPSync writes on a
pgvector destination. We did not run a vector query for this guide.
LlamaIndex reads files and pages, so query the tables
SharePointReader 0.10.0 signs in with a client ID, secret and tenant ID, then reads the
files in a drive folder, or the site’s pages when you set sharepoint_type to pages. It
can attach permission metadata to each document. List items are not one of its sources.
For list data, LlamaIndex’s text-to-SQL engine works on the replica unchanged. This is the API from LlamaIndex’s own SQL example, given a schema and two tables:
import osfrom sqlalchemy import create_enginefrom llama_index.core import SQLDatabasefrom llama_index.core.query_engine import NLSQLTableQueryEngine
engine = create_engine(os.environ["REPLICA_URI"]) # logs in as agent_livetables = ["ab_snagging_and_defects", "ab_projects"]sql_database = SQLDatabase(engine, schema="spsync", include_tables=tables)
query_engine = NLSQLTableQueryEngine(sql_database=sql_database, tables=tables, llm=llm)response = query_engine.query("Which live projects have the most open defects?")print(response.metadata["sql_query"])llm is whichever LlamaIndex model you already use, and the engine also wants an
embedding model in Settings. The table description it sends to the model lists every
column, including the replication bookkeeping columns, so a view with only the columns
the question needs keeps the prompt short. The engine’s own docstring tells you to run it
under restricted roles, which is what agent_live is: a direct UPDATE through
sql_database.run_sql failed in a read-only transaction. LlamaIndex’s Postgres vector
store keeps its own data_ table, so it will not read SPSync’s embedding column as it
stands.
How do I use SharePoint lists in Semantic Kernel?
Through a plugin you add. The Python package, 1.45.0, has no SharePoint connector and no SQL plugin. You can write a native function that runs a parameterised query, or load an MCP server as a plugin, which Microsoft documents in Adding MCP plugins:
import osfrom semantic_kernel import Kernelfrom semantic_kernel.connectors.mcp import MCPStdioPlugin
async def build_kernel(): async with MCPStdioPlugin( name="Replica", description="Read-only SQL over the SharePoint replica", command="npx", env={"REPLICA_PASSWORD": os.environ["REPLICA_PASSWORD"]}, ) as replica: kernel = Kernel() kernel.add_plugin(replica) # build your agent on this kernel inside the blockkernel.invoke on Replica and execute_sql returned the same three projects, and a
delete was refused. Semantic Kernel’s Postgres and Azure AI Search vector store
connectors are both marked preview on Learn. Microsoft now calls
Agent Framework the direct
successor to Semantic Kernel and AutoGen, so new projects may start there. The replica
and the role stay the same whichever you choose.
CrewAI: an AMP integration for live calls, NL2SQLTool for the replica
CrewAI’s Microsoft SharePoint integration belongs to CrewAI AMP, the paid platform. You
connect a Microsoft account there, set an integration token, and give an agent
apps=['microsoft_sharepoint']. Its actions include getting a list’s items by site and
list ID, so it reads list data, live, through the account you connected.
On the replica, CrewAI’s NL2SQLTool takes a SQLAlchemy URI and is read only by default
in 1.15.28. It allows SELECT, SHOW, DESCRIBE and EXPLAIN and blocks statements
chained with semicolons:
import osfrom crewai import Agentfrom crewai_tools import NL2SQLTool
nl2sql = NL2SQLTool(db_uri=os.environ["REPLICA_URI"]) # logs in as agent_live
analyst = Agent( role="Snagging analyst", goal="Answer questions about open defects on live projects", backstory="Reads the SharePoint replica through a read-only login.", tools=[nl2sql],)The tool ran the join and refused an UPDATE before it reached the database. One catch:
in 1.15.28 the tool looks for tables in the public schema only, and SPSync’s tables sat in spsync,
so the tool found no tables on its own. Name the schema and tables in the task, or
replicate into public. CrewAI’s docs also describe a PGSearchTool for semantic search
in Postgres, marked as under development, and it is not in the 1.15.28 package. For MCP,
an agent’s mcps field takes servers directly, and MCPServerAdapter is the route when
you want to manage the connection yourself.
AutoGen is archived, so pin it or plan the move
Microsoft has archived AutoGen. Its README advises against production use and points new users to Agent Framework, and 0.7.5, from September 2025, is the latest release. AutoGen has no SharePoint integration of its own. Composio’s SharePoint toolkit, which includes actions that get list items a page at a time, connects through Composio’s AutoGen provider, and that provider runs on AG2, the community continuation of AutoGen 0.2.
The MCP tools in autogen-ext still work against the replica, with one condition. With
today’s mcp package, autogen_ext.tools.mcp failed to import, so we resolved the
dependencies as they stood on 15 October 2025 (uv run --exclude-newer 2025-10-15):
import osfrom autogen_agentchat.agents import AssistantAgentfrom autogen_ext.tools.mcp import StdioServerParams, mcp_server_tools
async def snagging_agent(model_client): replica = StdioServerParams( command="npx", env={"REPLICA_PASSWORD": os.environ["REPLICA_PASSWORD"]}, ) tools = await mcp_server_tools(replica) return AssistantAgent( name="snagging_analyst", model_client=model_client, tools=tools, reflect_on_tool_use=True )The execute_sql tool returned the three projects, and a drop table raised the
server’s read-only error. If you are starting now, put the effort into the move, since
the database side carries over unchanged.
Can n8n read SharePoint list items for an AI agent?
Yes, live. From n8n 2.37.0, a Microsoft SharePoint node added to a workflow is version 2,
built on Microsoft Graph, and its Item operations include Get and Get Many. It signs in as a person or as an
app registration, with Sites.Read.All to read or Sites.Selected for site-by-site
grants. That suits a workflow that fetches one item when something changes.
For an AI Agent node answering questions across lists, attach a Postgres node as a tool:
- Create a Postgres credential that logs in as
agent_live, with SSL on. - Add a Postgres node to the agent’s tools and choose Execute Query.
- Write the query with numbered placeholders, the form n8n documents for query parameters, and let the model fill only those values.
- Describe the tool in plain words, such as “open defects per live project”, so the agent knows when to call it.
The Postgres node is documented as usable as an AI tool, and a fixed query with parameters keeps the model away from writing SQL at all. n8n’s MCP Client Tool node connects to an MCP server over HTTP if you would rather share one DBHub server across workflows. n8n’s PGVector and Azure AI Search vector store nodes expect their own column and field layout, with a metadata column, so check that mapping before pointing either one at SPSync’s tables or indexes. We did not run these n8n steps; they come from n8n’s docs and rest on the same SQL and role we tested.
Where pgvector and Azure AI Search fit
SPSync writes embeddings on each sync for two destinations, Postgres with pgvector and Azure AI Search, and re-embeds only rows whose text changed. A framework’s retriever can read those vectors if it embeds the question with the same model and dimensions that the sync used, and if it can be told which columns or fields hold the id, the text and the vector. Keep counts and joins on the SQL tool, and send questions about wording to the vectors.
On Azure, Azure OpenAI On Your Data was retired on 14 October 2026. Microsoft’s migration moves Azure AI Search-backed apps to Foundry IQ and reuses the existing index, which can be the index SPSync maintains. The Azure AI Search destination covers the index layout.
Testing the boundary before the agent goes live
We built the replica by running SPSync against our fake Graph server with the
construction demo scenario, writing into a local Postgres 16 with pgvector. No language
model was called at any point: we tested the tool layer and the database boundary only,
with a stub model standing in for LlamaIndex’s. For LangChain, LlamaIndex, Semantic
Kernel, CrewAI and AutoGen we listed the tools the agent would get, ran the join as
agent_live through the tool, and tried a write. n8n was not run; its steps come from
n8n’s docs and rest on the same SQL and role, which we ran directly as agent_live. Every read returned only the three projects still on site, and every write
was stopped, by the tool’s own check or by the database. A second sync after row-level
security was switched on still succeeded.
Do the same on yours before an agent sees real data. Connect as the agent’s role, run a
query the agent will need, try an update, and check that the next scheduled sync
completes. The AI on SharePoint data guide sets
out when to choose SQL tools and when to choose retrieval, and the
Postgres starter kit has the grant and policy SQL for
a three-list schema.
Frequently asked questions
Does LangChain have a SharePoint list loader?
Not for list items. SharePointLoader in langchain-community 0.4.2 loads files from one document library through the O365 package, and LangChain's current documentation no longer lists it. For list rows, replicate the list into a SQL database and give the agent a database tool, such as a database MCP server loaded through MCPAdapter.
How do I give a CrewAI agent SharePoint list data?
Two ways. The Microsoft SharePoint integration on CrewAI AMP reads list items live through your Microsoft account, one call at a time. For questions that count, join or filter across lists, replicate the lists into Postgres and give the agent NL2SQLTool with a read-only login, which is read only by default in 1.15.28. In that version it only finds tables in the public schema, so name the tables in the task or replicate into public.
Does SPSync ship an MCP server or an agent for these frameworks?
SPSync ships no agent. It replicates SharePoint lists one way into a database and keeps that copy current, and it has a read-only MCP server of its own, spsync mcp serve. The frameworks use their own SQL tools, or a database MCP server such as DBHub, against the replica. The MCP post covers the servers we have tested.
Do SharePoint item permissions carry over into the replica?
No. SPSync copies the fields of each item, not who may see it. The database login is the boundary, so give each agent its own role and use row-level security when two agents should see different rows.
Can an agent write changes back to SharePoint through the replica?
No. Replication runs one way and SharePoint stays the system of record. Write-back is designed but not shipped, so an agent that proposes a change should write it to a staging table that a person reviews.
Can I still use Azure OpenAI On Your Data over the replica?
No. Microsoft retired On Your Data on 14 October 2026. Its successor for an Azure AI Search index is Foundry IQ, and Microsoft's migration reuses the existing index, which can be one SPSync keeps current.