Skip to main content
Glama
graysonlevino

Addepar MCP Server

Servidor MCP de Addepar

Servidor MCP de solo lectura que expone los datos de cartera y propiedad de Addepar a Claude.

Diseñado para su uso en informes financieros en un asesor de inversiones registrado. Los principios rectores, por orden de prioridad, son fiabilidad, exactitud, seguridad y, por último, conveniencia.


Qué garantiza este servidor

No garantiza que ningún número sea correcto en el mundo real. Eso no es algo que ninguna herramienta pueda prometer honestamente, porque el propio Addepar arrastra valoraciones obsoletas: una consulta ejecutada «a fecha de hoy» devuelve habitualmente un valor fechado semanas antes, porque los fondos privados valoran trimestralmente.

Lo que garantiza es una total honestidad sobre la procedencia:

  • Nunca inventa un número.

  • Nunca descarta datos silenciosamente.

  • Siempre indica lo que no sabe.

No hay deliberadamente puntuaciones de confianza. Una cifra etiquetada como «94% de confianza» es una falsa precisión, y la falsa precisión es peor que inútil en un contexto de cumplimiento normativo. En su lugar, cada respuesta incluye un array estructurado caveats que está vacío cuando el resultado es limpio, de modo que su vaciedad es una afirmación positiva y no una ausencia de comprobación.

La regla del null

Un valor null y un valor 0.0 son hechos distintos y nunca se fusionan.

Confirmado con datos reales, dos posiciones en el mismo hogar:

Position

Value

Meaning

Leslie A Dahl, WRD Capital

0.0

Addepar calculó un valor, y es cero

W Robert Dahl, Goldman Sachs -400P

null

No se calculó ningún valor, motivo no indicado

Convertir ese null a cero y sumarlo produce un total que está equivocado con total seguridad y que parece completamente plausible. Por lo tanto, los null se excluyen de las sumas, se cuentan y se mencionan en NULL_VALUES_EXCLUDED.

Códigos de advertencia

Code

Raised when

STALE_VALUATION

Una posición fue valorada más de 35 días antes de la fecha solicitada

NULL_VALUES_EXCLUDED

Una o más posiciones no devolvieron ningún valor calculado

AMBIGUOUS_MATCH

Una búsqueda encontró más de un candidato plausible

PATTERN_MATCH_USED

Se utilizó la coincidencia por nombre, que no es exhaustiva por naturaleza

DEPTH_CAP_REACHED

El recorrido se detuvo antes de tiempo, lo que sugiere anidamiento circular

MIXED_VALUATION_DATES

Un total combina valores valorados en fechas diferentes

RESULT_TRUNCATED

Existen más filas de las que se devolvieron; los totales siguen cubriéndolo todo

UNVERIFIED_CITATION

No hay ningún patrón de enlace de interfaz confirmado para este tipo de objeto


Herramientas

Tool

Question it answers

resolve_entity

Convertir un nombre en un ID y tipo de objeto específicos de Addepar

get_ownership_rollup

Exposición total, tenencias específicas o propiedad efectiva

get_group_exposure

Exposición en una familia de fondos relacionados

get_entity_attributes

Cómo se clasifican las tenencias de un cliente

list_views

Qué informes guardados existen

get_view_data

Ejecutar uno de los informes guardados de la propia firma

get_commitments

Capital comprometido, exigido y no desembolsado

Las siete declaran read_only_hint=True, de modo que un cliente de confianza puede omitir los avisos de confirmación. La garantía real es estructural: ver más abajo.

Mantenga disciplinado el número de herramientas. Las definiciones de herramientas se cargan en el contexto del modelo en cada solicitud, por lo que cada una cuesta tokens se use o no, y una superficie inflada degrada notablemente la selección de herramientas. Prefiera añadir un parámetro a una herramienta existente antes que añadir un casi duplicado.


Arquitectura

src/addepar_mcp/
  config.py       Settings from environment. No secrets in code.
  errors.py       Three failure classes. Extends the SDK ToolError.
  models.py       The response contract. Caveats, provenance, disclosure.
  client.py       Read-only HTTP client. Cannot construct a mutating request.
  tree.py         Traversal and null-safe arithmetic. No network dependency.
  citations.py    UI links, only for confirmed URL patterns.
  audit.py        Structured JSON Lines compliance record.
  auth.py         Per-request identity extraction. Entra ready.
  runtime.py      Shared runtime container.
  server.py       Entrypoint, transports, identity middleware.
  tools/          One module per tool, each exposing register(mcp).

Añadir una herramienta implica añadir un módulo y una línea en tools/__init__.py.

Solo lectura, garantizado por código

El cliente expone únicamente get y query, donde query es un POST restringido a una lista fija de endpoints de consulta de solo lectura. No existe ninguna ruta de código que pueda emitir PATCH, PUT o DELETE, ni forma de hacer POST a una ruta arbitraria. Intentarlo lanza ReadOnlyViolationError.

Esto es deliberado, no decorativo. Ningún caso de uso de v1 escribe, y un error que mutara la estructura de propiedad de un cliente no sería totalmente recuperable.

Cierre ante fallos

Ante un tiempo de espera agotado o un límite de frecuencia alcanzado a mitad de la operación, las herramientas devuelven un error y ningún dato. Nunca devuelven un árbol parcial ni un total menor, porque un total de propiedad truncado es indistinguible a simple vista de uno correcto.


Configuración

python -m venv .venv
.venv/bin/pip install -e ".[dev]"
cp .env.example .env      # then fill in credentials
.venv/bin/python -m pytest tests/ -q

Ejecutar localmente a través de stdio:

TRANSPORT=stdio .venv/bin/python -m addepar_mcp.server

Ejecutar a través de HTTP:

TRANSPORT=http HOST=0.0.0.0 PORT=8080 .venv/bin/python -m addepar_mcp.server

Comprobación de salud en GET /healthz. El endpoint de MCP está en /mcp.


Despliegue y autenticación

Despliegue en remoto sobre HTTPS para tener una única instancia que operar en lugar de una por puesto de trabajo.

Identidad, y por qué es importante

Hay dos capas de identidad separadas, y confundirlas causa confusión más adelante:

  • Identidad de quien llama: quién invocó la herramienta. Se extrae en cada solicitud y se escribe en todos los registros de auditoría.

  • Identidad ascendente: lo que muestra el propio registro de Addepar, que es la credencial de servicio única sin importar quién lo haya solicitado.

Esto significa que el registro de auditoría del lado del servidor es la respuesta autorizada a «quién ha mirado los datos de los clientes». El registro de Addepar no lo corroborará a nivel de usuario.

Dos modos admitidos:

Mode

Per-user attribution

Credencial compartida de la organización (static_headers)

No. Un administrador introduce una credencial; cada solicitud de usuario la lleva consigo y todos los usuarios son indistinguibles.

OAuth por usuario

Sí. Cada usuario da su consentimiento individualmente, de modo que la solicitud lo identifica.

Si el cumplimiento normativo necesita responder a «quién pidió qué», OAuth no es opcional. Es la única configuración que produce esa respuesta.

Para este despliegue, el servidor de autorización natural es el inquilino de Entra ID de la firma, puesto que ya utilizan Microsoft 365. Eso vincula el acceso a cuentas corporativas reales y lo hace gobernable a través del SSO propio de la firma, en lugar de una credencial en manos de un tercero.

Establezca REQUIRE_AUTH=true una vez que OAuth esté configurado. Hasta entonces, el servidor registra las llamadas como no atribuidas, lo cual es honesto pero no satisface un requisito de auditoría por usuario.

Advertencias del despliegue que conviene conocer de antemano

  • El URI de redireccionamiento para las interfaces alojadas de Claude es https://claude.ai/api/mcp/auth_callback.

  • El tráfico de salida de Anthropic se origina en 160.79.104.0/21. Tanto este servidor como los endpoints de descubrimiento del servidor de autorización deben ser alcanzables desde ese rango. Un cortafuegos delante del proveedor de identidad rompe el flujo incluso cuando el propio servidor MCP es alcanzable.

  • Con Entra ID, la URL del servidor MCP también debe registrarse como un URI de ID de aplicación en el registro de la aplicación; de lo contrario, la solicitud de token falla con AADSTS9010010.

  • Claude permite aproximadamente 10 segundos para los endpoints de descubrimiento y token, y 30 segundos para la renovación. Los endpoints lentos aparecen como fallos de conexión intermitentes en lugar de persistentes.

La verificación de firmas no está implementada

auth.py decodifica las declaraciones (claims) JWT con fines de auditoría pero no verifica firmas. Eso es aceptable en una red de confianza y no es aceptable una vez que el servidor es alcanzable por usuarios no confiables. Sustitúyala por una verificación JWKS real (obtener las claves del inquilino, verificar la firma, comprobar el emisor, la audiencia y la caducidad) antes de exponerlo. La identidad procedente de un token no verificado es una afirmación, no un hecho. Esto se dejó visiblemente incompleto en lugar de simular que está terminado.


Registro de auditoría

JSON Lines estructurado, un objeto por llamada a herramienta, escrito en AUDIT_LOG_PATH. Cada registro contiene marca de tiempo, herramienta, identidad de quien llama, argumentos, resultado, duración, IDs de solicitud de Addepar, entidades consultadas, número de filas, códigos de advertencia y cualquier error.

El registro debe residir en el lado del servidor. Una transcripción de conversación no es un registro duradero: el usuario puede eliminarla y, en algunas interfaces, no se puede archivar en absoluto. Si la única huella de un acceso a datos vive en una ventana de chat, no existe a efectos de cumplimiento normativo.

Plantéelo en la conversación sobre cumplimiento: estos registros contienen nombres de entidades, importes en dólares y patrones de acceso. Por tanto, el registro se encuentra dentro del mismo perímetro de cumplimiento que los datos subyacentes de los clientes, con las mismas preguntas asociadas sobre retención y acceso. Decida pronto si escribe en su propio almacén o si emite al pipeline de archivo existente, porque tener dos almacenes de los mismos datos de clientes duplica la superficie de cumplimiento.


Citas

Regla: emitir un enlace solo cuando tanto el tipo de objeto como el espacio de nombres de ID estén confirmados. De lo contrario, emitir la consulta reproducible. Una cita equivocada con seguridad es peor que ninguna, porque parece autoritativa y envía a alguien al lugar equivocado.

Object

Pattern

Status

Detalle de entidad

/app/tools/details/entity/{entity_id}

Confirmado

Vista sobre entidad

/app/tools/portfolio/entity/{portfolio_id}/view/{view_id}

Confirmado

Vista sobre grupo

/app/tools/portfolio/group/{group_id}/view/{view_id}

Inferido, no emitido

Detalle de posición

desconocido, puede que no exista

No emitido

Los agregados calculados, como la exposición total, no existen como objetos de Addepar y no tienen URL nativa. Se citan mediante un enlace profundo a una vista guardada con raíz en la misma cartera, lo que lleva al usuario a un informe que la firma creó y ya utiliza con confianza.

Estos patrones no pueden validarse mediante programación. La aplicación web de Addepar es una aplicación de página única que devuelve HTTP 200 para cada ruta, incluidas rutas deliberadamente absurdas, por lo que curl no puede distinguir una ruta válida de una inválida. Cualquier patrón nuevo debe ser confirmado por una persona copiando una URL real desde la interfaz en vivo.


Comportamiento validado

Verificado contra el inquilino real el 2026-08-26. Estos son datos de regresión en tests/test_regression_fixtures.py. Si una refactorización cambia alguno de ellos, la refactorización es incorrecta hasta que se demuestre lo contrario.

Assertion

Value

Total del hogar Dahl

486,034,402.38

Loon Point Holdings II LLC, búsqueda específica, 4 apariciones sumadas

21,427,660.34

Familia Pacific Lake, 6 coincidencias de 4,121 escaneadas

15,229,060.19

Parte de Charlotte en la LLC compartida

5,356,915.09

Profundidad máxima real de propiedad

5

Hogares en la firma

9

Dos comprobaciones cruzadas hacen que estos datos sean fiables, no meramente registrados:

  1. El total del hogar es idéntico tanto si se obtiene agrupando por ownership (jerarquía legal anidada) como por security (tenencias planas). Dos formas de consulta completamente distintas, el mismo número hasta el céntimo.

  2. El total de una LLC compartida es igual a la suma de las participaciones de los cuatro fideicomisos hermanos sobre ella, alcanzado desde direcciones de recorrido opuestas, sin doble contabilización.


Notas sobre la API de Addepar

Comportamiento ganado con esfuerzo, registrado para no tener que redescubrirlo de forma dolorosa.

  • Todos los endpoints requieren la cabecera Addepar-Firm, incluido /v1/users/me.

  • filter[name] en /v1/entities se ignora silenciosamente. No es un filtro real: devuelve entidades arbitrarias en lugar de coincidencias por nombre, lo cual es peor que un error porque parece que ha funcionado. filter[entity_types] es real y funciona.

  • GET /v1/entities sin filtrar devuelve un 400 ("cache is not responsible for firm 2142"). Añadir cualquier parámetro de filtro lo evita. Es un bug del lado de Addepar, sorteado en lugar de notificado.

  • La búsqueda por nombre funciona en POST /v1/groups/query mediante display_names. Es la única búsqueda por nombre que funciona en la API.

  • La agrupación ownership solo recorre entidades legales. Se detiene en las hojas de tipo holding-account y no desciende a los valores que contienen. Utilice la agrupación security para las líneas de inversión reales.

  • Los filtros discretos son solo de coincidencia exacta. No hay coincidencia por prefijo ni por subcadena, por lo que un nombre parcial devuelve cero filas en lugar de una coincidencia aproximada.

  • Los errores son claros y específicos, por ejemplo "Invalid grouping attribute: nonsense_grouping". Se transmiten tal cual.

  • La latencia es variable. La consolidación de hogares normalmente se completa en unos 3 segundos. Una ejecución tardó 47,8 segundos frente al límite de 60 segundos de Addepar. El tiempo de espera del cliente está fijado en 55 segundos para que aparezca un error claro en lugar de que la conexión se corte a mitad de respuesta.

  • Los límites de frecuencia son a nivel de firma: 50 peticiones cada 15 minutos y 1.000 cada 24 horas, compartidos con todas las demás integraciones de la firma. Por tanto, un límite puede activarse debido a actividad no relacionada con este servidor.

Colisiones de mismo nombre

Se encontraron tres en una sola sesión, lo que indica que es una característica de los datos y no mala suerte:

Nombre

Objetos

Dahl 2012 Dynasty Trust

entidad PERSON_NODE 31643590 y entidad TRUST 31643598

Pacific Lake Partners Long-Term Hold Fund One, L.P.

Aparece dos veces

Dahl Family

GROUP 3192711 y entidad HOUSEHOLD 31647552

Por tanto, cada respuesta revela el nombre, el ID y el tipo de objeto. Los ID de diferentes espacios de nombres no son intercambiables, y portfolio_type debe coincidir.


Nota sobre la versión del SDK

Esto está dirigido al MCP Python SDK 2.x. Si se va a portar código antiguo en esta organización:

  • FastMCP ahora es MCPServer, de mcp.server.mcpserver.

  • Los campos de ToolAnnotations pasaron de camelCase a snake_case (readOnlyHint se convirtió en read_only_hint).

  • stateless_http y json_response se trasladaron del constructor a streamable_http_app().

  • Las excepciones personalizadas deben heredar del ToolError del SDK. Cualquier otra cosa se trata como un fallo y su mensaje se mantiene en el servidor, por lo que el modelo solo recibe un fallo genérico. Esto rompe silenciosamente cualquier error que se suponía que debía devolver información, como una lista de candidatos en caso de ambigüedad.


Lagunas conocidas

  • get_commitments y get_entity_attributes siguen los mismos patrones validados que las demás herramientas, pero no se han probado con datos reales. Las columnas de compromisos devolvieron 0.0 durante las pruebas preliminares y puede que necesiten los argumentos de período que usan las vistas guardadas de la firma.

  • La verificación de la firma JWT no está implementada. Véase más arriba.

  • El patrón de URL de la vista con raíz en el grupo se infiere y se omite deliberadamente.

  • Las credenciales se han expuesto en texto plano durante varias sesiones de trabajo. El código lee de variables de entorno, por lo que la rotación es un cambio de configuración, pero la rotación en sí aún debe hacerse antes del uso en producción.

-
license - not tested
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Read-only public financial evidence from LiquiLens, Undertow, Seiche and Palimpsest.

  • Read-only access to your VortexIQ store data: audits, KPIs, alerts, Brand DNA, reports, Ask VIQ.

  • Read-only NuMetric.work accounting & ERP data: statements, KPIs, reports, invoices, documents.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/graysonlevino/oakridge-addepar'

If you have feedback or need assistance with the MCP directory API, please join our Discord server